create-better-t-stack 2.22.4 → 2.22.6

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.
package/README.md CHANGED
@@ -27,12 +27,12 @@ Follow the prompts to configure your project or use the `--yes` flag for default
27
27
  | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
28
28
  | **TypeScript** | End-to-end type safety across all parts of your application |
29
29
  | **Frontend** | • React with TanStack Router<br>• React with React Router<br>• React with TanStack Start (SSR)<br>• Next.js<br>• SvelteKit<br>• Nuxt (Vue)<br>• SolidJS<br>• React Native with NativeWind (via Expo)<br>• React Native with Unistyles (via Expo)<br>• None |
30
- | **Backend** | • Hono<br>• Express<br>• Elysia<br>• Next.js API routes<br>• Convex<br>• Fastify<br>• None |
30
+ | **Backend** | • Hono<br>• Express<br>• Elysia<br>• Next.js API routes<br>• Convex<br>• Fastify<br>• None |
31
31
  | **API Layer** | • tRPC (type-safe APIs)<br>• oRPC (OpenAPI-compatible type-safe APIs)<br>• None |
32
- | **Runtime** | • Bun<br>• Node.js |
32
+ | **Runtime** | • Bun<br>• Node.js<br>• Cloudflare Workers<br>• None |
33
33
  | **Database** | • SQLite<br>• PostgreSQL<br>• MySQL<br>• MongoDB<br>• None |
34
34
  | **ORM** | • Drizzle (TypeScript-first)<br>• Prisma (feature-rich)<br>• Mongoose (for MongoDB)<br>• None |
35
- | **Database Setup** | • Turso (SQLite)<br>• Neon (PostgreSQL)<br>• Prisma Postgres (via Prisma Accelerate)<br>• MongoDB Atlas<br>• None (manual setup) |
35
+ | **Database Setup** | • Turso (SQLite)<br>• Cloudflare D1 (SQLite)<br>• Neon (PostgreSQL)<br>• Supabase (PostgreSQL)<br>• Prisma Postgres (via Prisma Accelerate)<br>• MongoDB Atlas<br>• None (manual setup) |
36
36
  | **Authentication** | Better-Auth (email/password, with more options coming soon) |
37
37
  | **Styling** | Tailwind CSS with shadcn/ui components |
38
38
  | **Addons** | • PWA support<br>• Tauri (desktop applications)<br>• Starlight (documentation site)<br>• Biome (linting and formatting)<br>• Husky (Git hooks)<br>• Turborepo (optimized builds) |
@@ -59,9 +59,9 @@ Options:
59
59
  --package-manager <pm> Package manager (npm, pnpm, bun)
60
60
  --install Install dependencies
61
61
  --no-install Skip installing dependencies
62
- --db-setup <setup> Database setup (turso, neon, prisma-postgres, mongodb-atlas, none)
62
+ --db-setup <setup> Database setup (turso, d1, neon, supabase, prisma-postgres, mongodb-atlas, none)
63
63
  --backend <framework> Backend framework (hono, express, elysia, next, convex, fastify, none)
64
- --runtime <runtime> Runtime (bun, node, none)
64
+ --runtime <runtime> Runtime (bun, node, workers, none)
65
65
  --api <type> API type (trpc, orpc, none)
66
66
  -h, --help Display help
67
67
  ```
@@ -104,6 +104,12 @@ Create a project with Turso database setup:
104
104
  npx create-better-t-stack my-app --database sqlite --orm drizzle --db-setup turso
105
105
  ```
106
106
 
107
+ Create a project with Supabase PostgreSQL setup:
108
+
109
+ ```bash
110
+ npx create-better-t-stack my-app --database postgres --orm drizzle --db-setup supabase --auth
111
+ ```
112
+
107
113
  Create a project with Convex backend:
108
114
 
109
115
  ```bash
@@ -116,10 +122,48 @@ Create a project with documentation site:
116
122
  npx create-better-t-stack my-app --addons starlight
117
123
  ```
118
124
 
