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,75 @@
1
+ # {{projectName}}
2
+
3
+ Authentication backend powered by [Better Auth](https://better-auth.com), built with Hono + Kysely + 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
+ # Run migrations
19
+ npm run db:migrate
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 Kysely query builder with PostgreSQL.
58
+
59
+ ```bash
60
+ npm run db:migrate # Run migrations (creates tables)
61
+ ```
62
+
63
+ ## Frontend Integration
64
+
65
+ ```typescript
66
+ import { createAuthClient } from "better-auth/react";
67
+
68
+ export const authClient = createAuthClient({
69
+ baseURL: "http://localhost:3000",
70
+ });
71
+ ```
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,11 @@
1
+ import { Kysely, MysqlDialect } from "kysely";
2
+ import { createPool } from "mysql2";
3
+ import type { Database } from "./types";
4
+
5
+ const dialect = new MysqlDialect({
6
+ pool: createPool({
7
+ uri: process.env.DATABASE_URL,
8
+ }),
9
+ });
10
+
11
+ export const db = new Kysely<Database>({ dialect });
@@ -0,0 +1,77 @@
1
+ import { Kysely, MysqlDialect, sql } from "kysely";
2
+ import { createPool } from "mysql2";
3
+ import type { Database } from "./types";
4
+
5
+ async function main() {
6
+ const dialect = new MysqlDialect({
7
+ pool: createPool({
8
+ uri: process.env.DATABASE_URL,
9
+ }),
10
+ });
11
+
12
+ const db = new Kysely<Database>({ dialect });
13
+
14
+ console.log("Running migrations...");
15
+
16
+ await db.schema
17
+ .createTable("user")
18
+ .ifNotExists()
19
+ .addColumn("id", "varchar(36)", (col) => col.primaryKey())
20
+ .addColumn("name", "text", (col) => col.notNull())
21
+ .addColumn("email", "varchar(255)", (col) => col.notNull().unique())
22
+ .addColumn("email_verified", "boolean", (col) => col.notNull().defaultTo(false))
23
+ .addColumn("image", "text")
24
+ .addColumn("created_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
25
+ .addColumn("updated_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
26
+ .execute();
27
+
28
+ await db.schema
29
+ .createTable("session")
30
+ .ifNotExists()
31
+ .addColumn("id", "varchar(36)", (col) => col.primaryKey())
32
+ .addColumn("expires_at", "datetime", (col) => col.notNull())
33
+ .addColumn("token", "varchar(255)", (col) => col.notNull().unique())
34
+ .addColumn("created_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
35
+ .addColumn("updated_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
36
+ .addColumn("ip_address", "text")
37
+ .addColumn("user_agent", "text")
38
+ .addColumn("user_id", "varchar(36)", (col) => col.notNull().references("user.id"))
39
+ .execute();
40
+
41
+ await db.schema
42
+ .createTable("account")
43
+ .ifNotExists()
44
+ .addColumn("id", "varchar(36)", (col) => col.primaryKey())
45
+ .addColumn("account_id", "text", (col) => col.notNull())
46
+ .addColumn("provider_id", "text", (col) => col.notNull())
47
+ .addColumn("user_id", "varchar(36)", (col) => col.notNull().references("user.id"))
48
+ .addColumn("access_token", "text")
49
+ .addColumn("refresh_token", "text")
50
+ .addColumn("id_token", "text")
51
+ .addColumn("access_token_expires_at", "datetime")
52
+ .addColumn("refresh_token_expires_at", "datetime")
53
+ .addColumn("scope", "text")
54
+ .addColumn("password", "text")
55
+ .addColumn("created_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
56
+ .addColumn("updated_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
57
+ .execute();
58
+
59
+ await db.schema
60
+ .createTable("verification")
61
+ .ifNotExists()
62
+ .addColumn("id", "varchar(36)", (col) => col.primaryKey())
63
+ .addColumn("identifier", "text", (col) => col.notNull())
64
+ .addColumn("value", "text", (col) => col.notNull())
65
+ .addColumn("expires_at", "datetime", (col) => col.notNull())
66
+ .addColumn("created_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
67
+ .addColumn("updated_at", "datetime", (col) => col.notNull().defaultTo(sql`now()`))
68
+ .execute();
69
+
70
+ console.log("Migrations complete.");
71
+ await db.destroy();
72
+ }
73
+
74
+ main().catch((err) => {
75
+ console.error("Migration failed:", err);
76
+ process.exit(1);
77
+ });
@@ -0,0 +1,54 @@
1
+ import type { Generated, ColumnType } from "kysely";
2
+
3
+ export interface Database {
4
+ user: UserTable;
5
+ session: SessionTable;
6
+ account: AccountTable;
7
+ verification: VerificationTable;
8
+ }
9
+
10
+ export interface UserTable {
11
+ id: string;
12
+ name: string;
13
+ email: string;
14
+ emailVerified: boolean;
15
+ image: string | null;
16
+ createdAt: Generated<Date>;
17
+ updatedAt: Generated<Date>;
18
+ }
19
+
20
+ export interface SessionTable {
21
+ id: string;
22
+ expiresAt: Date;
23
+ token: string;
24
+ createdAt: Generated<Date>;
25
+ updatedAt: Generated<Date>;
26
+ ipAddress: string | null;
27
+ userAgent: string | null;
28
+ userId: string;
29
+ }
30
+
31
+ export interface AccountTable {
32
+ id: string;
33
+ accountId: string;
34
+ providerId: string;
35
+ userId: string;
36
+ accessToken: string | null;
37
+ refreshToken: string | null;
38
+ idToken: string | null;
39
+ accessTokenExpiresAt: Date | null;
40
+ refreshTokenExpiresAt: Date | null;
41
+ scope: string | null;
42
+ password: string | null;
43
+ createdAt: Generated<Date>;
44
+ updatedAt: Generated<Date>;
45
+ }
46
+
47
+ export interface VerificationTable {
48
+ id: string;
49
+ identifier: string;
50
+ value: string;
51
+ expiresAt: Date;
52
+ createdAt: Generated<Date>;
53
+ updatedAt: Generated<Date>;
54
+ }
@@ -0,0 +1,30 @@
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:migrate": "tsx db/migrate.ts"
11
+ },
12
+ "dependencies": {
13
+ "@fastify/cors": "^10.0.0",
14
+ "better-auth": "^1.2.0",
15
+ "fastify": "^5.2.0",
16
+ "kysely": "^0.27.0",
17
+ "mysql2": "^3.11.0"
18
+ {{#if (eq emailProvider "resend")}},
19
+ "resend": "^4.0.0"{{/if}}{{#if (eq emailProvider "sendgrid")}},
20
+ "@sendgrid/mail": "^8.1.0"{{/if}}{{#if (eq emailProvider "smtp")}},
21
+ "nodemailer": "^6.9.0"{{/if}}
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^22.13.0",
25
+ "tsx": "^4.19.0",
26
+ "typescript": "^5.7.0"
27
+ {{#if (eq emailProvider "smtp")}},
28
+ "@types/nodemailer": "^6.4.0"{{/if}}
29
+ }
30
+ }
@@ -0,0 +1,114 @@
1
+ import { betterAuth } from "better-auth";
2
+ import { kyselyAdapter } from "better-auth/adapters/kysely";
3
+ import { db } from "../db/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: kyselyAdapter(db, {
35
+ type: "mysql",
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,34 @@
1
+ import Fastify from "fastify";
2
+ import cors from "@fastify/cors";
3
+ import { auth } from "./auth";
4
+ import { toNodeHandler } from "better-auth/node";
5
+
6
+ const app = Fastify({ logger: true });
7
+
8
+ // CORS
9
+ await app.register(cors, {
10
+ origin: process.env.CORS_ORIGIN || "http://localhost:3001",
11
+ credentials: true,
12
+ });
13
+
14
+ // Mount Better Auth handler
15
+ app.all("/api/auth/*", async (req, reply) => {
16
+ const handler = toNodeHandler(auth);
17
+ // @ts-ignore - bridge Fastify to Node handler
18
+ handler(req.raw, reply.raw);
19
+ });
20
+
21
+ // Health check
22
+ app.get("/", async () => {
23
+ return { status: "ok", message: "Auth backend is running" };
24
+ });
25
+
26
+ // Start server
27
+ const port = Number(process.env.PORT) || 3000;
28
+ try {
29
+ await app.listen({ port, host: "0.0.0.0" });
30
+ console.log(`Server running on http://localhost:${port}`);
31
+ } catch (err) {
32
+ app.log.error(err);
33
+ process.exit(1);
34
+ }
@@ -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=postgresql://user:password@localhost:5432/{{projectName}}
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,75 @@
1
+ # {{projectName}}
2
+
3
+ Authentication backend powered by [Better Auth](https://better-auth.com), built with Hono + Kysely + 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
+ # Run migrations
19
+ npm run db:migrate
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 Kysely query builder with PostgreSQL.
58
+
59
+ ```bash
60
+ npm run db:migrate # Run migrations (creates tables)
61
+ ```
62
+
63
+ ## Frontend Integration
64
+
65
+ ```typescript
66
+ import { createAuthClient } from "better-auth/react";
67
+
68
+ export const authClient = createAuthClient({
69
+ baseURL: "http://localhost:3000",
70
+ });
71
+ ```
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,11 @@
1
+ import { Kysely, PostgresDialect } from "kysely";
2
+ import pg from "pg";
3
+ import type { Database } from "./types";
4
+
5
+ const dialect = new PostgresDialect({
6
+ pool: new pg.Pool({
7
+ connectionString: process.env.DATABASE_URL,
8
+ }),
9
+ });
10
+
11
+ export const db = new Kysely<Database>({ dialect });
@@ -0,0 +1,77 @@
1
+ import { Kysely, PostgresDialect, sql } from "kysely";
2
+ import pg from "pg";
3
+ import type { Database } from "./types";
4
+
5
+ async function main() {
6
+ const dialect = new PostgresDialect({
7
+ pool: new pg.Pool({
8
+ connectionString: process.env.DATABASE_URL,
9
+ }),
10
+ });
11
+
12
+ const db = new Kysely<Database>({ dialect });
13
+
14
+ console.log("Running migrations...");
15
+
16
+ await db.schema
17
+ .createTable("user")
18
+ .ifNotExists()
19
+ .addColumn("id", "text", (col) => col.primaryKey())
20
+ .addColumn("name", "text", (col) => col.notNull())
21
+ .addColumn("email", "text", (col) => col.notNull().unique())
22
+ .addColumn("email_verified", "boolean", (col) => col.notNull().defaultTo(false))
23
+ .addColumn("image", "text")
24
+ .addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
25
+ .addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
26
+ .execute();
27
+
28
+ await db.schema
29
+ .createTable("session")
30
+ .ifNotExists()
31
+ .addColumn("id", "text", (col) => col.primaryKey())
32
+ .addColumn("expires_at", "timestamptz", (col) => col.notNull())
33
+ .addColumn("token", "text", (col) => col.notNull().unique())
34
+ .addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
35
+ .addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
36
+ .addColumn("ip_address", "text")
37
+ .addColumn("user_agent", "text")
38
+ .addColumn("user_id", "text", (col) => col.notNull().references("user.id"))
39
+ .execute();
40
+
41
+ await db.schema
42
+ .createTable("account")
43
+ .ifNotExists()
44
+ .addColumn("id", "text", (col) => col.primaryKey())
45
+ .addColumn("account_id", "text", (col) => col.notNull())
46
+ .addColumn("provider_id", "text", (col) => col.notNull())
47
+ .addColumn("user_id", "text", (col) => col.notNull().references("user.id"))
48
+ .addColumn("access_token", "text")
49
+ .addColumn("refresh_token", "text")
50
+ .addColumn("id_token", "text")
51
+ .addColumn("access_token_expires_at", "timestamptz")
52
+ .addColumn("refresh_token_expires_at", "timestamptz")
53
+ .addColumn("scope", "text")
54
+ .addColumn("password", "text")
55
+ .addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
56
+ .addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
57
+ .execute();
58
+
59
+ await db.schema
60
+ .createTable("verification")
61
+ .ifNotExists()
62
+ .addColumn("id", "text", (col) => col.primaryKey())
63
+ .addColumn("identifier", "text", (col) => col.notNull())
64
+ .addColumn("value", "text", (col) => col.notNull())
65
+ .addColumn("expires_at", "timestamptz", (col) => col.notNull())
66
+ .addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
67
+ .addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))
68
+ .execute();
69
+
70
+ console.log("Migrations complete.");
71
+ await db.destroy();
72
+ }
73
+
74
+ main().catch((err) => {
75
+ console.error("Migration failed:", err);
76
+ process.exit(1);
77
+ });
@@ -0,0 +1,54 @@
1
+ import type { Generated, ColumnType } from "kysely";
2
+
3
+ export interface Database {
4
+ user: UserTable;
5
+ session: SessionTable;
6
+ account: AccountTable;
7
+ verification: VerificationTable;
8
+ }
9
+
10
+ export interface UserTable {
11
+ id: string;
12
+ name: string;
13
+ email: string;
14
+ emailVerified: boolean;
15
+ image: string | null;
16
+ createdAt: Generated<Date>;
17
+ updatedAt: Generated<Date>;
18
+ }
19
+
20
+ export interface SessionTable {
21
+ id: string;
22
+ expiresAt: Date;
23
+ token: string;
24
+ createdAt: Generated<Date>;
25
+ updatedAt: Generated<Date>;
26
+ ipAddress: string | null;
27
+ userAgent: string | null;
28
+ userId: string;
29
+ }
30
+
31
+ export interface AccountTable {
32
+ id: string;
33
+ accountId: string;
34
+ providerId: string;
35
+ userId: string;
36
+ accessToken: string | null;
37
+ refreshToken: string | null;
38
+ idToken: string | null;
39
+ accessTokenExpiresAt: Date | null;
40
+ refreshTokenExpiresAt: Date | null;
41
+ scope: string | null;
42
+ password: string | null;
43
+ createdAt: Generated<Date>;
44
+ updatedAt: Generated<Date>;
45
+ }
46
+
47
+ export interface VerificationTable {
48
+ id: string;
49
+ identifier: string;
50
+ value: string;
51
+ expiresAt: Date;
52
+ createdAt: Generated<Date>;
53
+ updatedAt: Generated<Date>;
54
+ }