create-stackkit-app 0.3.1 → 0.4.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 (96) hide show
  1. package/README.md +12 -94
  2. package/dist/index.d.ts +0 -1
  3. package/dist/index.js +0 -1
  4. package/dist/lib/create-project.d.ts +0 -1
  5. package/dist/lib/create-project.js +103 -66
  6. package/dist/lib/template-composer.d.ts +0 -1
  7. package/dist/lib/template-composer.js +0 -2
  8. package/{templates → modules}/auth/authjs-express/files/lib/auth.ts +0 -3
  9. package/{templates → modules}/auth/authjs-nextjs/files/lib/auth.ts +0 -2
  10. package/modules/auth/better-auth-express/files/lib/auth.ts +16 -0
  11. package/{templates/auth/authjs-express → modules/auth/better-auth-express/files}/routes/auth.ts +3 -3
  12. package/modules/auth/better-auth-express/module.json +38 -0
  13. package/{templates/auth/better-auth-nextjs/app → modules/auth/better-auth-nextjs/files}/api/auth/[...all]/route.ts +1 -0
  14. package/modules/auth/better-auth-nextjs/files/lib/auth.ts +26 -0
  15. package/modules/auth/better-auth-nextjs/module.json +41 -0
  16. package/modules/auth/clerk-express/files/lib/auth.ts +7 -0
  17. package/modules/auth/clerk-express/module.json +19 -0
  18. package/modules/auth/clerk-nextjs/files/lib/auth-provider.tsx +5 -0
  19. package/modules/auth/clerk-nextjs/files/middleware.ts +9 -0
  20. package/modules/auth/clerk-nextjs/module.json +27 -0
  21. package/modules/auth/clerk-react/files/lib/auth-provider.tsx +15 -0
  22. package/modules/auth/clerk-react/module.json +18 -0
  23. package/modules/auth/nextauth/files/app-router/api/auth/[...nextauth]/route.ts +6 -0
  24. package/modules/auth/nextauth/files/lib/auth.ts +82 -0
  25. package/modules/auth/nextauth/files/pages-router/api/auth/[...nextauth].ts +4 -0
  26. package/modules/auth/nextauth/module.json +50 -0
  27. package/modules/database/drizzle-postgresql/files/drizzle.config.ts +10 -0
  28. package/modules/database/drizzle-postgresql/files/lib/db.ts +7 -0
  29. package/modules/database/drizzle-postgresql/files/lib/schema.ts +8 -0
  30. package/modules/database/drizzle-postgresql/module.json +34 -0
  31. package/modules/database/mongoose-mongodb/files/lib/db.ts +40 -0
  32. package/modules/database/mongoose-mongodb/module.json +17 -0
  33. package/{templates/databases/prisma-postgresql → modules/database/prisma-mongodb/files}/lib/db.ts +2 -6
  34. package/{templates/databases/prisma-mongodb → modules/database/prisma-mongodb/files}/prisma/schema.prisma +1 -0
  35. package/modules/database/prisma-mongodb/module.json +36 -0
  36. package/{templates/databases/prisma-mongodb → modules/database/prisma-postgresql/files}/lib/db.ts +2 -6
  37. package/{templates/databases/prisma-postgresql → modules/database/prisma-postgresql/files}/prisma/schema.prisma +1 -0
  38. package/modules/database/prisma-postgresql/module.json +36 -0
  39. package/package.json +8 -6
  40. package/templates/bases/nextjs-base/README.md +36 -0
  41. package/templates/bases/nextjs-base/app/favicon.ico +0 -0
  42. package/templates/bases/nextjs-base/app/globals.css +26 -3
  43. package/templates/bases/nextjs-base/app/layout.tsx +21 -6
  44. package/templates/bases/nextjs-base/app/page.tsx +61 -4
  45. package/templates/bases/nextjs-base/eslint.config.mjs +18 -0
  46. package/templates/bases/nextjs-base/next.config.ts +4 -2
  47. package/templates/bases/nextjs-base/package-lock.json +6538 -0
  48. package/templates/bases/nextjs-base/package.json +12 -10
  49. package/templates/bases/nextjs-base/postcss.config.mjs +7 -0
  50. package/templates/bases/nextjs-base/public/file.svg +1 -0
  51. package/templates/bases/nextjs-base/public/globe.svg +1 -0
  52. package/templates/bases/nextjs-base/public/next.svg +1 -0
  53. package/templates/bases/nextjs-base/public/vercel.svg +1 -0
  54. package/templates/bases/nextjs-base/public/window.svg +1 -0
  55. package/templates/bases/nextjs-base/template.json +12 -1
  56. package/templates/bases/nextjs-base/tsconfig.json +9 -2
  57. package/templates/bases/react-vite-base/index.html +13 -0
  58. package/templates/bases/react-vite-base/package.json +27 -0
  59. package/templates/bases/react-vite-base/src/App.css +14 -0
  60. package/templates/bases/react-vite-base/src/App.tsx +23 -0
  61. package/templates/bases/react-vite-base/src/index.css +68 -0
  62. package/templates/bases/react-vite-base/src/main.tsx +10 -0
  63. package/templates/bases/react-vite-base/src/vite-env.d.ts +1 -0
  64. package/templates/bases/react-vite-base/template.json +5 -0
  65. package/templates/bases/react-vite-base/tsconfig.json +21 -0
  66. package/templates/bases/react-vite-base/vite.config.ts +7 -0
  67. package/dist/index.d.ts.map +0 -1
  68. package/dist/index.js.map +0 -1
  69. package/dist/lib/create-project.d.ts.map +0 -1
  70. package/dist/lib/create-project.js.map +0 -1
  71. package/dist/lib/template-composer.d.ts.map +0 -1
  72. package/dist/lib/template-composer.js.map +0 -1
  73. package/templates/auth/authjs-express/config.json +0 -20
  74. package/templates/auth/authjs-express/lib/auth.ts +0 -43
  75. package/templates/auth/authjs-nextjs/config.json +0 -19
  76. package/templates/auth/authjs-nextjs/files/api/auth/[...nextauth]/route.ts +0 -3
  77. package/templates/auth/authjs-nextjs/lib/auth.ts +0 -45
  78. package/templates/auth/better-auth-express/config.json +0 -18
  79. package/templates/auth/better-auth-express/src/lib/auth.ts +0 -12
  80. package/templates/auth/better-auth-express/src/routes/auth.ts +0 -10
  81. package/templates/auth/better-auth-nextjs/config.json +0 -18
  82. package/templates/auth/better-auth-nextjs/lib/auth.ts +0 -14
  83. package/templates/auth/better-auth-react/config.json +0 -15
  84. package/templates/auth/better-auth-react/lib/auth-client.ts +0 -9
  85. package/templates/auth/nextauth/app/api/auth/[...nextauth]/route.ts +0 -3
  86. package/templates/auth/nextauth/config.json +0 -18
  87. package/templates/auth/nextauth/lib/auth.ts +0 -31
  88. package/templates/bases/nextjs-base/.eslintrc.json +0 -3
  89. package/templates/databases/prisma-mongodb/config.json +0 -21
  90. package/templates/databases/prisma-postgresql/config.json +0 -22
  91. package/{templates → modules}/auth/authjs-express/files/routes/auth.ts +1 -1
  92. /package/{templates → modules}/auth/authjs-express/module.json +0 -0
  93. /package/{templates/auth/authjs-nextjs/app → modules/auth/authjs-nextjs/files}/api/auth/[...nextauth]/route.ts +0 -0
  94. /package/{templates → modules}/auth/authjs-nextjs/module.json +0 -0
  95. /package/{templates → modules}/auth/better-auth-react/files/lib/auth-client.ts +0 -0
  96. /package/{templates → modules}/auth/better-auth-react/module.json +0 -0