125
+ Create a minimal TypeScript project with no backend:
126
+
127
+ ```bash
128
+ npx create-better-t-stack my-app --backend none --frontend tanstack-router
129
+ ```
130
+
131
+ Create a backend-only project with no frontend:
132
+
133
+ ```bash
134
+ npx create-better-t-stack my-app --frontend none --backend hono --database postgres --orm drizzle
135
+ ```
136
+
137
+ Create a simple frontend-only project:
138
+
139
+ ```bash
140
+ npx create-better-t-stack my-app --backend none --frontend next --addons none --examples none
141
+ ```
142
+
143
+ Create a Cloudflare Workers project:
144
+
145
+ ```bash
146
+ npx create-better-t-stack my-app --backend hono --runtime workers --database sqlite --orm drizzle --db-setup d1
147
+ ```
148
+
149
+ Create a minimal API-only project:
150
+
151
+ ```bash
152
+ npx create-better-t-stack my-app --frontend none --backend hono --api trpc --database none --addons none
153
+ ```
154
+
119
155
  ## Compatibility Notes
120
156
 
121
157
  - **Convex backend**: Automatically disables authentication, database, ORM, and API options
122
158
  - **Backend 'none'**: If selected, this option will force related options like API, ORM, database, authentication, and runtime to 'none'. Examples will also be disabled (set to none/empty).
159
+ - **Frontend 'none'**: Creates a backend-only project. When selected, PWA, Tauri, and certain examples may be disabled.
160
+ - **API 'none'**: Disables tRPC/oRPC setup. Can be used with backend frameworks for REST APIs or custom API implementations.
161
+ - **Database 'none'**: Disables database setup. Automatically sets ORM to 'none' and disables authentication.
162
+ - **ORM 'none'**: Can be used when you want to handle database operations manually or use a different ORM.
163
+ - **Runtime 'none'**: Only available with Convex backend or when backend is 'none'.
164
+ - **Cloudflare Workers runtime**: Only compatible with Hono backend, Drizzle ORM (or no ORM), and SQLite database (with D1 setup). Not compatible with MongoDB.
165
+ - **Addons 'none'**: Skips all addons (PWA, Tauri, Starlight, Biome, Husky, Turborepo).
166
+ - **Examples 'none'**: Skips all example implementations (todo, AI chat).
123
167
  - **SvelteKit, Nuxt, and SolidJS** frontends are only compatible with oRPC API layer
124
168
  - **PWA support** requires React with TanStack Router, React Router, or SolidJS
125
169
  - **Tauri desktop app** requires React (TanStack Router/React Router), Nuxt, SvelteKit, or SolidJS
