create-scaffauth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/dist/index.js +1050 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/templates/express/drizzle-mysql/.env.example.hbs +39 -0
  6. package/dist/templates/express/drizzle-mysql/README.md.hbs +78 -0
  7. package/dist/templates/express/drizzle-mysql/drizzle/db.ts +8 -0
  8. package/dist/templates/express/drizzle-mysql/drizzle/migrate.ts +22 -0
  9. package/dist/templates/express/drizzle-mysql/drizzle/schema.ts +58 -0
  10. package/dist/templates/express/drizzle-mysql/drizzle.config.ts +10 -0
  11. package/dist/templates/express/drizzle-mysql/package.json.hbs +36 -0
  12. package/dist/templates/express/drizzle-mysql/src/auth.ts.hbs +114 -0
  13. package/dist/templates/express/drizzle-mysql/src/index.ts +28 -0
  14. package/dist/templates/express/drizzle-mysql/tsconfig.json +19 -0
  15. package/dist/templates/express/drizzle-postgres/.env.example.hbs +39 -0
  16. package/dist/templates/express/drizzle-postgres/README.md.hbs +78 -0
  17. package/dist/templates/express/drizzle-postgres/drizzle/db.ts +8 -0
  18. package/dist/templates/express/drizzle-postgres/drizzle/migrate.ts +22 -0
  19. package/dist/templates/express/drizzle-postgres/drizzle/schema.ts +57 -0
  20. package/dist/templates/express/drizzle-postgres/drizzle.config.ts +10 -0
  21. package/dist/templates/express/drizzle-postgres/package.json.hbs +37 -0
  22. package/dist/templates/express/drizzle-postgres/src/auth.ts.hbs +114 -0
  23. package/dist/templates/express/drizzle-postgres/src/index.ts +28 -0
  24. package/dist/templates/express/drizzle-postgres/tsconfig.json +19 -0
  25. package/dist/templates/express/drizzle-sqlite/.env.example.hbs +39 -0
  26. package/dist/templates/express/drizzle-sqlite/README.md.hbs +78 -0
  27. package/dist/templates/express/drizzle-sqlite/drizzle/db.ts +6 -0
  28. package/dist/templates/express/drizzle-sqlite/drizzle/migrate.ts +12 -0
  29. package/dist/templates/express/drizzle-sqlite/drizzle/schema.ts +55 -0
  30. package/dist/templates/express/drizzle-sqlite/drizzle.config.ts +10 -0
  31. package/dist/templates/express/drizzle-sqlite/package.json.hbs +37 -0
  32. package/dist/templates/express/drizzle-sqlite/src/auth.ts.hbs +114 -0
  33. package/dist/templates/express/drizzle-sqlite/src/index.ts +28 -0
  34. package/dist/templates/express/drizzle-sqlite/tsconfig.json +19 -0
  35. package/dist/templates/express/kysely-mysql/.env.example.hbs +39 -0
  36. package/dist/templates/express/kysely-mysql/README.md.hbs +75 -0
  37. package/dist/templates/express/kysely-mysql/db/db.ts +11 -0
  38. package/dist/templates/express/kysely-mysql/db/migrate.ts +77 -0
  39. package/dist/templates/express/kysely-mysql/db/types.ts +54 -0
  40. package/dist/templates/express/kysely-mysql/package.json.hbs +32 -0
  41. package/dist/templates/express/kysely-mysql/src/auth.ts.hbs +114 -0
  42. package/dist/templates/express/kysely-mysql/src/index.ts +28 -0
  43. package/dist/templates/express/kysely-mysql/tsconfig.json +19 -0
  44. package/dist/templates/express/kysely-postgres/.env.example.hbs +39 -0
  45. package/dist/templates/express/kysely-postgres/README.md.hbs +75 -0
  46. package/dist/templates/express/kysely-postgres/db/db.ts +11 -0
  47. package/dist/templates/express/kysely-postgres/db/migrate.ts +77 -0
  48. package/dist/templates/express/kysely-postgres/db/types.ts +54 -0
  49. package/dist/templates/express/kysely-postgres/package.json.hbs +33 -0
  50. package/dist/templates/express/kysely-postgres/src/auth.ts.hbs +114 -0
  51. package/dist/templates/express/kysely-postgres/src/index.ts +28 -0
  52. package/dist/templates/express/kysely-postgres/tsconfig.json +19 -0
  53. package/dist/templates/express/kysely-sqlite/.env.example.hbs +39 -0
  54. package/dist/templates/express/kysely-sqlite/README.md.hbs +75 -0
  55. package/dist/templates/express/kysely-sqlite/db/db.ts +9 -0
  56. package/dist/templates/express/kysely-sqlite/db/migrate.ts +75 -0
  57. package/dist/templates/express/kysely-sqlite/db/types.ts +54 -0
  58. package/dist/templates/express/kysely-sqlite/package.json.hbs +33 -0
  59. package/dist/templates/express/kysely-sqlite/src/auth.ts.hbs +114 -0
  60. package/dist/templates/express/kysely-sqlite/src/index.ts +28 -0
  61. package/dist/templates/express/kysely-sqlite/tsconfig.json +19 -0
  62. package/dist/templates/express/prisma-mysql/.env.example.hbs +39 -0
  63. package/dist/templates/express/prisma-mysql/README.md.hbs +79 -0
  64. package/dist/templates/express/prisma-mysql/package.json.hbs +35 -0
  65. package/dist/templates/express/prisma-mysql/prisma/schema.prisma +66 -0
  66. package/dist/templates/express/prisma-mysql/src/auth.ts.hbs +114 -0
  67. package/dist/templates/express/prisma-mysql/src/db.ts +3 -0
  68. package/dist/templates/express/prisma-mysql/src/index.ts +28 -0
  69. package/dist/templates/express/prisma-mysql/tsconfig.json +19 -0
  70. package/dist/templates/express/prisma-postgres/.env.example.hbs +39 -0
  71. package/dist/templates/express/prisma-postgres/README.md.hbs +79 -0
  72. package/dist/templates/express/prisma-postgres/package.json.hbs +35 -0
  73. package/dist/templates/express/prisma-postgres/prisma/schema.prisma +66 -0
  74. package/dist/templates/express/prisma-postgres/src/auth.ts.hbs +114 -0
  75. package/dist/templates/express/prisma-postgres/src/db.ts +3 -0
  76. package/dist/templates/express/prisma-postgres/src/index.ts +28 -0
  77. package/dist/templates/express/prisma-postgres/tsconfig.json +19 -0
  78. package/dist/templates/express/prisma-sqlite/.env.example.hbs +39 -0
  79. package/dist/templates/express/prisma-sqlite/README.md.hbs +79 -0
  80. package/dist/templates/express/prisma-sqlite/package.json.hbs +35 -0
  81. package/dist/templates/express/prisma-sqlite/prisma/schema.prisma +66 -0
  82. package/dist/templates/express/prisma-sqlite/src/auth.ts.hbs +114 -0
  83. package/dist/templates/express/prisma-sqlite/src/db.ts +3 -0
  84. package/dist/templates/express/prisma-sqlite/src/index.ts +28 -0
  85. package/dist/templates/express/prisma-sqlite/tsconfig.json +19 -0
  86. package/dist/templates/fastify/drizzle-mysql/.env.example.hbs +39 -0
  87. package/dist/templates/fastify/drizzle-mysql/README.md.hbs +78 -0
  88. package/dist/templates/fastify/drizzle-mysql/drizzle/db.ts +8 -0
  89. package/dist/templates/fastify/drizzle-mysql/drizzle/migrate.ts +22 -0
  90. package/dist/templates/fastify/drizzle-mysql/drizzle/schema.ts +58 -0
  91. package/dist/templates/fastify/drizzle-mysql/drizzle.config.ts +10 -0
  92. package/dist/templates/fastify/drizzle-mysql/package.json.hbs +34 -0
  93. package/dist/templates/fastify/drizzle-mysql/src/auth.ts.hbs +114 -0
  94. package/dist/templates/fastify/drizzle-mysql/src/index.ts +34 -0
  95. package/dist/templates/fastify/drizzle-mysql/tsconfig.json +19 -0
  96. package/dist/templates/fastify/drizzle-postgres/.env.example.hbs +39 -0
  97. package/dist/templates/fastify/drizzle-postgres/README.md.hbs +78 -0
  98. package/dist/templates/fastify/drizzle-postgres/drizzle/db.ts +8 -0
  99. package/dist/templates/fastify/drizzle-postgres/drizzle/migrate.ts +22 -0
  100. package/dist/templates/fastify/drizzle-postgres/drizzle/schema.ts +57 -0
  101. package/dist/templates/fastify/drizzle-postgres/drizzle.config.ts +10 -0
  102. package/dist/templates/fastify/drizzle-postgres/package.json.hbs +35 -0
  103. package/dist/templates/fastify/drizzle-postgres/src/auth.ts.hbs +114 -0
  104. package/dist/templates/fastify/drizzle-postgres/src/index.ts +34 -0
  105. package/dist/templates/fastify/drizzle-postgres/tsconfig.json +19 -0
  106. package/dist/templates/fastify/drizzle-sqlite/.env.example.hbs +39 -0
  107. package/dist/templates/fastify/drizzle-sqlite/README.md.hbs +78 -0
  108. package/dist/templates/fastify/drizzle-sqlite/drizzle/db.ts +6 -0
  109. package/dist/templates/fastify/drizzle-sqlite/drizzle/migrate.ts +12 -0
  110. package/dist/templates/fastify/drizzle-sqlite/drizzle/schema.ts +55 -0
  111. package/dist/templates/fastify/drizzle-sqlite/drizzle.config.ts +10 -0
  112. package/dist/templates/fastify/drizzle-sqlite/package.json.hbs +35 -0
  113. package/dist/templates/fastify/drizzle-sqlite/src/auth.ts.hbs +114 -0
  114. package/dist/templates/fastify/drizzle-sqlite/src/index.ts +34 -0
  115. package/dist/templates/fastify/drizzle-sqlite/tsconfig.json +19 -0
  116. package/dist/templates/fastify/kysely-mysql/.env.example.hbs +39 -0
  117. package/dist/templates/fastify/kysely-mysql/README.md.hbs +75 -0
  118. package/dist/templates/fastify/kysely-mysql/db/db.ts +11 -0
  119. package/dist/templates/fastify/kysely-mysql/db/migrate.ts +77 -0
  120. package/dist/templates/fastify/kysely-mysql/db/types.ts +54 -0
  121. package/dist/templates/fastify/kysely-mysql/package.json.hbs +30 -0
  122. package/dist/templates/fastify/kysely-mysql/src/auth.ts.hbs +114 -0
  123. package/dist/templates/fastify/kysely-mysql/src/index.ts +34 -0
  124. package/dist/templates/fastify/kysely-mysql/tsconfig.json +19 -0
  125. package/dist/templates/fastify/kysely-postgres/.env.example.hbs +39 -0
  126. package/dist/templates/fastify/kysely-postgres/README.md.hbs +75 -0
  127. package/dist/templates/fastify/kysely-postgres/db/db.ts +11 -0
  128. package/dist/templates/fastify/kysely-postgres/db/migrate.ts +77 -0
  129. package/dist/templates/fastify/kysely-postgres/db/types.ts +54 -0
  130. package/dist/templates/fastify/kysely-postgres/package.json.hbs +31 -0
  131. package/dist/templates/fastify/kysely-postgres/src/auth.ts.hbs +114 -0
  132. package/dist/templates/fastify/kysely-postgres/src/index.ts +34 -0
  133. package/dist/templates/fastify/kysely-postgres/tsconfig.json +19 -0
  134. package/dist/templates/fastify/kysely-sqlite/.env.example.hbs +39 -0
  135. package/dist/templates/fastify/kysely-sqlite/README.md.hbs +75 -0
  136. package/dist/templates/fastify/kysely-sqlite/db/db.ts +9 -0
  137. package/dist/templates/fastify/kysely-sqlite/db/migrate.ts +75 -0
  138. package/dist/templates/fastify/kysely-sqlite/db/types.ts +54 -0
  139. package/dist/templates/fastify/kysely-sqlite/package.json.hbs +31 -0
  140. package/dist/templates/fastify/kysely-sqlite/src/auth.ts.hbs +114 -0
  141. package/dist/templates/fastify/kysely-sqlite/src/index.ts +34 -0
  142. package/dist/templates/fastify/kysely-sqlite/tsconfig.json +19 -0
  143. package/dist/templates/fastify/prisma-mysql/.env.example.hbs +39 -0
  144. package/dist/templates/fastify/prisma-mysql/README.md.hbs +79 -0
  145. package/dist/templates/fastify/prisma-mysql/package.json.hbs +33 -0
  146. package/dist/templates/fastify/prisma-mysql/prisma/schema.prisma +66 -0
  147. package/dist/templates/fastify/prisma-mysql/src/auth.ts.hbs +114 -0
  148. package/dist/templates/fastify/prisma-mysql/src/db.ts +3 -0
  149. package/dist/templates/fastify/prisma-mysql/src/index.ts +34 -0
  150. package/dist/templates/fastify/prisma-mysql/tsconfig.json +19 -0
  151. package/dist/templates/fastify/prisma-postgres/.env.example.hbs +39 -0
  152. package/dist/templates/fastify/prisma-postgres/README.md.hbs +79 -0
  153. package/dist/templates/fastify/prisma-postgres/package.json.hbs +33 -0
  154. package/dist/templates/fastify/prisma-postgres/prisma/schema.prisma +66 -0
  155. package/dist/templates/fastify/prisma-postgres/src/auth.ts.hbs +114 -0
  156. package/dist/templates/fastify/prisma-postgres/src/db.ts +3 -0
  157. package/dist/templates/fastify/prisma-postgres/src/index.ts +34 -0
  158. package/dist/templates/fastify/prisma-postgres/tsconfig.json +19 -0
  159. package/dist/templates/fastify/prisma-sqlite/.env.example.hbs +39 -0
  160. package/dist/templates/fastify/prisma-sqlite/README.md.hbs +79 -0
  161. package/dist/templates/fastify/prisma-sqlite/package.json.hbs +33 -0
  162. package/dist/templates/fastify/prisma-sqlite/prisma/schema.prisma +66 -0
  163. package/dist/templates/fastify/prisma-sqlite/src/auth.ts.hbs +114 -0
  164. package/dist/templates/fastify/prisma-sqlite/src/db.ts +3 -0
  165. package/dist/templates/fastify/prisma-sqlite/src/index.ts +34 -0
  166. package/dist/templates/fastify/prisma-sqlite/tsconfig.json +19 -0
  167. package/dist/templates/hono/drizzle-mysql/.env.example.hbs +39 -0
  168. package/dist/templates/hono/drizzle-mysql/README.md.hbs +85 -0
  169. package/dist/templates/hono/drizzle-mysql/drizzle/db.ts +8 -0
  170. package/dist/templates/hono/drizzle-mysql/drizzle/migrate.ts +22 -0
  171. package/dist/templates/hono/drizzle-mysql/drizzle/schema.ts +58 -0
  172. package/dist/templates/hono/drizzle-mysql/drizzle.config.ts +10 -0
  173. package/dist/templates/hono/drizzle-mysql/package.json.hbs +33 -0
  174. package/dist/templates/hono/drizzle-mysql/src/auth.ts.hbs +114 -0
  175. package/dist/templates/hono/drizzle-mysql/src/index.ts +35 -0
  176. package/dist/templates/hono/drizzle-mysql/tsconfig.json +19 -0
  177. package/dist/templates/hono/drizzle-postgres/.env.example.hbs +39 -0
  178. package/dist/templates/hono/drizzle-postgres/README.md.hbs +85 -0
  179. package/dist/templates/hono/drizzle-postgres/drizzle/db.ts +8 -0
  180. package/dist/templates/hono/drizzle-postgres/drizzle/migrate.ts +22 -0
  181. package/dist/templates/hono/drizzle-postgres/drizzle/schema.ts +57 -0
  182. package/dist/templates/hono/drizzle-postgres/drizzle.config.ts +10 -0
  183. package/dist/templates/hono/drizzle-postgres/package.json.hbs +34 -0
  184. package/dist/templates/hono/drizzle-postgres/src/auth.ts.hbs +114 -0
  185. package/dist/templates/hono/drizzle-postgres/src/index.ts +35 -0
  186. package/dist/templates/hono/drizzle-postgres/tsconfig.json +19 -0
  187. package/dist/templates/hono/drizzle-sqlite/.env.example.hbs +39 -0
  188. package/dist/templates/hono/drizzle-sqlite/README.md.hbs +85 -0
  189. package/dist/templates/hono/drizzle-sqlite/drizzle/db.ts +6 -0
  190. package/dist/templates/hono/drizzle-sqlite/drizzle/migrate.ts +12 -0
  191. package/dist/templates/hono/drizzle-sqlite/drizzle/schema.ts +55 -0
  192. package/dist/templates/hono/drizzle-sqlite/drizzle.config.ts +10 -0
  193. package/dist/templates/hono/drizzle-sqlite/package.json.hbs +34 -0
  194. package/dist/templates/hono/drizzle-sqlite/src/auth.ts.hbs +114 -0
  195. package/dist/templates/hono/drizzle-sqlite/src/index.ts +35 -0
  196. package/dist/templates/hono/drizzle-sqlite/tsconfig.json +19 -0
  197. package/dist/templates/hono/kysely-mysql/.env.example.hbs +39 -0
  198. package/dist/templates/hono/kysely-mysql/README.md.hbs +75 -0
  199. package/dist/templates/hono/kysely-mysql/db/db.ts +11 -0
  200. package/dist/templates/hono/kysely-mysql/db/migrate.ts +77 -0
  201. package/dist/templates/hono/kysely-mysql/db/types.ts +54 -0
  202. package/dist/templates/hono/kysely-mysql/package.json.hbs +29 -0
  203. package/dist/templates/hono/kysely-mysql/src/auth.ts.hbs +114 -0
  204. package/dist/templates/hono/kysely-mysql/src/index.ts +35 -0
  205. package/dist/templates/hono/kysely-mysql/tsconfig.json +19 -0
  206. package/dist/templates/hono/kysely-postgres/.env.example.hbs +39 -0
  207. package/dist/templates/hono/kysely-postgres/README.md.hbs +75 -0
  208. package/dist/templates/hono/kysely-postgres/db/db.ts +11 -0
  209. package/dist/templates/hono/kysely-postgres/db/migrate.ts +77 -0
  210. package/dist/templates/hono/kysely-postgres/db/types.ts +54 -0
  211. package/dist/templates/hono/kysely-postgres/package.json.hbs +30 -0
  212. package/dist/templates/hono/kysely-postgres/src/auth.ts.hbs +114 -0
  213. package/dist/templates/hono/kysely-postgres/src/index.ts +35 -0
  214. package/dist/templates/hono/kysely-postgres/tsconfig.json +19 -0
  215. package/dist/templates/hono/kysely-sqlite/.env.example.hbs +39 -0
  216. package/dist/templates/hono/kysely-sqlite/README.md.hbs +75 -0
  217. package/dist/templates/hono/kysely-sqlite/db/db.ts +9 -0
  218. package/dist/templates/hono/kysely-sqlite/db/migrate.ts +75 -0
  219. package/dist/templates/hono/kysely-sqlite/db/types.ts +54 -0
  220. package/dist/templates/hono/kysely-sqlite/package.json.hbs +30 -0
  221. package/dist/templates/hono/kysely-sqlite/src/auth.ts.hbs +114 -0
  222. package/dist/templates/hono/kysely-sqlite/src/index.ts +35 -0
  223. package/dist/templates/hono/kysely-sqlite/tsconfig.json +19 -0
  224. package/dist/templates/hono/prisma-mysql/.env.example.hbs +39 -0
  225. package/dist/templates/hono/prisma-mysql/README.md.hbs +79 -0
  226. package/dist/templates/hono/prisma-mysql/package.json.hbs +32 -0
  227. package/dist/templates/hono/prisma-mysql/prisma/schema.prisma +66 -0
  228. package/dist/templates/hono/prisma-mysql/src/auth.ts.hbs +114 -0
  229. package/dist/templates/hono/prisma-mysql/src/db.ts +3 -0
  230. package/dist/templates/hono/prisma-mysql/src/index.ts +35 -0
  231. package/dist/templates/hono/prisma-mysql/tsconfig.json +19 -0
  232. package/dist/templates/hono/prisma-postgres/.env.example.hbs +39 -0
  233. package/dist/templates/hono/prisma-postgres/README.md.hbs +79 -0
  234. package/dist/templates/hono/prisma-postgres/package.json.hbs +32 -0
  235. package/dist/templates/hono/prisma-postgres/prisma/schema.prisma +66 -0
  236. package/dist/templates/hono/prisma-postgres/src/auth.ts.hbs +114 -0
  237. package/dist/templates/hono/prisma-postgres/src/db.ts +3 -0
  238. package/dist/templates/hono/prisma-postgres/src/index.ts +35 -0
  239. package/dist/templates/hono/prisma-postgres/tsconfig.json +19 -0
  240. package/dist/templates/hono/prisma-sqlite/.env.example.hbs +39 -0
  241. package/dist/templates/hono/prisma-sqlite/README.md.hbs +79 -0
  242. package/dist/templates/hono/prisma-sqlite/package.json.hbs +32 -0
  243. package/dist/templates/hono/prisma-sqlite/prisma/schema.prisma +66 -0
  244. package/dist/templates/hono/prisma-sqlite/src/auth.ts.hbs +114 -0
  245. package/dist/templates/hono/prisma-sqlite/src/db.ts +3 -0
  246. package/dist/templates/hono/prisma-sqlite/src/index.ts +35 -0
  247. package/dist/templates/hono/prisma-sqlite/tsconfig.json +19 -0
  248. package/package.json +71 -0