package/README.md CHANGED
@@ -1,107 +1,25 @@
1
1
  # create-stackkit-app
2
2
 
3
- Production-ready project generator with interactive wizard setup.
4
-
5
- [![npm](https://img.shields.io/npm/v/create-stackkit-app)](https://www.npmjs.com/package/create-stackkit-app)
3
+ Create production-ready projects with one command.
6
4
 
7
5
  ## Usage
8
6
 
9
7
  ```bash
10
- # npm
11
- npx create-stackkit-app@latest my-app
12
-
13
- # pnpm
14
- pnpm dlx create-stackkit-app@latest my-app
15
-
16
- # yarn
17
- yarn dlx create-stackkit-app@latest my-app
18
-
19
- # bun
20
- bunx create-stackkit-app@latest my-app
21
- ```
22
-
23
- ## Interactive Wizard
24
-
25
- The wizard guides you through project setup:
26
-
27
- 1. **Framework Selection**
28
- - Next.js
29
- - Express.js
30
- - React (Vite)
31
- - Astro
32
-
33
- 2. **Database/ORM**
34
- - Prisma + PostgreSQL
35
- - Prisma + MongoDB
36
- - Mongoose + MongoDB
37
- - Drizzle + PostgreSQL
38
- - None
39
-
40
- 3. **Authentication**
41
- - Auth.js (NextAuth)
42
- - Better Auth
43
- - Clerk
44
- - None
45
-
46
- 4. **Language**
47
- - TypeScript _(recommended)_
48
- - JavaScript
49
-
50
- 5. **Package Manager**
51
- - pnpm _(recommended)_
52
- - npm
53
- - yarn
54
-
55
- ## Automatic Setup
56
-
57
- After answering questions, the tool automatically:
58
-
59
- ✅ Creates project files
60
- ✅ Installs dependencies
61
- ✅ Initializes git repository
62
-
63
- No manual `npm install` or `git init` needed.
64
-
65
- ## What's Included
66
-
67
- Default Next.js + Prisma + PostgreSQL template:
68
-
69
- - ⚡ Next.js 15 with App Router
70
- - 🛡️ TypeScript
71
- - 🗄️ Prisma ORM + PostgreSQL
72
- - 🎨 shadcn/ui components
73
- - 💅 Tailwind CSS
74
- - ✅ Zod validation
75
- - 🔧 ESLint + Prettier
76
-
77
- ## Next Steps
78
-
79
- After creating your project:
80
-
81
- ```bash
82
- cd my-app
83
- pnpm dev
8
+ npx create-stackkit-app my-app
84
9
  ```
85
10
 
86
- Add modules to existing projects:
11
+ Interactive wizard for:
12
+ - **Framework**: Next.js, Express, React (Vite)
13
+ - **Database**: Prisma, Drizzle, Mongoose, or none
14
+ - **Auth**: Auth.js, Better Auth, Clerk, or none
15
+ - **Language**: TypeScript or JavaScript
87
16
 
88
- ```bash
89
- npx stackkit-cli add auth
90
- ```
91
-
92
- ## Full CLI
93
-
94
- For advanced features:
17
+ ## Development
95
18
 
96
19
  ```bash
97
- npm install -g stackkit-cli
98
-
99
- stackkit list # View all templates/modules
100
- stackkit add auth
20
+ pnpm install
21
+ pnpm build
22
+ npx . test-app
101
23
  ```
102
24
 
103
- See [stackkit-cli](https://www.npmjs.com/package/stackkit-cli) for details.
104
-
105
- ## License
106
-
107
- MIT
25
+ See [main README](../../README.md) for full documentation.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
2
  export {};
3
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -14,4 +14,3 @@ async function main() {
14
14
  }
15
15
  }
16
16
  main();
17
- //# sourceMappingURL=index.js.map
@@ -1,2 +1 @@
1
1
  export declare function createProject(projectName?: string): Promise<void>;
2
- //# sourceMappingURL=create-project.d.ts.map
@@ -54,36 +54,30 @@ async function getProjectConfig(projectName) {
54
54
  { name: 'Next.js', value: 'nextjs' },
55
55
  { name: 'Express.js', value: 'express' },
56
56
  { name: 'React (Vite)', value: 'react-vite' },
57
- { name: 'Astro', value: 'astro' },
58
57
  ],
59
58
  },
60
59
  {
61
60
  type: 'list',
62
61
  name: 'database',
63
62
  message: 'Select database/ORM:',
64
- choices: (answers) => {
65
- // React apps don't need server-side database
66
- if (answers.framework === 'react-vite') {
67
- return [{ name: 'None', value: 'none' }];
68
- }
69
- return [
70
- { name: 'Prisma + PostgreSQL', value: 'prisma-postgresql' },
71
- { name: 'Prisma + MongoDB', value: 'prisma-mongodb' },
72
- { name: 'Mongoose + MongoDB', value: 'mongoose-mongodb' },
73
- { name: 'Drizzle + PostgreSQL', value: 'drizzle-postgresql' },
74
- { name: 'None', value: 'none' },
75
- ];
76
- },
63
+ when: (answers) => answers.framework !== 'react-vite',
64
+ choices: [
65
+ { name: 'Prisma + PostgreSQL', value: 'prisma-postgresql' },
66
+ { name: 'Prisma + MongoDB', value: 'prisma-mongodb' },
67
+ { name: 'Mongoose + MongoDB', value: 'mongoose-mongodb' },
68
+ { name: 'Drizzle + PostgreSQL', value: 'drizzle-postgresql' },
69
+ { name: 'None', value: 'none' },
70
+ ],
77
71
  },
78
72
  {
79
73
  type: 'list',
80
74
  name: 'auth',
81
75
  message: 'Select authentication:',
82
76
  choices: (answers) => {
83
- // React apps - client-side only
84
77
  if (answers.framework === 'react-vite') {
85
78
  return [
86
- { name: 'Better Auth (React)', value: 'better-auth-react' },
79
+ { name: 'Better Auth', value: 'better-auth-react' },
80
+ { name: 'Clerk', value: 'clerk-react' },
87
81
  { name: 'None', value: 'none' },
88
82
  ];
89
83
  }
@@ -93,7 +87,7 @@ async function getProjectConfig(projectName) {
93
87
  { name: 'Auth.js v5', value: 'authjs-nextjs' },
94
88
  { name: 'NextAuth.js', value: 'nextauth' },
95
89
  { name: 'Better Auth', value: 'better-auth-nextjs' },
96
- { name: 'Clerk', value: 'clerk' },
90
+ { name: 'Clerk', value: 'clerk-nextjs' },
97
91
  { name: 'None', value: 'none' },
98
92
  ];
99
93
  }
@@ -102,6 +96,7 @@ async function getProjectConfig(projectName) {
102
96
  return [
103
97
  { name: 'Auth.js', value: 'authjs-express' },
104
98
  { name: 'Better Auth', value: 'better-auth-express' },
99
+ { name: 'Clerk', value: 'clerk-express' },
105
100
  { name: 'None', value: 'none' },
106
101
  ];
107
102
  }
@@ -130,7 +125,7 @@ async function getProjectConfig(projectName) {
130
125
  return {
131
126
  projectName: projectName || answers.projectName,
132
127
  framework: answers.framework,
133
- database: answers.database,
128
+ database: answers.framework === 'react-vite' ? 'none' : answers.database,
134
129
  auth: answers.auth,
135
130
  language: answers.language,
136
131
  packageManager: answers.packageManager,
@@ -206,37 +201,51 @@ async function copyBaseFramework(templatesDir, targetDir, framework) {
206
201
  });
207
202
  }
208
203
  async function mergeDatabaseConfig(templatesDir, targetDir, database) {
209
- const dbDir = path_1.default.join(templatesDir, 'databases', database);
210
- if (!(await fs_extra_1.default.pathExists(dbDir))) {
211
- console.warn(`Database template not found: ${database}`);
204
+ // Use modules directory (sibling to templates)
205
+ const modulesDir = path_1.default.join(templatesDir, '..', 'modules');
206
+ const dbModulePath = path_1.default.join(modulesDir, 'database', database);
207
+ if (!(await fs_extra_1.default.pathExists(dbModulePath))) {
208
+ console.warn(`Database module not found: ${database}`);
212
209
  return;
213
210
  }
214
- // Read config
215
- const configPath = path_1.default.join(dbDir, 'config.json');
216
- if (!(await fs_extra_1.default.pathExists(configPath))) {
211
+ // Read module.json
212
+ const moduleJsonPath = path_1.default.join(dbModulePath, 'module.json');
213
+ if (!(await fs_extra_1.default.pathExists(moduleJsonPath))) {
217
214
  return;
218
215
  }
219
- const config = await fs_extra_1.default.readJson(configPath);
220
- // Copy database files
221
- const entries = await fs_extra_1.default.readdir(dbDir, { withFileTypes: true });
222
- for (const entry of entries) {
223
- if (entry.name === 'config.json')
224
- continue;
225
- const sourcePath = path_1.default.join(dbDir, entry.name);
226
- const destPath = path_1.default.join(targetDir, entry.name);
227
- if (entry.isDirectory()) {
228
- await fs_extra_1.default.copy(sourcePath, destPath, { overwrite: false });
229
- }
230
- else {
231
- await fs_extra_1.default.copy(sourcePath, destPath, { overwrite: false });
216
+ const moduleData = await fs_extra_1.default.readJson(moduleJsonPath);
217
+ // Copy files from module
218
+ const filesDir = path_1.default.join(dbModulePath, 'files');
219
+ if (await fs_extra_1.default.pathExists(filesDir)) {
220
+ // Copy files based on patches in module.json
221
+ for (const patch of moduleData.patches || []) {
222
+ if (patch.type === 'create-file') {
223
+ const sourceFile = path_1.default.join(filesDir, patch.source);
224
+ let destFile = path_1.default.join(targetDir, patch.destination);
225
+ // Simple placeholder replacement for lib
226
+ destFile = destFile.replace('{{lib}}', 'lib').replace('{{src}}', 'src');
227
+ if (await fs_extra_1.default.pathExists(sourceFile)) {
228
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(destFile));
229
+ await fs_extra_1.default.copy(sourceFile, destFile, { overwrite: false });
230
+ }
231
+ }
232
232
  }
233
233
  }
234
- // Merge package.json
235
- await mergePackageJson(targetDir, config);
236
- // Merge .env
237
- await mergeEnvFile(targetDir, config.env || {});
234
+ // Merge package.json with module dependencies
235
+ await mergePackageJson(targetDir, {
236
+ dependencies: moduleData.dependencies,
237
+ devDependencies: moduleData.devDependencies,
238
+ });
239
+ // Merge .env with module envVars
240
+ const envVars = {};
241
+ for (const envVar of moduleData.envVars || []) {
242
+ envVars[envVar.key] = envVar.value;
243
+ }
244
+ await mergeEnvFile(targetDir, envVars);
238
245
  }
239
246
  async function mergeAuthConfig(templatesDir, targetDir, framework, auth) {
247
+ // Use modules directory (sibling to templates)
248
+ const modulesDir = path_1.default.join(templatesDir, '..', 'modules');
240
249
  // Auth modules are now named with framework suffix
241
250
  // e.g., better-auth-nextjs, authjs-express, better-auth-react
242
251
  // If auth already has framework suffix, use it directly
@@ -244,38 +253,67 @@ async function mergeAuthConfig(templatesDir, targetDir, framework, auth) {
244
253
  const authMap = {
245
254
  nextauth: 'nextauth',
246
255
  'better-auth': framework === 'nextjs' ? 'better-auth-nextjs' : 'better-auth-express',
247
- clerk: 'clerk',
256
+ clerk: framework === 'nextjs'
257
+ ? 'clerk-nextjs'
258
+ : framework === 'react-vite'
259
+ ? 'clerk-react'
260
+ : 'clerk-express',
248
261
  };
249
262
  const authKey = auth.includes('-') ? auth : authMap[auth] || auth;
250
- const authDir = path_1.default.join(templatesDir, 'auth', authKey);
251
- if (!(await fs_extra_1.default.pathExists(authDir))) {
252
- console.warn(`Auth template not found: ${authKey}`);
263
+ const authModulePath = path_1.default.join(modulesDir, 'auth', authKey);
264
+ if (!(await fs_extra_1.default.pathExists(authModulePath))) {
265
+ console.warn(`Auth module not found: ${authKey}`);
253
266
  return;
254
267
  }
255
- // Read config
256
- const configPath = path_1.default.join(authDir, 'config.json');
257
- if (!(await fs_extra_1.default.pathExists(configPath))) {
268
+ // Read module.json
269
+ const moduleJsonPath = path_1.default.join(authModulePath, 'module.json');
270
+ if (!(await fs_extra_1.default.pathExists(moduleJsonPath))) {
258
271
  return;
259
272
  }
260
- const config = await fs_extra_1.default.readJson(configPath);
261
- // Copy auth files
262
- const entries = await fs_extra_1.default.readdir(authDir, { withFileTypes: true });
263
- for (const entry of entries) {
264
- if (entry.name === 'config.json')
265
- continue;
266
- const sourcePath = path_1.default.join(authDir, entry.name);
267
- const destPath = path_1.default.join(targetDir, entry.name);
268
- if (entry.isDirectory()) {
269
- await fs_extra_1.default.copy(sourcePath, destPath, { overwrite: false });
270
- }
271
- else {
272
- await fs_extra_1.default.copy(sourcePath, destPath, { overwrite: false });
273
+ const moduleData = await fs_extra_1.default.readJson(moduleJsonPath);
274
+ // Copy files from module
275
+ const filesDir = path_1.default.join(authModulePath, 'files');
276
+ if (await fs_extra_1.default.pathExists(filesDir)) {
277
+ // Determine path replacements based on framework
278
+ const getReplacements = () => {
279
+ if (framework === 'nextjs') {
280
+ return { lib: 'lib', router: 'app' };
281
+ }
282
+ else if (framework === 'express') {
283
+ return { lib: 'src', router: 'src' };
284
+ }
285
+ else {
286
+ return { lib: 'src', router: 'src' };
287
+ }
288
+ };
289
+ const replacements = getReplacements();
290
+ // Copy files based on patches in module.json
291
+ for (const patch of moduleData.patches || []) {
292
+ if (patch.type === 'create-file') {
293
+ const sourceFile = path_1.default.join(filesDir, patch.source);
294
+ let destFile = path_1.default.join(targetDir, patch.destination);
295
+ // Replace placeholders
296
+ destFile = destFile
297
+ .replace('{{lib}}', replacements.lib)
298
+ .replace('{{router}}', replacements.router);
299
+ if (await fs_extra_1.default.pathExists(sourceFile)) {
300
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(destFile));
301
+ await fs_extra_1.default.copy(sourceFile, destFile, { overwrite: false });
302
+ }
303
+ }
273
304
  }
274
305
  }
275
- // Merge package.json
276
- await mergePackageJson(targetDir, config);
277
- // Merge .env
278
- await mergeEnvFile(targetDir, config.env || {});
306
+ // Merge package.json with module dependencies
307
+ await mergePackageJson(targetDir, {
308
+ dependencies: moduleData.dependencies,
309
+ devDependencies: moduleData.devDependencies,
310
+ });
311
+ // Merge .env with module envVars
312
+ const envVars = {};
313
+ for (const envVar of moduleData.envVars || []) {
314
+ envVars[envVar.key] = envVar.value;
315
+ }
316
+ await mergeEnvFile(targetDir, envVars);
279
317
  }
280
318
  async function mergePackageJson(targetDir, config) {
281
319
  const pkgPath = path_1.default.join(targetDir, 'package.json');
@@ -397,4 +435,3 @@ function showNextSteps(config) {
397
435
  console.log(chalk_1.default.cyan(` cd ${config.projectName}`));
398
436
  console.log(chalk_1.default.cyan(` ${config.packageManager}${config.packageManager === 'npm' ? ' run' : ''} dev\n`));
399
437
  }
400
- //# sourceMappingURL=create-project.js.map
@@ -14,4 +14,3 @@ export declare class TemplateComposer {
14
14
  private writeEnvFile;
15
15
  private getAuthKey;
16
16
  }
17
- //# sourceMappingURL=template-composer.d.ts.map
@@ -7,7 +7,6 @@ exports.TemplateComposer = void 0;
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  class TemplateComposer {
10
- templatesDir;
11
10
  constructor(templatesDir) {
12
11
  this.templatesDir = templatesDir;
13
12
  }
@@ -196,4 +195,3 @@ class TemplateComposer {
196
195
  }
197
196
  }
198
197
  exports.TemplateComposer = TemplateComposer;
199
- //# sourceMappingURL=template-composer.js.map
@@ -1,6 +1,3 @@
1
- import { Auth } from '@auth/core';
2
- import GitHub from '@auth/core/providers/github';
3
- import Google from '@auth/core/providers/google';
4
1
  import Credentials from '@auth/core/providers/credentials';
5
2
 
6
3
  export const authConfig = {
@@ -1,6 +1,4 @@
1
1
  import NextAuth from 'next-auth';
2
- import GitHub from 'next-auth/providers/github';
3
- import Google from 'next-auth/providers/google';
4
2
  import Credentials from 'next-auth/providers/credentials';
5
3
 
6
4
  export const { handlers, signIn, signOut, auth } = NextAuth({
@@ -0,0 +1,16 @@
1
+ import { betterAuth } from 'better-auth';
2
+
3
+ export const auth = betterAuth({
4
+ secret: process.env.BETTER_AUTH_SECRET!,
5
+ baseURL: process.env.BETTER_AUTH_URL!,
6
+
7
+ emailAndPassword: {
8
+ enabled: true,
9
+ },
10
+
11
+ // Uncomment to add database adapter
12
+ // database: {
13
+ // provider: "pg", // or "mongodb", "mysql"
14
+ // url: process.env.DATABASE_URL!,
15
+ // },
16
+ });
@@ -1,11 +1,11 @@
1
1
  import { Router } from 'express';
2
- import { Auth } from '@auth/core';
3
- import { authConfig } from '../lib/auth';
2
+ import { auth } from '../lib/auth';
4
3
 
5
4
  const router = Router();
6
5
 
6
+ // Mount Better Auth handlers
7
7
  router.all('/auth/*', async (req, res) => {
8
- const response = await Auth(req, authConfig);
8
+ const response = await auth.handler(req);
9
9
  return res.status(response.status).json(response.body);
10
10
  });
11
11
 
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "auth",
3
+ "displayName": "Better Auth (Express)",
4
+ "description": "Modern authentication with Better Auth for Express",
5
+ "category": "auth",
6
+ "supportedFrameworks": ["express"],
7
+ "dependencies": {
8
+ "better-auth": "^1.0.0"
9
+ },
10
+ "envVars": [
11
+ {
12
+ "key": "BETTER_AUTH_SECRET",
13
+ "value": "",
14
+ "description": "Secret key for Better Auth. Generate with: openssl rand -base64 32",
15
+ "required": true
16
+ },
17
+ {
18
+ "key": "BETTER_AUTH_URL",
19
+ "value": "http://localhost:3000",
20
+ "description": "Base URL of your application (change in production)",
21
+ "required": true
22
+ }
23
+ ],
24
+ "patches": [
25
+ {
26
+ "type": "create-file",
27
+ "description": "Create Better Auth configuration",
28
+ "source": "lib/auth.ts",
29
+ "destination": "src/lib/auth.ts"
30
+ },
31
+ {
32
+ "type": "create-file",
33
+ "description": "Create auth routes",
34
+ "source": "routes/auth.ts",
35
+ "destination": "src/routes/auth.ts"
36
+ }
37
+ ]
38
+ }
@@ -2,3 +2,4 @@ import { auth } from '@/lib/auth';
2
2
  import { toNextJsHandler } from 'better-auth/next-js';
3
3
 
4
4
  export const { GET, POST } = toNextJsHandler(auth);
5
+
@@ -0,0 +1,26 @@
1
+ import { prismaAdapter } from '@better-auth/prisma';
2
+ import { betterAuth } from 'better-auth';
3
+ import { prisma } from './db';
4
+
5
+ export const auth = betterAuth({
6
+ database: prismaAdapter(prisma, {
7
+ provider: 'postgresql', // Change to 'mongodb' if using MongoDB
8
+ }),
9
+ emailAndPassword: {
10
+ enabled: true,
11
+ },
12
+ socialProviders: {
13
+ // Uncomment to add OAuth providers
14
+ // google: {
15
+ // clientId: process.env.GOOGLE_CLIENT_ID!,
16
+ // clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
17
+ // },
18
+ // github: {
19
+ // clientId: process.env.GITHUB_CLIENT_ID!,
20
+ // clientSecret: process.env.GITHUB_CLIENT_SECRET!,
21
+ // },
22
+ },
23
+ });
24
+
25
+ export type Session = typeof auth.$Infer.Session;
26
+ export type User = typeof auth.$Infer.User;
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "auth",
3
+ "displayName": "Better Auth (Next.js)",
4
+ "description": "Modern authentication with Better Auth for Next.js App Router",
5
+ "category": "auth",
6
+ "provider": "better-auth",
7
+ "supportedFrameworks": ["nextjs"],
8
+ "compatibleDatabases": ["prisma-postgresql", "prisma-mongodb"],
9
+ "dependencies": {
10
+ "better-auth": "^1.1.4",
11
+ "@better-auth/prisma": "^1.1.4"
12
+ },
13
+ "envVars": [
14
+ {
15
+ "key": "BETTER_AUTH_SECRET",
16
+ "value": "",
17
+ "description": "Secret key for Better Auth. Generate with: openssl rand -base64 32",
18
+ "required": true
19
+ },
20
+ {
21
+ "key": "BETTER_AUTH_URL",
22
+ "value": "http://localhost:3000",
23
+ "description": "Base URL of your application (change in production)",
24
+ "required": true
25
+ }
26
+ ],
27
+ "patches": [
28
+ {
29
+ "type": "create-file",
30
+ "description": "Create Better Auth configuration",
31
+ "source": "lib/auth.ts",
32
+ "destination": "{{lib}}/auth.ts"
33
+ },
34
+ {
35
+ "type": "create-file",
36
+ "description": "Create Better Auth API route handler",
37
+ "source": "app/api/auth/[...all]/route.ts",
38
+ "destination": "{{router}}/api/auth/[...all]/route.ts"
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,7 @@
1
+ import { clerkClient, clerkMiddleware, requireAuth } from '@clerk/express';
2
+
3
+ export { clerkMiddleware, requireAuth };
4
+
5
+ export async function getCurrentUser(userId: string) {
6
+ return await clerkClient.users.getUser(userId);
7
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "clerk-express",
3
+ "description": "Clerk Authentication for Express.js",
4
+ "category": "auth",
5
+ "framework": "express",
6
+ "dependencies": {
7
+ "@clerk/express": "^1.4.5"
8
+ },
9
+ "env": {
10
+ "CLERK_PUBLISHABLE_KEY": "pk_test_your_key_here",
11
+ "CLERK_SECRET_KEY": "sk_test_your_key_here"
12
+ },
13
+ "files": [
14
+ {
15
+ "source": "files/lib/auth.ts",
16
+ "destination": "lib/auth.ts"
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,5 @@
1
+ import { ClerkProvider } from '@clerk/nextjs';
2
+
3
+ export function AuthProvider({ children }: { children: React.ReactNode }) {
4
+ return <ClerkProvider>{children}</ClerkProvider>;
5
+ }
@@ -0,0 +1,9 @@
1
+ import { authMiddleware } from '@clerk/nextjs';
2
+
3
+ export default authMiddleware({
4
+ publicRoutes: ['/'],
5
+ });
6
+
7
+ export const config = {
8
+ matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
9
+ };
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "clerk-nextjs",
3
+ "description": "Clerk Authentication for Next.js",
4
+ "category": "auth",
5
+ "framework": "nextjs",
6
+ "dependencies": {
7
+ "@clerk/nextjs": "^6.10.2"
8
+ },
9
+ "env": {
10
+ "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY": "pk_test_your_key_here",
11
+ "CLERK_SECRET_KEY": "sk_test_your_key_here",
12
+ "NEXT_PUBLIC_CLERK_SIGN_IN_URL": "/sign-in",
13
+ "NEXT_PUBLIC_CLERK_SIGN_UP_URL": "/sign-up",
14
+ "NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL": "/",
15
+ "NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL": "/"
16
+ },
17
+ "files": [
18
+ {
19
+ "source": "files/lib/auth-provider.tsx",
20
+ "destination": "lib/auth-provider.tsx"
21
+ },
22
+ {
23
+ "source": "files/middleware.ts",
24
+ "destination": "middleware.ts"
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,15 @@
1
+ import { ClerkProvider } from '@clerk/clerk-react';
2
+
3
+ const publishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
4
+
5
+ if (!publishableKey) {
6
+ throw new Error('Missing Publishable Key');
7
+ }
8
+
9
+ export function AuthProvider({ children }: { children: React.ReactNode }) {
10
+ return (
11
+ <ClerkProvider publishableKey={publishableKey} afterSignOutUrl="/">
12
+ {children}
13
+ </ClerkProvider>
14
+ );
15
+ }