package/dist/index.js CHANGED
@@ -52,6 +52,7 @@ const dependencyVersionMap = {
52
52
  "drizzle-orm": "^0.44.2",
53
53
  "drizzle-kit": "^0.31.2",
54
54
  "@libsql/client": "^0.15.9",
55
+ "@neondatabase/serverless": "^1.0.1",
55
56
  pg: "^8.14.1",
56
57
  "@types/pg": "^8.11.11",
57
58
  mysql2: "^3.14.0",
@@ -93,7 +94,7 @@ const dependencyVersionMap = {
93
94
  "@trpc/tanstack-react-query": "^11.4.2",
94
95
  "@trpc/server": "^11.4.2",
95
96
  "@trpc/client": "^11.4.2",
96
- convex: "^1.23.0",
97
+ convex: "^1.25.0",
97
98
  "@convex-dev/react-query": "^0.0.0-alpha.8",
98
99
  "convex-svelte": "^0.0.11",
99
100
  "@tanstack/svelte-query": "^5.74.4",
@@ -3416,7 +3417,12 @@ async function setupDatabase(config) {
3416
3417
  devDependencies: ["drizzle-kit"],
3417
3418
  projectDir: serverDir
3418
3419
  });
3419
- else if (database === "postgres") await addPackageDependency({
3420
+ else if (database === "postgres") if (dbSetup === "neon") await addPackageDependency({
3421
+ dependencies: ["drizzle-orm", "@neondatabase/serverless"],
3422
+ devDependencies: ["drizzle-kit"],
3423
+ projectDir: serverDir
3424
+ });
3425
+ else await addPackageDependency({
3420
3426
  dependencies: ["drizzle-orm", "pg"],
3421
3427
  devDependencies: ["drizzle-kit", "@types/pg"],
3422
3428
  projectDir: serverDir
@@ -3573,19 +3579,15 @@ function generateReadmeContent(options) {
3573
3579
  const { projectName, packageManager, database, auth, addons = [], orm = "drizzle", runtime = "bun", frontend = ["tanstack-router"], backend = "hono", api = "trpc" } = options;
3574
3580
  const isConvex = backend === "convex";
3575
3581
  const hasReactRouter = frontend.includes("react-router");
3576
- const hasTanstackRouter = frontend.includes("tanstack-router");
3577
3582
  const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
3578
- const hasNext = frontend.includes("next");
3579
- const hasTanstackStart = frontend.includes("tanstack-start");
3580
3583
  const hasSvelte = frontend.includes("svelte");
3581
- const hasSolid = frontend.includes("solid");
3582
- const hasNuxt = frontend.includes("nuxt");
3583
3584
  const packageManagerRunCmd = packageManager === "npm" ? "npm run" : packageManager;
3584
3585
  let webPort = "3001";
3585
3586
  if (hasReactRouter || hasSvelte) webPort = "5173";
3587
+ const stackDescription = generateStackDescription(frontend, backend, api, isConvex);
3586
3588
  return `# ${projectName}
3587
3589
 
3588
- This project was created with [Better-T-Stack](https://github.com/AmanVarshney01/create-better-t-stack), a modern TypeScript stack that combines ${hasTanstackRouter ? "React, TanStack Router" : hasReactRouter ? "React, React Router" : hasNext ? "Next.js" : hasTanstackStart ? "React, TanStack Start" : hasSvelte ? "SvelteKit" : hasNuxt ? "Nuxt" : hasSolid ? "SolidJS" : ""}, ${backend[0].toUpperCase() + backend.slice(1)}${isConvex ? "" : `, ${api.toUpperCase()}`}, and more.
3590
+ This project was created with [Better-T-Stack](https://github.com/AmanVarshney01/create-better-t-stack), a modern TypeScript stack${stackDescription ? ` that combines ${stackDescription}` : ""}.
3589
3591
 
3590
3592
  ## Features
3591
3593
 
@@ -3615,18 +3617,14 @@ Then, run the development server:
3615
3617
  ${packageManagerRunCmd} dev
3616
3618
  \`\`\`
3617
3619
 
3618
- ${hasTanstackRouter || hasReactRouter || hasNext || hasTanstackStart || hasSvelte || hasNuxt || hasSolid ? `Open [http://localhost:${webPort}](http://localhost:${webPort}) in your browser to see the web application.` : ""}
3619
- ${hasNative ? "Use the Expo Go app to run the mobile application.\n" : ""}
3620
- ${isConvex ? "Your app will connect to the Convex cloud backend automatically." : "The API is running at [http://localhost:3000](http://localhost:3000)."}
3620
+ ${generateRunningInstructions(frontend, backend, webPort, hasNative, isConvex)}
3621
3621
 
3622
3622
  ${addons.includes("pwa") && hasReactRouter ? "\n## PWA Support with React Router v7\n\nThere is a known compatibility issue between VitePWA and React Router v7.\nSee: https://github.com/vite-pwa/vite-plugin-pwa/issues/809\n" : ""}
3623
3623
 
3624
3624
  ## Project Structure
3625
3625
 
3626
3626
  \`\`\`
3627
- ${projectName}/
3628
- ├── apps/
3629
- ${hasTanstackRouter || hasReactRouter || hasNext || hasTanstackStart || hasSvelte || hasNuxt || hasSolid ? `│ ├── web/ # Frontend application (${hasTanstackRouter ? "React + TanStack Router" : hasReactRouter ? "React + React Router" : hasNext ? "Next.js" : hasTanstackStart ? "React + TanStack Start" : hasSvelte ? "SvelteKit" : hasNuxt ? "Nuxt" : hasSolid ? "SolidJS" : ""})\n` : ""}${hasNative ? "│ ├── native/ # Mobile application (React Native, Expo)\n" : ""}${addons.includes("starlight") ? "│ ├── docs/ # Documentation site (Astro Starlight)\n" : ""}${isConvex ? "├── packages/\n│ └── backend/ # Convex backend functions and schema\n" : `│ └── server/ # Backend API (${backend[0].toUpperCase() + backend.slice(1)}, ${api.toUpperCase()})`}
3627
+ ${generateProjectStructure(projectName, frontend, backend, addons, isConvex, api)}
3630
3628
  \`\`\`
3631
3629
 
3632
3630
  ## Available Scripts
@@ -3634,8 +3632,89 @@ ${hasTanstackRouter || hasReactRouter || hasNext || hasTanstackStart || hasSvelt
3634
3632
  ${generateScriptsList(packageManagerRunCmd, database, orm, auth, hasNative, addons, backend)}
3635
3633
  `;
3636
3634
  }
3635
+ function generateStackDescription(frontend, backend, api, isConvex) {
3636
+ const parts = [];
3637
+ const hasTanstackRouter = frontend.includes("tanstack-router");
3638
+ const hasReactRouter = frontend.includes("react-router");
3639
+ const hasNext = frontend.includes("next");
3640
+ const hasTanstackStart = frontend.includes("tanstack-start");
3641
+ const hasSvelte = frontend.includes("svelte");
3642
+ const hasNuxt = frontend.includes("nuxt");
3643
+ const hasSolid = frontend.includes("solid");
3644
+ const hasFrontendNone = frontend.length === 0 || frontend.includes("none");
3645
+ if (!hasFrontendNone) {
3646
+ if (hasTanstackRouter) parts.push("React, TanStack Router");
3647
+ else if (hasReactRouter) parts.push("React, React Router");
3648
+ else if (hasNext) parts.push("Next.js");
3649
+ else if (hasTanstackStart) parts.push("React, TanStack Start");
3650
+ else if (hasSvelte) parts.push("SvelteKit");
3651
+ else if (hasNuxt) parts.push("Nuxt");
3652
+ else if (hasSolid) parts.push("SolidJS");
3653
+ }
3654
+ if (backend !== "none") parts.push(backend[0].toUpperCase() + backend.slice(1));
3655
+ if (!isConvex && api !== "none") parts.push(api.toUpperCase());
3656
+ return parts.length > 0 ? `${parts.join(", ")}, and more` : "";
3657
+ }
3658
+ function generateRunningInstructions(frontend, backend, webPort, hasNative, isConvex) {
3659
+ const instructions = [];
3660
+ const hasFrontendNone = frontend.length === 0 || frontend.includes("none");
3661
+ const isBackendNone = backend === "none";
3662
+ if (!hasFrontendNone) {
3663
+ const hasTanstackRouter = frontend.includes("tanstack-router");
3664
+ const hasReactRouter = frontend.includes("react-router");
3665
+ const hasNext = frontend.includes("next");
3666
+ const hasTanstackStart = frontend.includes("tanstack-start");
3667
+ const hasSvelte = frontend.includes("svelte");
3668
+ const hasNuxt = frontend.includes("nuxt");
3669
+ const hasSolid = frontend.includes("solid");
3670
+ if (hasTanstackRouter || hasReactRouter || hasNext || hasTanstackStart || hasSvelte || hasNuxt || hasSolid) instructions.push(`Open [http://localhost:${webPort}](http://localhost:${webPort}) in your browser to see the web application.`);
3671
+ }
3672
+ if (hasNative) instructions.push("Use the Expo Go app to run the mobile application.");
3673
+ if (isConvex) instructions.push("Your app will connect to the Convex cloud backend automatically.");
3674
+ else if (!isBackendNone) instructions.push("The API is running at [http://localhost:3000](http://localhost:3000).");
3675
+ return instructions.join("\n");
3676
+ }
3677
+ function generateProjectStructure(projectName, frontend, backend, addons, isConvex, api) {
3678
+ const structure = [`${projectName}/`, "├── apps/"];
3679
+ const hasFrontendNone = frontend.length === 0 || frontend.includes("none");
3680
+ const isBackendNone = backend === "none";
3681
+ if (!hasFrontendNone) {
3682
+ const hasTanstackRouter = frontend.includes("tanstack-router");
3683
+ const hasReactRouter = frontend.includes("react-router");
3684
+ const hasNext = frontend.includes("next");
3685
+ const hasTanstackStart = frontend.includes("tanstack-start");
3686
+ const hasSvelte = frontend.includes("svelte");
3687
+ const hasNuxt = frontend.includes("nuxt");
3688
+ const hasSolid = frontend.includes("solid");
3689
+ if (hasTanstackRouter || hasReactRouter || hasNext || hasTanstackStart || hasSvelte || hasNuxt || hasSolid) {
3690
+ let frontendType = "";
3691
+ if (hasTanstackRouter) frontendType = "React + TanStack Router";
3692
+ else if (hasReactRouter) frontendType = "React + React Router";
3693
+ else if (hasNext) frontendType = "Next.js";
3694
+ else if (hasTanstackStart) frontendType = "React + TanStack Start";
3695
+ else if (hasSvelte) frontendType = "SvelteKit";
3696
+ else if (hasNuxt) frontendType = "Nuxt";
3697
+ else if (hasSolid) frontendType = "SolidJS";
3698
+ structure.push(`│ ├── web/ # Frontend application (${frontendType})`);
3699
+ }
3700
+ }
3701
+ const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
3702
+ if (hasNative) structure.push("│ ├── native/ # Mobile application (React Native, Expo)");
3703
+ if (addons.includes("starlight")) structure.push("│ ├── docs/ # Documentation site (Astro Starlight)");
3704
+ if (isConvex) {
3705
+ structure.push("├── packages/");
3706
+ structure.push("│ └── backend/ # Convex backend functions and schema");
3707
+ } else if (!isBackendNone) {
3708
+ const backendName = backend[0].toUpperCase() + backend.slice(1);
3709
+ const apiName = api !== "none" ? api.toUpperCase() : "";
3710
+ const backendDesc = apiName ? `${backendName}, ${apiName}` : backendName;
3711
+ structure.push(`│ └── server/ # Backend API (${backendDesc})`);
3712
+ }
3713
+ return structure.join("\n");
3714
+ }
3637
3715
  function generateFeaturesList(database, auth, addons, orm, runtime, frontend, backend, api) {
3638
3716
  const isConvex = backend === "convex";
3717
+ const isBackendNone = backend === "none";
3639
3718
  const hasTanstackRouter = frontend.includes("tanstack-router");
3640
3719
  const hasReactRouter = frontend.includes("react-router");
3641
3720
  const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
@@ -3644,21 +3723,24 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
3644
3723
  const hasSvelte = frontend.includes("svelte");
3645
3724
  const hasNuxt = frontend.includes("nuxt");
3646
3725
  const hasSolid = frontend.includes("solid");
3726
+ const hasFrontendNone = frontend.length === 0 || frontend.includes("none");
3647
3727
  const addonsList = ["- **TypeScript** - For type safety and improved developer experience"];
3648
- if (hasTanstackRouter) addonsList.push("- **TanStack Router** - File-based routing with full type safety");
3649
- else if (hasReactRouter) addonsList.push("- **React Router** - Declarative routing for React");
3650
- else if (hasNext) addonsList.push("- **Next.js** - Full-stack React framework");
3651
- else if (hasTanstackStart) addonsList.push("- **TanStack Start** - SSR framework with TanStack Router");
3652
- else if (hasSvelte) addonsList.push("- **SvelteKit** - Web framework for building Svelte apps");
3653
- else if (hasNuxt) addonsList.push("- **Nuxt** - The Intuitive Vue Framework");
3654
- else if (hasSolid) addonsList.push("- **SolidJS** - Simple and performant reactivity");
3728
+ if (!hasFrontendNone) {
3729
+ if (hasTanstackRouter) addonsList.push("- **TanStack Router** - File-based routing with full type safety");
3730
+ else if (hasReactRouter) addonsList.push("- **React Router** - Declarative routing for React");
3731
+ else if (hasNext) addonsList.push("- **Next.js** - Full-stack React framework");
3732
+ else if (hasTanstackStart) addonsList.push("- **TanStack Start** - SSR framework with TanStack Router");
3733
+ else if (hasSvelte) addonsList.push("- **SvelteKit** - Web framework for building Svelte apps");
3734
+ else if (hasNuxt) addonsList.push("- **Nuxt** - The Intuitive Vue Framework");
3735
+ else if (hasSolid) addonsList.push("- **SolidJS** - Simple and performant reactivity");
3736
+ }
3655
3737
  if (hasNative) {
3656
3738
  addonsList.push("- **React Native** - Build mobile apps using React");
3657
3739
  addonsList.push("- **Expo** - Tools for React Native development");
3658
3740
  }
3659
- addonsList.push("- **TailwindCSS** - Utility-first CSS for rapid UI development", "- **shadcn/ui** - Reusable UI components");
3741
+ if (!hasFrontendNone) addonsList.push("- **TailwindCSS** - Utility-first CSS for rapid UI development", "- **shadcn/ui** - Reusable UI components");
3660
3742
  if (isConvex) addonsList.push("- **Convex** - Reactive backend-as-a-service platform");
3661
- else {
3743
+ else if (!isBackendNone) {
3662
3744
  if (backend === "hono") addonsList.push("- **Hono** - Lightweight, performant server framework");
3663
3745
  else if (backend === "express") addonsList.push("- **Express** - Fast, unopinionated web framework");
3664
3746
  else if (backend === "fastify") addonsList.push("- **Fastify** - Fast, low-overhead web framework");
@@ -3666,9 +3748,13 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
3666
3748
  else if (backend === "next") addonsList.push("- **Next.js** - Full-stack React framework");
3667
3749
  if (api === "trpc") addonsList.push("- **tRPC** - End-to-end type-safe APIs");
3668
3750
  else if (api === "orpc") addonsList.push("- **oRPC** - End-to-end type-safe APIs with OpenAPI integration");
3669
- addonsList.push(`- **${runtime === "bun" ? "Bun" : "Node.js"}** - Runtime environment`);
3751
+ if (runtime !== "none") addonsList.push(`- **${runtime === "bun" ? "Bun" : runtime === "node" ? "Node.js" : runtime}** - Runtime environment`);
3752
+ }
3753
+ if (database !== "none" && !isConvex) {
3754
+ const ormName = orm === "drizzle" ? "Drizzle" : orm === "prisma" ? "Prisma" : orm === "mongoose" ? "Mongoose" : "ORM";
3755
+ const dbName = database === "sqlite" ? "SQLite/Turso" : database === "postgres" ? "PostgreSQL" : database === "mysql" ? "MySQL" : database === "mongodb" ? "MongoDB" : "Database";
3756
+ addonsList.push(`- **${ormName}** - TypeScript-first ORM`, `- **${dbName}** - Database engine`);
3670
3757
  }
3671
- if (database !== "none" && !isConvex) addonsList.push(`- **${orm === "drizzle" ? "Drizzle" : orm === "prisma" ? "Prisma" : "Mongoose"}** - TypeScript-first ORM`, `- **${database === "sqlite" ? "SQLite/Turso" : database === "postgres" ? "PostgreSQL" : database === "mysql" ? "MySQL" : "MongoDB"}** - Database engine`);
3672
3758
  if (auth && !isConvex) addonsList.push("- **Authentication** - Email & password authentication with Better Auth");
3673
3759
  for (const addon of addons) if (addon === "pwa") addonsList.push("- **PWA** - Progressive Web App support");
3674
3760
  else if (addon === "tauri") addonsList.push("- **Tauri** - Build native desktop applications");
@@ -3678,10 +3764,10 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
3678
3764
  else if (addon === "turborepo") addonsList.push("- **Turborepo** - Optimized monorepo build system");
3679
3765
  return addonsList.join("\n");
3680
3766
  }
3681
- function generateDatabaseSetup(database, auth, packageManagerRunCmd, orm) {
3767
+ function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm) {
3682
3768
  if (database === "none") return "";
3683
3769
  let setup = "## Database Setup\n\n";
3684
- if (database === "sqlite") setup += `This project uses SQLite${orm === "drizzle" ? " with Drizzle ORM" : " with Prisma"}.
3770
+ if (database === "sqlite") setup += `This project uses SQLite${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
3685
3771
 
3686
3772
  1. Start the local SQLite database:
3687
3773
  \`\`\`bash
@@ -3690,23 +3776,23 @@ cd apps/server && ${packageManagerRunCmd} db:local
3690
3776
 
3691
3777
  2. Update your \`.env\` file in the \`apps/server\` directory with the appropriate connection details if needed.
3692
3778
  `;
3693
- else if (database === "postgres") setup += `This project uses PostgreSQL${orm === "drizzle" ? " with Drizzle ORM" : " with Prisma"}.
3779
+ else if (database === "postgres") setup += `This project uses PostgreSQL${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
3694
3780
 
3695
3781
  1. Make sure you have a PostgreSQL database set up.
3696
3782
  2. Update your \`apps/server/.env\` file with your PostgreSQL connection details.
3697
3783
  `;
3698
- else if (database === "mysql") setup += `This project uses MySQL${orm === "drizzle" ? " with Drizzle ORM" : " with Prisma"}.
3784
+ else if (database === "mysql") setup += `This project uses MySQL${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
3699
3785
 
3700
3786
  1. Make sure you have a MySQL database set up.
3701
3787
  2. Update your \`apps/server/.env\` file with your MySQL connection details.
3702
3788
  `;
3703
- else if (database === "mongodb") setup += `This project uses MongoDB ${orm === "mongoose" ? "with Mongoose" : "with Prisma ORM"}.
3789
+ else if (database === "mongodb") setup += `This project uses MongoDB ${orm === "mongoose" ? "with Mongoose" : orm === "prisma" ? "with Prisma ORM" : `with ${orm}`}.
3704
3790
 
3705
3791
  1. Make sure you have MongoDB set up.
3706
3792
  2. Update your \`apps/server/.env\` file with your MongoDB connection URI.
3707
3793
  `;
3708
3794
  setup += `
3709
- ${auth ? "3" : "3"}. ${orm === "prisma" ? `Generate the Prisma client and push the schema:
3795
+ 3. ${orm === "prisma" ? `Generate the Prisma client and push the schema:
3710
3796
  \`\`\`bash
3711
3797
  ${packageManagerRunCmd} db:push
3712
3798
  \`\`\`` : orm === "drizzle" ? `Apply the schema to your database:
@@ -3721,12 +3807,14 @@ ${packageManagerRunCmd} db:push
3721
3807
  }
3722
3808
  function generateScriptsList(packageManagerRunCmd, database, orm, _auth, hasNative, addons, backend) {
3723
3809
  const isConvex = backend === "convex";
3810
+ const isBackendNone = backend === "none";
3724
3811
  let scripts = `- \`${packageManagerRunCmd} dev\`: Start all applications in development mode
3725
- - \`${packageManagerRunCmd} build\`: Build all applications
3812
+ - \`${packageManagerRunCmd} build\`: Build all applications`;
3813
+ scripts += `
3726
3814
  - \`${packageManagerRunCmd} dev:web\`: Start only the web application`;
3727
3815
  if (isConvex) scripts += `
3728
3816
  - \`${packageManagerRunCmd} dev:setup\`: Setup and configure your Convex project`;
3729
- else scripts += `
3817
+ else if (!isBackendNone) scripts += `
3730
3818
  - \`${packageManagerRunCmd} dev:server\`: Start only the server`;
3731
3819
  scripts += `
3732
3820
  - \`${packageManagerRunCmd} check-types\`: Check TypeScript types across all apps`;
@@ -3787,6 +3875,7 @@ function displayPostInstallInstructions(config) {
3787
3875
  if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} ${packageManager} install\n`;
3788
3876
  if (isConvex) {
3789
3877
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:setup ${pc.dim("(this will guide you through Convex project setup)")}\n`;
3878
+ output += `${pc.cyan(`${stepCounter++}.`)} Copy environment variables from ${pc.white("packages/backend/.env.local")} \nto ${pc.white("apps/*/.env")}\n`;
3790
3879
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n\n`;
3791
3880
  } else {
3792
3881
  if (runtime !== "workers") output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
@@ -3898,7 +3987,7 @@ async function updateRootPackageJson(projectDir, options) {
3898
3987
  scripts["dev:native"] = "turbo -F native dev";
3899
3988
  scripts["dev:web"] = "turbo -F web dev";
3900
3989
  scripts["dev:server"] = serverDevScript;
3901
- if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} setup`;
3990
+ if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} dev:setup`;
3902
3991
  if (needsDbScripts) {
3903
3992
  scripts["db:push"] = `turbo -F ${backendPackageName} db:push`;
3904
3993
  scripts["db:studio"] = `turbo -F ${backendPackageName} db:studio`;
@@ -3917,7 +4006,7 @@ async function updateRootPackageJson(projectDir, options) {
3917
4006
  scripts["dev:native"] = "pnpm --filter native dev";
3918
4007
  scripts["dev:web"] = "pnpm --filter web dev";
3919
4008
  scripts["dev:server"] = serverDevScript;
3920
- if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} setup`;
4009
+ if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} dev:setup`;
3921
4010
  if (needsDbScripts) {
3922
4011
  scripts["db:push"] = `pnpm --filter ${backendPackageName} db:push`;
3923
4012
  scripts["db:studio"] = `pnpm --filter ${backendPackageName} db:studio`;
@@ -3936,7 +4025,7 @@ async function updateRootPackageJson(projectDir, options) {
3936
4025
  scripts["dev:native"] = "npm run dev --workspace native";
3937
4026
  scripts["dev:web"] = "npm run dev --workspace web";
3938
4027
  scripts["dev:server"] = serverDevScript;
3939
- if (options.backend === "convex") scripts["dev:setup"] = `npm run setup --workspace ${backendPackageName}`;
4028
+ if (options.backend === "convex") scripts["dev:setup"] = `npm run dev:setup --workspace ${backendPackageName}`;
3940
4029
  if (needsDbScripts) {
3941
4030
  scripts["db:push"] = `npm run db:push --workspace ${backendPackageName}`;
3942
4031
  scripts["db:studio"] = `npm run db:studio --workspace ${backendPackageName}`;
@@ -3955,7 +4044,7 @@ async function updateRootPackageJson(projectDir, options) {
3955
4044
  scripts["dev:native"] = "bun run --filter native dev";
3956
4045
  scripts["dev:web"] = "bun run --filter web dev";
3957
4046
  scripts["dev:server"] = serverDevScript;
3958
- if (options.backend === "convex") scripts["dev:setup"] = `bun run --filter ${backendPackageName} setup`;
4047
+ if (options.backend === "convex") scripts["dev:setup"] = `bun run --filter ${backendPackageName} dev:setup`;
3959
4048
  if (needsDbScripts) {
3960
4049
  scripts["db:push"] = `bun run --filter ${backendPackageName} db:push`;
3961
4050
  scripts["db:studio"] = `bun run --filter ${backendPackageName} db:studio`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "2.22.4",
3
+ "version": "2.22.6",
4
4
  "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -17,7 +17,7 @@
17
17
  "cache": false,
18
18
  "persistent": true
19
19
  }{{#if (eq backend "convex")}},
20
- "setup": {
20
+ "dev:setup": {
21
21
  "cache": false,
22
22
  "persistent": true
23
23
  }
@@ -3,7 +3,7 @@
3
3
  "version": "1.0.0",
4
4
  "scripts": {
5
5
  "dev": "convex dev",
6
- "setup": "convex dev --configure --until-success"
6
+ "dev:setup": "convex dev --configure --until-success"
7
7
  },
8
8
  "author": "",
9
9
  "license": "ISC",
@@ -12,6 +12,6 @@
12
12
  "typescript": "^5.8.3"
13
13
  },
14
14
  "dependencies": {
15
- "convex": "^1.23.0"
15
+ "convex": "^1.25.0"
16
16
  }
17
17
  }
@@ -1,12 +1,29 @@
1
1
  {{#if (or (eq runtime "bun") (eq runtime "node"))}}
2
+ {{#if (eq dbSetup "neon")}}
3
+ import { neon } from '@neondatabase/serverless';
4
+ import { drizzle } from 'drizzle-orm/neon-http';
5
+
6
+ const sql = neon(process.env.DATABASE_URL || "");
7
+ export const db = drizzle(sql);
8
+ {{else}}
2
9
  import { drizzle } from "drizzle-orm/node-postgres";
3
10
 
4
11
  export const db = drizzle(process.env.DATABASE_URL || "");
5
12
  {{/if}}
13
+ {{/if}}
6
14
 
7
15
  {{#if (eq runtime "workers")}}
16
+ {{#if (eq dbSetup "neon")}}
17
+ import { neon } from '@neondatabase/serverless';
18
+ import { drizzle } from 'drizzle-orm/neon-http';
19
+ import { env } from "cloudflare:workers";
20
+
21
+ const sql = neon(env.DATABASE_URL || "");
22
+ export const db = drizzle(sql);
23
+ {{else}}
8
24
  import { drizzle } from "drizzle-orm/node-postgres";
9
25
  import { env } from "cloudflare:workers";
10
26
 
11
27
  export const db = drizzle(env.DATABASE_URL || "");
12
28
  {{/if}}
29
+ {{/if}}