@@ -0,0 +1,78 @@
1
+ # {{projectName}}
2
+
3
+ Authentication backend powered by [Better Auth](https://better-auth.com), built with Express + Drizzle + PostgreSQL.
4
+
5
+ Generated with [Scaffauth](https://scaffauth.xyz).
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Install dependencies
11
+ npm install
12
+
13
+ # Copy environment variables
14
+ cp .env.example .env
15
+
16
+ # Update DATABASE_URL in .env with your PostgreSQL connection string
17
+
18
+ # Push database schema
19
+ npm run db:push
20
+
21
+ # Start development server
22
+ npm run dev
23
+ ```
24
+
25
+ Your auth backend will be running at `http://localhost:3000`.
26
+
27
+ ## API Endpoints
28
+
29
+ Better Auth provides these endpoints automatically:
30
+
31
+ | Method | Endpoint | Description |
32
+ |--------|----------|-------------|
33
+ | POST | `/api/auth/sign-up/email` | Register with email/password |
34
+ | POST | `/api/auth/sign-in/email` | Sign in with email/password |
35
+ | POST | `/api/auth/sign-out` | Sign out |
36
+ | GET | `/api/auth/session` | Get current session |
37
+ {{#each providers}}
38
+ | GET | `/api/auth/sign-in/social` | Sign in with {{this}} |
39
+ {{/each}}
40
+
41
+ ## Environment Variables
42
+
43
+ | Variable | Description |
44
+ |----------|-------------|
45
+ | `DATABASE_URL` | PostgreSQL connection string |
46
+ | `BETTER_AUTH_SECRET` | Secret key for signing tokens |
47
+ | `BETTER_AUTH_URL` | URL of the auth backend |
48
+ | `CORS_ORIGIN` | Allowed frontend origin |
49
+ | `PORT` | Server port (default: 3000) |
50
+ {{#each providers}}
51
+ | `{{uppercase this}}_CLIENT_ID` | {{this}} OAuth client ID |
52
+ | `{{uppercase this}}_CLIENT_SECRET` | {{this}} OAuth client secret |
53
+ {{/each}}
54
+
55
+ ## Database
56
+
57
+ This project uses Drizzle ORM with PostgreSQL.
58
+
59
+ ```bash
60
+ npm run db:generate # Generate migrations
61
+ npm run db:migrate # Run migrations
62
+ npm run db:push # Push schema changes directly
63
+ npm run db:studio # Open Drizzle Studio
64
+ ```
65
+
66
+ ## Frontend Integration
67
+
68
+ ```typescript
69
+ import { createAuthClient } from "better-auth/react";
70
+
71
+ export const authClient = createAuthClient({
72
+ baseURL: "http://localhost:3000",
73
+ });
74
+ ```
75
+
76
+ ## License
77
+
78
+ MIT
@@ -0,0 +1,8 @@
1
+ import { drizzle } from "drizzle-orm/node-postgres";
2
+ import pg from "pg";
3
+
4
+ const pool = new pg.Pool({
5
+ connectionString: process.env.DATABASE_URL,
6
+ });
7
+
8
+ export const db = drizzle(pool);
@@ -0,0 +1,22 @@
1
+ import { drizzle } from "drizzle-orm/node-postgres";
2
+ import { migrate } from "drizzle-orm/node-postgres/migrator";
3
+ import pg from "pg";
4
+
5
+ async function main() {
6
+ const pool = new pg.Pool({
7
+ connectionString: process.env.DATABASE_URL,
8
+ });
9
+
10
+ const db = drizzle(pool);
11
+
12
+ console.log("Running migrations...");
13
+ await migrate(db, { migrationsFolder: "./drizzle/migrations" });
14
+ console.log("Migrations complete.");
15
+
16
+ await pool.end();
17
+ }
18
+
19
+ main().catch((err) => {
20
+ console.error("Migration failed:", err);
21
+ process.exit(1);
22
+ });
@@ -0,0 +1,57 @@
1
+ import {
2
+ pgTable,
3
+ text,
4
+ timestamp,
5
+ boolean,
6
+ integer,
7
+ } from "drizzle-orm/pg-core";
8
+
9
+ export const user = pgTable("user", {
10
+ id: text("id").primaryKey(),
11
+ name: text("name").notNull(),
12
+ email: text("email").notNull().unique(),
13
+ emailVerified: boolean("email_verified").notNull().default(false),
14
+ image: text("image"),
15
+ createdAt: timestamp("created_at").notNull().defaultNow(),
16
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
17
+ });
18
+
19
+ export const session = pgTable("session", {
20
+ id: text("id").primaryKey(),
21
+ expiresAt: timestamp("expires_at").notNull(),
22
+ token: text("token").notNull().unique(),
23
+ createdAt: timestamp("created_at").notNull().defaultNow(),
24
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
25
+ ipAddress: text("ip_address"),
26
+ userAgent: text("user_agent"),
27
+ userId: text("user_id")
28
+ .notNull()
29
+ .references(() => user.id, { onDelete: "cascade" }),
30
+ });
31
+
32
+ export const account = pgTable("account", {
33
+ id: text("id").primaryKey(),
34
+ accountId: text("account_id").notNull(),
35
+ providerId: text("provider_id").notNull(),
36
+ userId: text("user_id")
37
+ .notNull()
38
+ .references(() => user.id, { onDelete: "cascade" }),
39
+ accessToken: text("access_token"),
40
+ refreshToken: text("refresh_token"),
41
+ idToken: text("id_token"),
42
+ accessTokenExpiresAt: timestamp("access_token_expires_at"),
43
+ refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
44
+ scope: text("scope"),
45
+ password: text("password"),
46
+ createdAt: timestamp("created_at").notNull().defaultNow(),
47
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
48
+ });
49
+
50
+ export const verification = pgTable("verification", {
51
+ id: text("id").primaryKey(),
52
+ identifier: text("identifier").notNull(),
53
+ value: text("value").notNull(),
54
+ expiresAt: timestamp("expires_at").notNull(),
55
+ createdAt: timestamp("created_at").notNull().defaultNow(),
56
+ updatedAt: timestamp("updated_at").notNull().defaultNow(),
57
+ });
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from "drizzle-kit";
2
+
3
+ export default defineConfig({
4
+ schema: "./drizzle/schema.ts",
5
+ out: "./drizzle/migrations",
6
+ dialect: "postgresql",
7
+ dbCredentials: {
8
+ url: process.env.DATABASE_URL!,
9
+ },
10
+ });
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "tsx watch src/index.ts",
8
+ "build": "tsc",
9
+ "start": "node dist/index.js",
10
+ "db:generate": "drizzle-kit generate",
11
+ "db:migrate": "tsx drizzle/migrate.ts",
12
+ "db:push": "drizzle-kit push",
13
+ "db:studio": "drizzle-kit studio"
14
+ },
15
+ "dependencies": {
16
+ "better-auth": "^1.2.0",
17
+ "cors": "^2.8.5",
18
+ "drizzle-orm": "^0.38.0",
19
+ "express": "^5.0.0",
20
+ "pg": "^8.13.0"
21
+ {{#if (eq emailProvider "resend")}},
22
+ "resend": "^4.0.0"{{/if}}{{#if (eq emailProvider "sendgrid")}},
23
+ "@sendgrid/mail": "^8.1.0"{{/if}}{{#if (eq emailProvider "smtp")}},
24
+ "nodemailer": "^6.9.0"{{/if}}
25
+ },
26
+ "devDependencies": {
27
+ "@types/cors": "^2.8.17",
28
+ "@types/express": "^5.0.0",
29
+ "@types/node": "^22.13.0",
30
+ "@types/pg": "^8.11.0",
31
+ "drizzle-kit": "^0.30.0",
32
+ "tsx": "^4.19.0",
33
+ "typescript": "^5.7.0"
34
+ {{#if (eq emailProvider "smtp")}},
35
+ "@types/nodemailer": "^6.4.0"{{/if}}
36
+ }
37
+ }
@@ -0,0 +1,114 @@
1
+ import { betterAuth } from "better-auth";
2
+ import { drizzleAdapter } from "better-auth/adapters/drizzle";
3
+ import { db } from "../drizzle/db";
4
+ {{#if twoFactor}}
5
+ import { twoFactor } from "better-auth/plugins";
6
+ {{/if}}
7
+ {{#if rbac}}
8
+ import { admin } from "better-auth/plugins";
9
+ {{/if}}
10
+ {{#if (eq emailProvider "resend")}}
11
+ import { Resend } from "resend";
12
+
13
+ const resend = new Resend(process.env.RESEND_API_KEY);
14
+ {{/if}}
15
+ {{#if (eq emailProvider "sendgrid")}}
16
+ import sgMail from "@sendgrid/mail";
17
+
18
+ sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
19
+ {{/if}}
20
+ {{#if (eq emailProvider "smtp")}}
21
+ import nodemailer from "nodemailer";
22
+
23
+ const transporter = nodemailer.createTransport({
24
+ host: process.env.SMTP_HOST,
25
+ port: Number(process.env.SMTP_PORT) || 587,
26
+ auth: {
27
+ user: process.env.SMTP_USER,
28
+ pass: process.env.SMTP_PASS,
29
+ },
30
+ });
31
+ {{/if}}
32
+
33
+ export const auth = betterAuth({
34
+ database: drizzleAdapter(db, {
35
+ provider: "pg",
36
+ }),
37
+ emailAndPassword: {
38
+ enabled: true,
39
+ {{#if emailProvider}}
40
+ requireEmailVerification: true,
41
+ sendResetPassword: async ({ user, url }) => {
42
+ await sendEmail(user.email, "Reset your password", `<a href="${url}">Reset password</a>`);
43
+ },
44
+ {{/if}}
45
+ },
46
+ session: {
47
+ expiresIn: {{sessionExpiresIn}},
48
+ updateAge: {{sessionUpdateAge}},
49
+ cookieCache: {
50
+ enabled: {{sessionCookieCacheEnabled}},
51
+ maxAge: {{sessionCookieCacheMaxAge}},
52
+ },
53
+ },
54
+ {{#if emailProvider}}
55
+ emailVerification: {
56
+ sendOnSignUp: true,
57
+ sendVerificationEmail: async ({ user, url }) => {
58
+ await sendEmail(user.email, "Verify your email", `<a href="${url}">Verify email</a>`);
59
+ },
60
+ },
61
+ {{/if}}
62
+ {{#if providers.length}}
63
+ socialProviders: {
64
+ {{#each providers}}
65
+ {{this}}: {
66
+ clientId: process.env.{{uppercase this}}_CLIENT_ID!,
67
+ clientSecret: process.env.{{uppercase this}}_CLIENT_SECRET!,
68
+ },
69
+ {{/each}}
70
+ },
71
+ {{/if}}
72
+ {{#if (or twoFactor rbac)}}
73
+ plugins: [
74
+ {{#if twoFactor}}
75
+ twoFactor(),
76
+ {{/if}}
77
+ {{#if rbac}}
78
+ admin({
79
+ defaultRole: "user",
80
+ }),
81
+ {{/if}}
82
+ ],
83
+ {{/if}}
84
+ trustedOrigins: [process.env.CORS_ORIGIN || "http://localhost:3001"],
85
+ });
86
+ {{#if emailProvider}}
87
+
88
+ async function sendEmail(to: string, subject: string, html: string) {
89
+ {{#if (eq emailProvider "resend")}}
90
+ await resend.emails.send({
91
+ from: process.env.EMAIL_FROM || "noreply@example.com",
92
+ to,
93
+ subject,
94
+ html,
95
+ });
96
+ {{/if}}
97
+ {{#if (eq emailProvider "sendgrid")}}
98
+ await sgMail.send({
99
+ from: process.env.EMAIL_FROM || "noreply@example.com",
100
+ to,
101
+ subject,
102
+ html,
103
+ });
104
+ {{/if}}
105
+ {{#if (eq emailProvider "smtp")}}
106
+ await transporter.sendMail({
107
+ from: process.env.EMAIL_FROM || "noreply@example.com",
108
+ to,
109
+ subject,
110
+ html,
111
+ });
112
+ {{/if}}
113
+ }
114
+ {{/if}}
@@ -0,0 +1,28 @@
1
+ import express from "express";
2
+ import cors from "cors";
3
+ import { auth } from "./auth";
4
+ import { toNodeHandler } from "better-auth/node";
5
+
6
+ const app = express();
7
+
8
+ // Middleware
9
+ app.use(
10
+ cors({
11
+ origin: process.env.CORS_ORIGIN || "http://localhost:3001",
12
+ credentials: true,
13
+ }),
14
+ );
15
+
16
+ // Mount Better Auth handler
17
+ app.all("/api/auth/*", toNodeHandler(auth));
18
+
19
+ // Health check
20
+ app.get("/", (_req, res) => {
21
+ res.json({ status: "ok", message: "Auth backend is running" });
22
+ });
23
+
24
+ // Start server
25
+ const port = Number(process.env.PORT) || 3000;
26
+ app.listen(port, () => {
27
+ console.log(`Server running on http://localhost:${port}`);
28
+ });
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022"],
7
+ "outDir": "dist",
8
+ "rootDir": ".",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "sourceMap": true
16
+ },
17
+ "include": ["src/**/*.ts", "drizzle/**/*.ts"],
18
+ "exclude": ["node_modules", "dist"]
19
+ }
@@ -0,0 +1,39 @@
1
+ # Database
2
+ DATABASE_URL=sqlite.db
3
+
4
+ # Better Auth
5
+ BETTER_AUTH_SECRET={{authSecret}}
6
+ BETTER_AUTH_URL=http://localhost:3000
7
+
8
+ # CORS
9
+ CORS_ORIGIN=http://localhost:3001
10
+
11
+ # Server
12
+ PORT=3000
13
+ {{#each providers}}
14
+
15
+ # {{uppercase this}} OAuth
16
+ {{uppercase this}}_CLIENT_ID=
17
+ {{uppercase this}}_CLIENT_SECRET=
18
+ {{/each}}
19
+ {{#if (eq emailProvider "resend")}}
20
+
21
+ # Email (Resend)
22
+ RESEND_API_KEY=
23
+ EMAIL_FROM=noreply@example.com
24
+ {{/if}}
25
+ {{#if (eq emailProvider "sendgrid")}}
26
+
27
+ # Email (SendGrid)
28
+ SENDGRID_API_KEY=
29
+ EMAIL_FROM=noreply@example.com
30
+ {{/if}}
31
+ {{#if (eq emailProvider "smtp")}}
32
+
33
+ # Email (SMTP)
34
+ SMTP_HOST=smtp.example.com
35
+ SMTP_PORT=587
36
+ SMTP_USER=
37
+ SMTP_PASS=
38
+ EMAIL_FROM=noreply@example.com
39
+ {{/if}}
@@ -0,0 +1,78 @@
1
+ # {{projectName}}
2
+
3
+ Authentication backend powered by [Better Auth](https://better-auth.com), built with Express + Drizzle + PostgreSQL.
4
+
5
+ Generated with [Scaffauth](https://scaffauth.xyz).
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Install dependencies
11
+ npm install
12
+
13
+ # Copy environment variables
14
+ cp .env.example .env
15
+
16
+ # Update DATABASE_URL in .env with your PostgreSQL connection string
17
+
18
+ # Push database schema
19
+ npm run db:push
20
+
21
+ # Start development server
22
+ npm run dev
23
+ ```
24
+
25
+ Your auth backend will be running at `http://localhost:3000`.
26
+
27
+ ## API Endpoints
28
+
29
+ Better Auth provides these endpoints automatically:
30
+
31
+ | Method | Endpoint | Description |
32
+ |--------|----------|-------------|
33
+ | POST | `/api/auth/sign-up/email` | Register with email/password |
34
+ | POST | `/api/auth/sign-in/email` | Sign in with email/password |
35
+ | POST | `/api/auth/sign-out` | Sign out |
36
+ | GET | `/api/auth/session` | Get current session |
37
+ {{#each providers}}
38
+ | GET | `/api/auth/sign-in/social` | Sign in with {{this}} |
39
+ {{/each}}
40
+
41
+ ## Environment Variables
42
+
43
+ | Variable | Description |
44
+ |----------|-------------|
45
+ | `DATABASE_URL` | PostgreSQL connection string |
46
+ | `BETTER_AUTH_SECRET` | Secret key for signing tokens |
47
+ | `BETTER_AUTH_URL` | URL of the auth backend |
48
+ | `CORS_ORIGIN` | Allowed frontend origin |
49
+ | `PORT` | Server port (default: 3000) |
50
+ {{#each providers}}
51
+ | `{{uppercase this}}_CLIENT_ID` | {{this}} OAuth client ID |
52
+ | `{{uppercase this}}_CLIENT_SECRET` | {{this}} OAuth client secret |
53
+ {{/each}}
54
+
55
+ ## Database
56
+
57
+ This project uses Drizzle ORM with PostgreSQL.
58
+
59
+ ```bash
60
+ npm run db:generate # Generate migrations
61
+ npm run db:migrate # Run migrations
62
+ npm run db:push # Push schema changes directly
63
+ npm run db:studio # Open Drizzle Studio
64
+ ```
65
+
66
+ ## Frontend Integration
67
+
68
+ ```typescript
69
+ import { createAuthClient } from "better-auth/react";
70
+
71
+ export const authClient = createAuthClient({
72
+ baseURL: "http://localhost:3000",
73
+ });
74
+ ```
75
+
76
+ ## License
77
+
78
+ MIT
@@ -0,0 +1,6 @@
1
+ import { drizzle } from "drizzle-orm/better-sqlite3";
2
+ import Database from "better-sqlite3";
3
+
4
+ const sqlite = new Database(process.env.DATABASE_URL || "sqlite.db");
5
+
6
+ export const db = drizzle(sqlite);
@@ -0,0 +1,12 @@
1
+ import { drizzle } from "drizzle-orm/better-sqlite3";
2
+ import { migrate } from "drizzle-orm/better-sqlite3/migrator";
3
+ import Database from "better-sqlite3";
4
+
5
+ const sqlite = new Database(process.env.DATABASE_URL || "sqlite.db");
6
+ const db = drizzle(sqlite);
7
+
8
+ console.log("Running migrations...");
9
+ migrate(db, { migrationsFolder: "./drizzle/migrations" });
10
+ console.log("Migrations complete.");
11
+
12
+ sqlite.close();
@@ -0,0 +1,55 @@
1
+ import {
2
+ sqliteTable,
3
+ text,
4
+ integer,
5
+ } from "drizzle-orm/sqlite-core";
6
+
7
+ export const user = sqliteTable("user", {
8
+ id: text("id").primaryKey(),
9
+ name: text("name").notNull(),
10
+ email: text("email").notNull().unique(),
11
+ emailVerified: integer("email_verified", { mode: "boolean" }).notNull().default(false),
12
+ image: text("image"),
13
+ createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
14
+ updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
15
+ });
16
+
17
+ export const session = sqliteTable("session", {
18
+ id: text("id").primaryKey(),
19
+ expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(),
20
+ token: text("token").notNull().unique(),
21
+ createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
22
+ updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
23
+ ipAddress: text("ip_address"),
24
+ userAgent: text("user_agent"),
25
+ userId: text("user_id")
26
+ .notNull()
27
+ .references(() => user.id, { onDelete: "cascade" }),
28
+ });
29
+
30
+ export const account = sqliteTable("account", {
31
+ id: text("id").primaryKey(),
32
+ accountId: text("account_id").notNull(),
33
+ providerId: text("provider_id").notNull(),
34
+ userId: text("user_id")
35
+ .notNull()
36
+ .references(() => user.id, { onDelete: "cascade" }),
37
+ accessToken: text("access_token"),
38
+ refreshToken: text("refresh_token"),
39
+ idToken: text("id_token"),
40
+ accessTokenExpiresAt: integer("access_token_expires_at", { mode: "timestamp" }),
41
+ refreshTokenExpiresAt: integer("refresh_token_expires_at", { mode: "timestamp" }),
42
+ scope: text("scope"),
43
+ password: text("password"),
44
+ createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
45
+ updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
46
+ });
47
+
48
+ export const verification = sqliteTable("verification", {
49
+ id: text("id").primaryKey(),
50
+ identifier: text("identifier").notNull(),
51
+ value: text("value").notNull(),
52
+ expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(),
53
+ createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
54
+ updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
55
+ });
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from "drizzle-kit";
2
+
3
+ export default defineConfig({
4
+ schema: "./drizzle/schema.ts",
5
+ out: "./drizzle/migrations",
6
+ dialect: "sqlite",
7
+ dbCredentials: {
8
+ url: process.env.DATABASE_URL || "sqlite.db",
9
+ },
10
+ });
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "tsx watch src/index.ts",
8
+ "build": "tsc",
9
+ "start": "node dist/index.js",
10
+ "db:generate": "drizzle-kit generate",
11
+ "db:migrate": "tsx drizzle/migrate.ts",
12
+ "db:push": "drizzle-kit push",
13
+ "db:studio": "drizzle-kit studio"
14
+ },
15
+ "dependencies": {
16
+ "better-auth": "^1.2.0",
17
+ "better-sqlite3": "^11.7.0",
18
+ "cors": "^2.8.5",
19
+ "drizzle-orm": "^0.38.0",
20
+ "express": "^5.0.0"
21
+ {{#if (eq emailProvider "resend")}},
22
+ "resend": "^4.0.0"{{/if}}{{#if (eq emailProvider "sendgrid")}},
23
+ "@sendgrid/mail": "^8.1.0"{{/if}}{{#if (eq emailProvider "smtp")}},
24
+ "nodemailer": "^6.9.0"{{/if}}
25
+ },
26
+ "devDependencies": {
27
+ "@types/better-sqlite3": "^7.6.0",
28
+ "@types/cors": "^2.8.17",
29
+ "@types/express": "^5.0.0",
30
+ "@types/node": "^22.13.0",
31
+ "drizzle-kit": "^0.30.0",
32
+ "tsx": "^4.19.0",
33
+ "typescript": "^5.7.0"
34
+ {{#if (eq emailProvider "smtp")}},
35
+ "@types/nodemailer": "^6.4.0"{{/if}}
36
+ }
37
+ }