create-better-t-stack 2.22.5 → 2.22.7
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 +49 -5
- package/dist/index.js +119 -36
- package/package.json +1 -1
- package/templates/addons/turborepo/turbo.json.hbs +1 -1
- package/templates/backend/convex/packages/backend/package.json.hbs +2 -2
- package/templates/frontend/native/unistyles/babel.config.js +1 -0
- package/templates/frontend/native/unistyles/package.json.hbs +1 -1
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
|
@@ -94,7 +94,7 @@ const dependencyVersionMap = {
|
|
|
94
94
|
"@trpc/tanstack-react-query": "^11.4.2",
|
|
95
95
|
"@trpc/server": "^11.4.2",
|
|
96
96
|
"@trpc/client": "^11.4.2",
|
|
97
|
-
convex: "^1.
|
|
97
|
+
convex: "^1.25.0",
|
|
98
98
|
"@convex-dev/react-query": "^0.0.0-alpha.8",
|
|
99
99
|
"convex-svelte": "^0.0.11",
|
|
100
100
|
"@tanstack/svelte-query": "^5.74.4",
|
|
@@ -3579,19 +3579,15 @@ function generateReadmeContent(options) {
|
|
|
3579
3579
|
const { projectName, packageManager, database, auth, addons = [], orm = "drizzle", runtime = "bun", frontend = ["tanstack-router"], backend = "hono", api = "trpc" } = options;
|
|
3580
3580
|
const isConvex = backend === "convex";
|
|
3581
3581
|
const hasReactRouter = frontend.includes("react-router");
|
|
3582
|
-
const hasTanstackRouter = frontend.includes("tanstack-router");
|
|
3583
3582
|
const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
|
|
3584
|
-
const hasNext = frontend.includes("next");
|
|
3585
|
-
const hasTanstackStart = frontend.includes("tanstack-start");
|
|
3586
3583
|
const hasSvelte = frontend.includes("svelte");
|
|
3587
|
-
const hasSolid = frontend.includes("solid");
|
|
3588
|
-
const hasNuxt = frontend.includes("nuxt");
|
|
3589
3584
|
const packageManagerRunCmd = packageManager === "npm" ? "npm run" : packageManager;
|
|
3590
3585
|
let webPort = "3001";
|
|
3591
3586
|
if (hasReactRouter || hasSvelte) webPort = "5173";
|
|
3587
|
+
const stackDescription = generateStackDescription(frontend, backend, api, isConvex);
|
|
3592
3588
|
return `# ${projectName}
|
|
3593
3589
|
|
|
3594
|
-
This project was created with [Better-T-Stack](https://github.com/AmanVarshney01/create-better-t-stack), a modern TypeScript stack
|
|
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}` : ""}.
|
|
3595
3591
|
|
|
3596
3592
|
## Features
|
|
3597
3593
|
|
|
@@ -3621,18 +3617,14 @@ Then, run the development server:
|
|
|
3621
3617
|
${packageManagerRunCmd} dev
|
|
3622
3618
|
\`\`\`
|
|
3623
3619
|
|
|
3624
|
-
${
|
|
3625
|
-
${hasNative ? "Use the Expo Go app to run the mobile application.\n" : ""}
|
|
3626
|
-
${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)}
|
|
3627
3621
|
|
|
3628
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" : ""}
|
|
3629
3623
|
|
|
3630
3624
|
## Project Structure
|
|
3631
3625
|
|
|
3632
3626
|
\`\`\`
|
|
3633
|
-
${projectName}
|
|
3634
|
-
├── apps/
|
|
3635
|
-
${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)}
|
|
3636
3628
|
\`\`\`
|
|
3637
3629
|
|
|
3638
3630
|
## Available Scripts
|
|
@@ -3640,8 +3632,89 @@ ${hasTanstackRouter || hasReactRouter || hasNext || hasTanstackStart || hasSvelt
|
|
|
3640
3632
|
${generateScriptsList(packageManagerRunCmd, database, orm, auth, hasNative, addons, backend)}
|
|
3641
3633
|
`;
|
|
3642
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
|
+
}
|
|
3643
3715
|
function generateFeaturesList(database, auth, addons, orm, runtime, frontend, backend, api) {
|
|
3644
3716
|
const isConvex = backend === "convex";
|
|
3717
|
+
const isBackendNone = backend === "none";
|
|
3645
3718
|
const hasTanstackRouter = frontend.includes("tanstack-router");
|
|
3646
3719
|
const hasReactRouter = frontend.includes("react-router");
|
|
3647
3720
|
const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
|
|
@@ -3650,21 +3723,24 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
|
|
|
3650
3723
|
const hasSvelte = frontend.includes("svelte");
|
|
3651
3724
|
const hasNuxt = frontend.includes("nuxt");
|
|
3652
3725
|
const hasSolid = frontend.includes("solid");
|
|
3726
|
+
const hasFrontendNone = frontend.length === 0 || frontend.includes("none");
|
|
3653
3727
|
const addonsList = ["- **TypeScript** - For type safety and improved developer experience"];
|
|
3654
|
-
if (
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
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
|
+
}
|
|
3661
3737
|
if (hasNative) {
|
|
3662
3738
|
addonsList.push("- **React Native** - Build mobile apps using React");
|
|
3663
3739
|
addonsList.push("- **Expo** - Tools for React Native development");
|
|
3664
3740
|
}
|
|
3665
|
-
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");
|
|
3666
3742
|
if (isConvex) addonsList.push("- **Convex** - Reactive backend-as-a-service platform");
|
|
3667
|
-
else {
|
|
3743
|
+
else if (!isBackendNone) {
|
|
3668
3744
|
if (backend === "hono") addonsList.push("- **Hono** - Lightweight, performant server framework");
|
|
3669
3745
|
else if (backend === "express") addonsList.push("- **Express** - Fast, unopinionated web framework");
|
|
3670
3746
|
else if (backend === "fastify") addonsList.push("- **Fastify** - Fast, low-overhead web framework");
|
|
@@ -3672,9 +3748,13 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
|
|
|
3672
3748
|
else if (backend === "next") addonsList.push("- **Next.js** - Full-stack React framework");
|
|
3673
3749
|
if (api === "trpc") addonsList.push("- **tRPC** - End-to-end type-safe APIs");
|
|
3674
3750
|
else if (api === "orpc") addonsList.push("- **oRPC** - End-to-end type-safe APIs with OpenAPI integration");
|
|
3675
|
-
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`);
|
|
3676
3757
|
}
|
|
3677
|
-
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`);
|
|
3678
3758
|
if (auth && !isConvex) addonsList.push("- **Authentication** - Email & password authentication with Better Auth");
|
|
3679
3759
|
for (const addon of addons) if (addon === "pwa") addonsList.push("- **PWA** - Progressive Web App support");
|
|
3680
3760
|
else if (addon === "tauri") addonsList.push("- **Tauri** - Build native desktop applications");
|
|
@@ -3684,10 +3764,10 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
|
|
|
3684
3764
|
else if (addon === "turborepo") addonsList.push("- **Turborepo** - Optimized monorepo build system");
|
|
3685
3765
|
return addonsList.join("\n");
|
|
3686
3766
|
}
|
|
3687
|
-
function generateDatabaseSetup(database,
|
|
3767
|
+
function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm) {
|
|
3688
3768
|
if (database === "none") return "";
|
|
3689
3769
|
let setup = "## Database Setup\n\n";
|
|
3690
|
-
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}`}.
|
|
3691
3771
|
|
|
3692
3772
|
1. Start the local SQLite database:
|
|
3693
3773
|
\`\`\`bash
|
|
@@ -3696,23 +3776,23 @@ cd apps/server && ${packageManagerRunCmd} db:local
|
|
|
3696
3776
|
|
|
3697
3777
|
2. Update your \`.env\` file in the \`apps/server\` directory with the appropriate connection details if needed.
|
|
3698
3778
|
`;
|
|
3699
|
-
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}`}.
|
|
3700
3780
|
|
|
3701
3781
|
1. Make sure you have a PostgreSQL database set up.
|
|
3702
3782
|
2. Update your \`apps/server/.env\` file with your PostgreSQL connection details.
|
|
3703
3783
|
`;
|
|
3704
|
-
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}`}.
|
|
3705
3785
|
|
|
3706
3786
|
1. Make sure you have a MySQL database set up.
|
|
3707
3787
|
2. Update your \`apps/server/.env\` file with your MySQL connection details.
|
|
3708
3788
|
`;
|
|
3709
|
-
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}`}.
|
|
3710
3790
|
|
|
3711
3791
|
1. Make sure you have MongoDB set up.
|
|
3712
3792
|
2. Update your \`apps/server/.env\` file with your MongoDB connection URI.
|
|
3713
3793
|
`;
|
|
3714
3794
|
setup += `
|
|
3715
|
-
|
|
3795
|
+
3. ${orm === "prisma" ? `Generate the Prisma client and push the schema:
|
|
3716
3796
|
\`\`\`bash
|
|
3717
3797
|
${packageManagerRunCmd} db:push
|
|
3718
3798
|
\`\`\`` : orm === "drizzle" ? `Apply the schema to your database:
|
|
@@ -3727,12 +3807,14 @@ ${packageManagerRunCmd} db:push
|
|
|
3727
3807
|
}
|
|
3728
3808
|
function generateScriptsList(packageManagerRunCmd, database, orm, _auth, hasNative, addons, backend) {
|
|
3729
3809
|
const isConvex = backend === "convex";
|
|
3810
|
+
const isBackendNone = backend === "none";
|
|
3730
3811
|
let scripts = `- \`${packageManagerRunCmd} dev\`: Start all applications in development mode
|
|
3731
|
-
- \`${packageManagerRunCmd} build\`: Build all applications
|
|
3812
|
+
- \`${packageManagerRunCmd} build\`: Build all applications`;
|
|
3813
|
+
scripts += `
|
|
3732
3814
|
- \`${packageManagerRunCmd} dev:web\`: Start only the web application`;
|
|
3733
3815
|
if (isConvex) scripts += `
|
|
3734
3816
|
- \`${packageManagerRunCmd} dev:setup\`: Setup and configure your Convex project`;
|
|
3735
|
-
else scripts += `
|
|
3817
|
+
else if (!isBackendNone) scripts += `
|
|
3736
3818
|
- \`${packageManagerRunCmd} dev:server\`: Start only the server`;
|
|
3737
3819
|
scripts += `
|
|
3738
3820
|
- \`${packageManagerRunCmd} check-types\`: Check TypeScript types across all apps`;
|
|
@@ -3793,6 +3875,7 @@ function displayPostInstallInstructions(config) {
|
|
|
3793
3875
|
if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} ${packageManager} install\n`;
|
|
3794
3876
|
if (isConvex) {
|
|
3795
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`;
|
|
3796
3879
|
output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n\n`;
|
|
3797
3880
|
} else {
|
|
3798
3881
|
if (runtime !== "workers") output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
|
|
@@ -3904,7 +3987,7 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
3904
3987
|
scripts["dev:native"] = "turbo -F native dev";
|
|
3905
3988
|
scripts["dev:web"] = "turbo -F web dev";
|
|
3906
3989
|
scripts["dev:server"] = serverDevScript;
|
|
3907
|
-
if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} setup`;
|
|
3990
|
+
if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} dev:setup`;
|
|
3908
3991
|
if (needsDbScripts) {
|
|
3909
3992
|
scripts["db:push"] = `turbo -F ${backendPackageName} db:push`;
|
|
3910
3993
|
scripts["db:studio"] = `turbo -F ${backendPackageName} db:studio`;
|
|
@@ -3923,7 +4006,7 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
3923
4006
|
scripts["dev:native"] = "pnpm --filter native dev";
|
|
3924
4007
|
scripts["dev:web"] = "pnpm --filter web dev";
|
|
3925
4008
|
scripts["dev:server"] = serverDevScript;
|
|
3926
|
-
if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} setup`;
|
|
4009
|
+
if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} dev:setup`;
|
|
3927
4010
|
if (needsDbScripts) {
|
|
3928
4011
|
scripts["db:push"] = `pnpm --filter ${backendPackageName} db:push`;
|
|
3929
4012
|
scripts["db:studio"] = `pnpm --filter ${backendPackageName} db:studio`;
|
|
@@ -3942,7 +4025,7 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
3942
4025
|
scripts["dev:native"] = "npm run dev --workspace native";
|
|
3943
4026
|
scripts["dev:web"] = "npm run dev --workspace web";
|
|
3944
4027
|
scripts["dev:server"] = serverDevScript;
|
|
3945
|
-
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}`;
|
|
3946
4029
|
if (needsDbScripts) {
|
|
3947
4030
|
scripts["db:push"] = `npm run db:push --workspace ${backendPackageName}`;
|
|
3948
4031
|
scripts["db:studio"] = `npm run db:studio --workspace ${backendPackageName}`;
|
|
@@ -3961,7 +4044,7 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
3961
4044
|
scripts["dev:native"] = "bun run --filter native dev";
|
|
3962
4045
|
scripts["dev:web"] = "bun run --filter web dev";
|
|
3963
4046
|
scripts["dev:server"] = serverDevScript;
|
|
3964
|
-
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`;
|
|
3965
4048
|
if (needsDbScripts) {
|
|
3966
4049
|
scripts["db:push"] = `bun run --filter ${backendPackageName} db:push`;
|
|
3967
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.
|
|
3
|
+
"version": "2.22.7",
|
|
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",
|
|
@@ -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.
|
|
15
|
+
"convex": "^1.25.0"
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"react-native-reanimated": "~3.17.4",
|
|
38
38
|
"react-native-safe-area-context": "5.4.0",
|
|
39
39
|
"react-native-screens": "~4.10.0",
|
|
40
|
-
"react-native-unistyles": "^3.0.0-rc.
|
|
40
|
+
"react-native-unistyles": "^3.0.0-rc.5",
|
|
41
41
|
"react-native-web": "^0.20.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|