create-better-t-stack 2.50.1-canary.58bbe5f6 → 2.50.1-canary.7ebd503f

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/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createBtsCli } from "./src-CulfT5QB.js";
2
+ import { createBtsCli } from "./src-DG05Vcnx.js";
3
3
 
4
4
  //#region src/cli.ts
5
5
  createBtsCli().run();
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { builder, createBtsCli, docs, init, router, sponsors } from "./src-CulfT5QB.js";
2
+ import { builder, createBtsCli, docs, init, router, sponsors } from "./src-DG05Vcnx.js";
3
3
 
4
4
  export { builder, createBtsCli, docs, init, router, sponsors };
@@ -347,16 +347,21 @@ function ensureSingleWebAndNative(frontends) {
347
347
  if (web.length > 1) exitWithError("Cannot select multiple web frameworks. Choose only one of: tanstack-router, tanstack-start, react-router, next, nuxt, svelte, solid");
348
348
  if (native.length > 1) exitWithError("Cannot select multiple native frameworks. Choose only one of: native-nativewind, native-unistyles");
349
349
  }
350
- const FULLSTACK_FRONTENDS$1 = ["next"];
350
+ const FULLSTACK_FRONTENDS$1 = [
351
+ "next",
352
+ "nuxt",
353
+ "svelte",
354
+ "tanstack-start"
355
+ ];
351
356
  function validateSelfBackendCompatibility(providedFlags, options, config) {
352
357
  const backend = config.backend || options.backend;
353
358
  const frontends = config.frontend || options.frontend || [];
354
359
  if (backend === "self") {
355
- if (!frontends.some((f) => FULLSTACK_FRONTENDS$1.includes(f))) exitWithError("Backend 'self' (fullstack) currently only supports Next.js frontend. Please use --frontend next. Support for Nuxt, SvelteKit, and TanStack Start will be added in a future update.");
360
+ if (!frontends.some((f) => FULLSTACK_FRONTENDS$1.includes(f))) exitWithError("Backend 'self' (fullstack) requires a fullstack-capable frontend. Please use --frontend with one of: next, nuxt, svelte, tanstack-start");
356
361
  if (frontends.length > 1) exitWithError("Backend 'self' (fullstack) can only be used with a single frontend framework.");
357
362
  }
358
363
  const hasFullstackFrontend = frontends.some((f) => FULLSTACK_FRONTENDS$1.includes(f));
359
- if (providedFlags.has("backend") && !hasFullstackFrontend && backend === "self") exitWithError("Backend 'self' (fullstack) currently only supports Next.js frontend. Please use --frontend next or choose a different backend. Support for Nuxt, SvelteKit, and TanStack Start will be added in a future update.");
364
+ if (providedFlags.has("backend") && !hasFullstackFrontend && backend === "self") exitWithError("Backend 'self' (fullstack) is only compatible with fullstack-capable frontends: next, nuxt, svelte, tanstack-start. Please choose a different backend or use a fullstack frontend.");
360
365
  }
361
366
  function validateWorkersCompatibility(providedFlags, options, config) {
362
367
  if (providedFlags.has("runtime") && options.runtime === "workers" && config.backend && config.backend !== "hono") exitWithError(`Cloudflare Workers runtime (--runtime workers) is only supported with Hono backend (--backend hono). Current backend: ${config.backend}. Please use '--backend hono' or choose a different runtime.`);
@@ -679,7 +684,12 @@ async function getAuthChoice(auth, hasDatabase, backend, frontend) {
679
684
 
680
685
  //#endregion
681
686
  //#region src/prompts/backend.ts
682
- const FULLSTACK_FRONTENDS = ["next"];
687
+ const FULLSTACK_FRONTENDS = [
688
+ "next",
689
+ "nuxt",
690
+ "svelte",
691
+ "tanstack-start"
692
+ ];
683
693
  async function getBackendFrameworkChoice(backendFramework, frontends) {
684
694
  if (backendFramework !== void 0) return backendFramework;
685
695
  const hasIncompatibleFrontend = frontends?.some((f) => f === "solid");
@@ -3145,29 +3155,25 @@ async function setupDockerComposeTemplates(projectDir, context) {
3145
3155
  if (await fs.pathExists(dockerSrcDir)) await processAndCopyFiles("**/*", dockerSrcDir, dbPackageDir, context);
3146
3156
  }
3147
3157
  async function setupDeploymentTemplates(projectDir, context) {
3148
- const isBackendSelf = context.backend === "self";
3149
- if (context.webDeploy === "alchemy" || context.serverDeploy === "alchemy") {
3158
+ if (context.webDeploy === "alchemy" || context.serverDeploy === "alchemy") if (context.webDeploy === "alchemy" && context.serverDeploy === "alchemy") {
3150
3159
  const alchemyTemplateSrc = path.join(PKG_ROOT, "templates/deploy/alchemy");
3151
- if (context.webDeploy === "alchemy" && (context.serverDeploy === "alchemy" || isBackendSelf)) {
3152
- if (await fs.pathExists(alchemyTemplateSrc)) {
3153
- await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, projectDir, context);
3154
- await addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc);
3155
- }
3156
- } else {
3157
- if (context.webDeploy === "alchemy") {
3158
- const webAppDir = path.join(projectDir, "apps/web");
3159
- if (await fs.pathExists(alchemyTemplateSrc) && await fs.pathExists(webAppDir)) {
3160
- await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, webAppDir, context);
3161
- await addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc);
3162
- }
3163
- }
3164
- if (context.serverDeploy === "alchemy" && !isBackendSelf) {
3165
- const serverAppDir = path.join(projectDir, "apps/server");
3166
- if (await fs.pathExists(alchemyTemplateSrc) && await fs.pathExists(serverAppDir)) {
3167
- await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, serverAppDir, context);
3168
- await processAndCopyFiles("env.d.ts.hbs", alchemyTemplateSrc, serverAppDir, context);
3169
- await addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc);
3170
- }
3160
+ if (await fs.pathExists(alchemyTemplateSrc)) {
3161
+ await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, projectDir, context);
3162
+ const serverAppDir = path.join(projectDir, "apps/server");
3163
+ if (await fs.pathExists(serverAppDir)) await processAndCopyFiles("env.d.ts.hbs", alchemyTemplateSrc, serverAppDir, context);
3164
+ }
3165
+ } else {
3166
+ if (context.webDeploy === "alchemy") {
3167
+ const alchemyTemplateSrc = path.join(PKG_ROOT, "templates/deploy/alchemy");
3168
+ const webAppDir = path.join(projectDir, "apps/web");
3169
+ if (await fs.pathExists(alchemyTemplateSrc) && await fs.pathExists(webAppDir)) await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, webAppDir, context);
3170
+ }
3171
+ if (context.serverDeploy === "alchemy") {
3172
+ const alchemyTemplateSrc = path.join(PKG_ROOT, "templates/deploy/alchemy");
3173
+ const serverAppDir = path.join(projectDir, "apps/server");
3174
+ if (await fs.pathExists(alchemyTemplateSrc) && await fs.pathExists(serverAppDir)) {
3175
+ await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, serverAppDir, context);
3176
+ await processAndCopyFiles("env.d.ts.hbs", alchemyTemplateSrc, serverAppDir, context);
3171
3177
  }
3172
3178
  }
3173
3179
  }
@@ -3190,7 +3196,7 @@ async function setupDeploymentTemplates(projectDir, context) {
3190
3196
  }
3191
3197
  }
3192
3198
  }
3193
- if (context.serverDeploy !== "none" && context.serverDeploy !== "alchemy" && !isBackendSelf) {
3199
+ if (context.serverDeploy !== "none" && context.serverDeploy !== "alchemy") {
3194
3200
  const serverAppDir = path.join(projectDir, "apps/server");
3195
3201
  if (await fs.pathExists(serverAppDir)) {
3196
3202
  const deployTemplateSrc = path.join(PKG_ROOT, `templates/deploy/${context.serverDeploy}/server`);
@@ -3198,18 +3204,6 @@ async function setupDeploymentTemplates(projectDir, context) {
3198
3204
  }
3199
3205
  }
3200
3206
  }
3201
- async function addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc) {
3202
- for (const packageName of [
3203
- "packages/api",
3204
- "packages/auth",
3205
- "packages/db"
3206
- ]) {
3207
- const packageDir = path.join(projectDir, packageName);
3208
- if (await fs.pathExists(packageDir)) await processAndCopyFiles("env.d.ts.hbs", alchemyTemplateSrc, packageDir, context);
3209
- }
3210
- const serverAppDir = path.join(projectDir, "apps/server");
3211
- if (await fs.pathExists(serverAppDir)) await processAndCopyFiles("env.d.ts.hbs", alchemyTemplateSrc, serverAppDir, context);
3212
- }
3213
3207
 
3214
3208
  //#endregion
3215
3209
  //#region src/helpers/core/add-addons.ts
@@ -3275,7 +3269,7 @@ async function setupServerDeploy(config) {
3275
3269
  serverDir,
3276
3270
  packageManager
3277
3271
  });
3278
- } else if (serverDeploy === "alchemy") await setupAlchemyServerDeploy(serverDir, packageManager, projectDir);
3272
+ } else if (serverDeploy === "alchemy") await setupAlchemyServerDeploy(serverDir, packageManager);
3279
3273
  }
3280
3274
  async function setupWorkersServerDeploy(serverDir, _packageManager) {
3281
3275
  const packageJsonPath = path.join(serverDir, "package.json");
@@ -3312,7 +3306,7 @@ async function generateCloudflareWorkerTypes({ serverDir, packageManager }) {
3312
3306
  log.warn(`Note: You can manually run 'cd apps/server && ${managerCmd} cf-typegen' in the project directory later`);
3313
3307
  }
3314
3308
  }
3315
- async function setupAlchemyServerDeploy(serverDir, _packageManager, projectDir) {
3309
+ async function setupAlchemyServerDeploy(serverDir, _packageManager) {
3316
3310
  if (!await fs.pathExists(serverDir)) return;
3317
3311
  await addPackageDependency({
3318
3312
  devDependencies: [
@@ -3323,7 +3317,6 @@ async function setupAlchemyServerDeploy(serverDir, _packageManager, projectDir)
3323
3317
  ],
3324
3318
  projectDir: serverDir
3325
3319
  });
3326
- if (projectDir) await addAlchemyPackagesDependencies$1(projectDir);
3327
3320
  const packageJsonPath = path.join(serverDir, "package.json");
3328
3321
  if (await fs.pathExists(packageJsonPath)) {
3329
3322
  const packageJson = await fs.readJson(packageJsonPath);
@@ -3336,19 +3329,6 @@ async function setupAlchemyServerDeploy(serverDir, _packageManager, projectDir)
3336
3329
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
3337
3330
  }
3338
3331
  }
3339
- async function addAlchemyPackagesDependencies$1(projectDir) {
3340
- for (const packageName of [
3341
- "packages/api",
3342
- "packages/auth",
3343
- "packages/db"
3344
- ]) {
3345
- const packageDir = path.join(projectDir, packageName);
3346
- if (await fs.pathExists(packageDir)) await addPackageDependency({
3347
- devDependencies: ["@cloudflare/workers-types"],
3348
- projectDir: packageDir
3349
- });
3350
- }
3351
- }
3352
3332
 
3353
3333
  //#endregion
3354
3334
  //#region src/helpers/deployment/alchemy/alchemy-next-setup.ts
@@ -3654,7 +3634,7 @@ async function setupCombinedAlchemyDeploy(projectDir, packageManager, config) {
3654
3634
  await fs.writeJson(rootPkgPath, pkg, { spaces: 2 });
3655
3635
  }
3656
3636
  const serverDir = path.join(projectDir, "apps/server");
3657
- if (await fs.pathExists(serverDir)) await setupAlchemyServerDeploy(serverDir, packageManager, projectDir);
3637
+ if (await fs.pathExists(serverDir)) await setupAlchemyServerDeploy(serverDir, packageManager);
3658
3638
  const frontend = config.frontend;
3659
3639
  const isNext = frontend.includes("next");
3660
3640
  const isNuxt = frontend.includes("nuxt");
@@ -3887,7 +3867,6 @@ async function setupWebDeploy(config) {
3887
3867
  if (webDeploy !== "wrangler" && webDeploy !== "alchemy") return;
3888
3868
  if (webDeploy === "alchemy" && serverDeploy === "alchemy") {
3889
3869
  await setupCombinedAlchemyDeploy(projectDir, packageManager, config);
3890
- await addAlchemyPackagesDependencies(projectDir);
3891
3870
  return;
3892
3871
  }
3893
3872
  const isNext = frontend.includes("next");
@@ -3911,7 +3890,6 @@ async function setupWebDeploy(config) {
3911
3890
  else if (isTanstackRouter) await setupTanStackRouterAlchemyDeploy(projectDir, packageManager);
3912
3891
  else if (isReactRouter) await setupReactRouterAlchemyDeploy(projectDir, packageManager);
3913
3892
  else if (isSolid) await setupSolidAlchemyDeploy(projectDir, packageManager);
3914
- await addAlchemyPackagesDependencies(projectDir);
3915
3893
  }
3916
3894
  }
3917
3895
  async function setupWorkersWebDeploy(projectDir, pkgManager) {
@@ -3929,19 +3907,6 @@ async function setupWorkersWebDeploy(projectDir, pkgManager) {
3929
3907
  }
3930
3908
  await setupWorkersVitePlugin(projectDir);
3931
3909
  }
3932
- async function addAlchemyPackagesDependencies(projectDir) {
3933
- for (const packageName of [
3934
- "packages/api",
3935
- "packages/auth",
3936
- "packages/db"
3937
- ]) {
3938
- const packageDir = path.join(projectDir, packageName);
3939
- if (await fs.pathExists(packageDir)) await addPackageDependency({
3940
- devDependencies: ["@cloudflare/workers-types"],
3941
- projectDir: packageDir
3942
- });
3943
- }
3944
- }
3945
3910
 
3946
3911
  //#endregion
3947
3912
  //#region src/helpers/core/add-deployment.ts
@@ -4267,7 +4232,7 @@ function getConvexDependencies(frontend) {
4267
4232
  return deps;
4268
4233
  }
4269
4234
  async function setupApi(config) {
4270
- const { api, projectName, frontend, backend, packageManager, projectDir } = config;
4235
+ const { api, projectName, frontend, backend, packageManager, projectDir, auth } = config;
4271
4236
  const isConvex = backend === "convex";
4272
4237
  const webDir = path.join(projectDir, "apps/web");
4273
4238
  const nativeDir = path.join(projectDir, "apps/native");
@@ -4288,14 +4253,40 @@ async function setupApi(config) {
4288
4253
  dependencies: apiDeps.server.dependencies,
4289
4254
  projectDir: webDir
4290
4255
  });
4291
- if (backend === "self") {
4292
- const frameworkDeps = [];
4256
+ const frameworkDeps = [];
4257
+ if (backend === "hono") frameworkDeps.push("hono");
4258
+ else if (backend === "elysia") frameworkDeps.push("elysia");
4259
+ else if (backend === "express") frameworkDeps.push("express", "@types/express");
4260
+ else if (backend === "fastify") frameworkDeps.push("fastify");
4261
+ else if (backend === "self") {
4293
4262
  if (frontend.includes("next")) frameworkDeps.push("next");
4294
- if (frameworkDeps.length > 0) await addPackageDependency({
4295
- dependencies: frameworkDeps,
4263
+ }
4264
+ if (frameworkDeps.length > 0) await addPackageDependency({
4265
+ dependencies: frameworkDeps,
4266
+ projectDir: apiPackageDir
4267
+ });
4268
+ if (api === "trpc") {
4269
+ if (backend === "hono") await addPackageDependency({
4270
+ dependencies: ["@hono/trpc-server"],
4271
+ projectDir: apiPackageDir
4272
+ });
4273
+ else if (backend === "elysia") await addPackageDependency({
4274
+ dependencies: ["@elysiajs/trpc"],
4275
+ projectDir: apiPackageDir
4276
+ });
4277
+ else if (backend === "express") await addPackageDependency({
4278
+ dependencies: ["@trpc/server"],
4279
+ projectDir: apiPackageDir
4280
+ });
4281
+ else if (backend === "fastify") await addPackageDependency({
4282
+ dependencies: ["@trpc/server"],
4296
4283
  projectDir: apiPackageDir
4297
4284
  });
4298
4285
  }
4286
+ if (auth === "better-auth") await addPackageDependency({
4287
+ dependencies: ["better-auth"],
4288
+ projectDir: apiPackageDir
4289
+ });
4299
4290
  }
4300
4291
  if (webDirExists && apiDeps.web) await addPackageDependency({
4301
4292
  dependencies: apiDeps.web.dependencies,
@@ -4347,23 +4338,34 @@ async function setupBackendDependencies(config) {
4347
4338
  const devDependencies = [];
4348
4339
  if (framework === "hono") {
4349
4340
  dependencies.push("hono");
4350
- if (runtime === "node") dependencies.push("@hono/node-server");
4341
+ if (api === "trpc") dependencies.push("@hono/trpc-server");
4342
+ if (runtime === "node") {
4343
+ dependencies.push("@hono/node-server");
4344
+ devDependencies.push("tsx", "@types/node");
4345
+ }
4351
4346
  } else if (framework === "elysia") {
4352
4347
  dependencies.push("elysia", "@elysiajs/cors");
4353
- if (runtime === "node") dependencies.push("@elysiajs/node");
4348
+ if (api === "trpc") dependencies.push("@elysiajs/trpc");
4349
+ if (runtime === "node") {
4350
+ dependencies.push("@elysiajs/node");
4351
+ devDependencies.push("tsx", "@types/node");
4352
+ }
4354
4353
  } else if (framework === "express") {
4355
4354
  dependencies.push("express", "cors");
4356
4355
  devDependencies.push("@types/express", "@types/cors");
4357
- } else if (framework === "fastify") dependencies.push("fastify", "@fastify/cors");
4356
+ if (runtime === "node") devDependencies.push("tsx", "@types/node");
4357
+ } else if (framework === "fastify") {
4358
+ dependencies.push("fastify", "@fastify/cors");
4359
+ if (runtime === "node") devDependencies.push("tsx", "@types/node");
4360
+ }
4358
4361
  if (api === "trpc") {
4359
- dependencies.push("@trpc/server");
4360
- if (framework === "hono") dependencies.push("@hono/trpc-server");
4361
- else if (framework === "elysia") dependencies.push("@elysiajs/trpc");
4362
+ if (framework === "express") dependencies.push("@trpc/server");
4363
+ else if (framework === "fastify") dependencies.push("@trpc/server");
4364
+ else if (runtime === "workers") dependencies.push("@trpc/server");
4362
4365
  } else if (api === "orpc") dependencies.push("@orpc/server", "@orpc/openapi", "@orpc/zod");
4363
4366
  if (auth === "better-auth") dependencies.push("better-auth");
4364
4367
  if (examples.includes("ai")) dependencies.push("ai", "@ai-sdk/google");
4365
- if (runtime === "node") devDependencies.push("tsx", "@types/node");
4366
- else if (runtime === "bun") devDependencies.push("@types/bun");
4368
+ if (runtime === "bun") devDependencies.push("@types/bun");
4367
4369
  if (dependencies.length > 0 || devDependencies.length > 0) await addPackageDependency({
4368
4370
  dependencies,
4369
4371
  devDependencies,
@@ -5993,7 +5995,7 @@ This project uses Convex as a backend. You'll need to set up Convex before runni
5993
5995
  ${packageManagerRunCmd} dev:setup
5994
5996
  \`\`\`
5995
5997
 
5996
- Follow the prompts to create a new Convex project and connect it to your application.${auth === "clerk" ? " See [Convex + Clerk guide](https://docs.convex.dev/auth/clerk) for auth setup." : ""}` : generateDatabaseSetup(database, auth, packageManagerRunCmd, orm, options.dbSetup, options.serverDeploy, options.backend)}
5998
+ Follow the prompts to create a new Convex project and connect it to your application.${auth === "clerk" ? " See [Convex + Clerk guide](https://docs.convex.dev/auth/clerk) for auth setup." : ""}` : generateDatabaseSetup(database, auth, packageManagerRunCmd, orm, options.dbSetup, options.serverDeploy)}
5997
5999
 
5998
6000
  Then, run the development server:
5999
6001
 
@@ -6046,7 +6048,6 @@ function generateRunningInstructions(frontend, backend, webPort, hasNative, isCo
6046
6048
  const instructions = [];
6047
6049
  const hasFrontendNone = frontend.length === 0 || frontend.includes("none");
6048
6050
  const isBackendNone = backend === "none";
6049
- const isBackendSelf = backend === "self";
6050
6051
  if (!hasFrontendNone) {
6051
6052
  const hasTanstackRouter = frontend.includes("tanstack-router");
6052
6053
  const hasReactRouter = frontend.includes("react-router");
@@ -6055,19 +6056,17 @@ function generateRunningInstructions(frontend, backend, webPort, hasNative, isCo
6055
6056
  const hasSvelte = frontend.includes("svelte");
6056
6057
  const hasNuxt = frontend.includes("nuxt");
6057
6058
  const hasSolid = frontend.includes("solid");
6058
- if (hasTanstackRouter || hasReactRouter || hasNext || hasTanstackStart || hasSvelte || hasNuxt || hasSolid) if (isBackendSelf) instructions.push(`Open [http://localhost:${webPort}](http://localhost:${webPort}) in your browser to see your fullstack application.`);
6059
- else instructions.push(`Open [http://localhost:${webPort}](http://localhost:${webPort}) in your browser to see the web application.`);
6059
+ 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.`);
6060
6060
  }
6061
6061
  if (hasNative) instructions.push("Use the Expo Go app to run the mobile application.");
6062
6062
  if (isConvex) instructions.push("Your app will connect to the Convex cloud backend automatically.");
6063
- else if (!isBackendNone && !isBackendSelf) instructions.push("The API is running at [http://localhost:3000](http://localhost:3000).");
6063
+ else if (!isBackendNone) instructions.push("The API is running at [http://localhost:3000](http://localhost:3000).");
6064
6064
  return instructions.join("\n");
6065
6065
  }
6066
6066
  function generateProjectStructure(projectName, frontend, backend, addons, isConvex, api, auth) {
6067
6067
  const structure = [`${projectName}/`, "├── apps/"];
6068
6068
  const hasFrontendNone = frontend.length === 0 || frontend.includes("none");
6069
6069
  const isBackendNone = backend === "none";
6070
- const isBackendSelf = backend === "self";
6071
6070
  if (!hasFrontendNone) {
6072
6071
  const hasTanstackRouter = frontend.includes("tanstack-router");
6073
6072
  const hasReactRouter = frontend.includes("react-router");
@@ -6085,32 +6084,21 @@ function generateProjectStructure(projectName, frontend, backend, addons, isConv
6085
6084
  else if (hasSvelte) frontendType = "SvelteKit";
6086
6085
  else if (hasNuxt) frontendType = "Nuxt";
6087
6086
  else if (hasSolid) frontendType = "SolidJS";
6088
- if (isBackendSelf) structure.push(`│ └── web/ # Fullstack application (${frontendType})`);
6089
- else structure.push(`│ ├── web/ # Frontend application (${frontendType})`);
6087
+ structure.push(`│ ├── web/ # Frontend application (${frontendType})`);
6090
6088
  }
6091
6089
  }
6092
- if (frontend.includes("native-nativewind") || frontend.includes("native-unistyles")) if (isBackendSelf) structure.push("│ ├── native/ # Mobile application (React Native, Expo)");
6093
- else structure.push("│ ├── native/ # Mobile application (React Native, Expo)");
6094
- if (addons.includes("starlight")) if (isBackendSelf) structure.push("│ ├── docs/ # Documentation site (Astro Starlight)");
6095
- else structure.push("├── docs/ # Documentation site (Astro Starlight)");
6096
- if (!isBackendSelf && !isBackendNone && !isConvex) {
6090
+ if (frontend.includes("native-nativewind") || frontend.includes("native-unistyles")) structure.push("│ ├── native/ # Mobile application (React Native, Expo)");
6091
+ if (addons.includes("starlight")) structure.push("│ ├── docs/ # Documentation site (Astro Starlight)");
6092
+ if (isConvex) {
6093
+ structure.push("├── packages/");
6094
+ structure.push("│ └── backend/ # Convex backend functions and schema");
6095
+ if (auth === "clerk") structure.push("│ ├── convex/ # Convex functions and schema", "│ └── .env.local # Convex environment variables");
6096
+ } else if (!isBackendNone) {
6097
6097
  const backendName = backend[0].toUpperCase() + backend.slice(1);
6098
6098
  const apiName = api !== "none" ? api.toUpperCase() : "";
6099
6099
  const backendDesc = apiName ? `${backendName}, ${apiName}` : backendName;
6100
6100
  structure.push(`│ └── server/ # Backend API (${backendDesc})`);
6101
6101
  }
6102
- if (isConvex || !isBackendNone) {
6103
- structure.push("├── packages/");
6104
- if (isConvex) {
6105
- structure.push("│ ├── backend/ # Convex backend functions and schema");
6106
- if (auth === "clerk") structure.push("│ │ ├── convex/ # Convex functions and schema", "│ │ └── .env.local # Convex environment variables");
6107
- }
6108
- if (!isConvex) {
6109
- structure.push("│ ├── api/ # API layer / business logic");
6110
- if (auth !== "none") structure.push("│ ├── auth/ # Authentication configuration & logic");
6111
- if (api !== "none" || auth !== "none") structure.push("│ └── db/ # Database schema & queries");
6112
- }
6113
- }
6114
6102
  return structure.join("\n");
6115
6103
  }
6116
6104
  function generateFeaturesList(database, auth, addons, orm, runtime, frontend, backend, api) {
@@ -6168,36 +6156,33 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
6168
6156
  else if (addon === "turborepo") addonsList.push("- **Turborepo** - Optimized monorepo build system");
6169
6157
  return addonsList.join("\n");
6170
6158
  }
6171
- function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm, dbSetup, serverDeploy, backend) {
6159
+ function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm, dbSetup, serverDeploy) {
6172
6160
  if (database === "none") return "";
6173
- const isBackendSelf = backend === "self";
6174
- const envPath = isBackendSelf ? "apps/web/.env" : "apps/server/.env";
6175
- const dbLocalPath = isBackendSelf ? "apps/web" : "apps/server";
6176
6161
  let setup = "## Database Setup\n\n";
6177
6162
  if (database === "sqlite") setup += `This project uses SQLite${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
6178
6163
 
6179
6164
  1. Start the local SQLite database:
6180
6165
  ${dbSetup === "d1" ? serverDeploy === "alchemy" ? "D1 local development and migrations are handled automatically by Alchemy during dev and deploy." : "Local development for a Cloudflare D1 database will already be running as part of the `wrangler dev` command." : `\`\`\`bash
6181
- cd ${dbLocalPath} && ${packageManagerRunCmd} db:local
6166
+ cd apps/server && ${packageManagerRunCmd} db:local
6182
6167
  \`\`\`
6183
6168
  `}
6184
6169
 
6185
- 2. Update your \`.env\` file in the \`${isBackendSelf ? "apps/web" : "apps/server"}\` directory with the appropriate connection details if needed.
6170
+ 2. Update your \`.env\` file in the \`apps/server\` directory with the appropriate connection details if needed.
6186
6171
  `;
6187
6172
  else if (database === "postgres") setup += `This project uses PostgreSQL${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
6188
6173
 
6189
6174
  1. Make sure you have a PostgreSQL database set up.
6190
- 2. Update your \`${envPath}\` file with your PostgreSQL connection details.
6175
+ 2. Update your \`apps/server/.env\` file with your PostgreSQL connection details.
6191
6176
  `;
6192
6177
  else if (database === "mysql") setup += `This project uses MySQL${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
6193
6178
 
6194
6179
  1. Make sure you have a MySQL database set up.
6195
- 2. Update your \`${envPath}\` file with your MySQL connection details.
6180
+ 2. Update your \`apps/server/.env\` file with your MySQL connection details.
6196
6181
  `;
6197
6182
  else if (database === "mongodb") setup += `This project uses MongoDB ${orm === "mongoose" ? "with Mongoose" : orm === "prisma" ? "with Prisma ORM" : `with ${orm}`}.
6198
6183
 
6199
6184
  1. Make sure you have MongoDB set up.
6200
- 2. Update your \`${envPath}\` file with your MongoDB connection URI.
6185
+ 2. Update your \`apps/server/.env\` file with your MongoDB connection URI.
6201
6186
  `;
6202
6187
  setup += `
6203
6188
  3. ${orm === "prisma" ? `Generate the Prisma client and push the schema:
@@ -6216,14 +6201,13 @@ ${packageManagerRunCmd} db:push
6216
6201
  function generateScriptsList(packageManagerRunCmd, database, orm, _auth, hasNative, addons, backend) {
6217
6202
  const isConvex = backend === "convex";
6218
6203
  const isBackendNone = backend === "none";
6219
- const isBackendSelf = backend === "self";
6220
6204
  let scripts = `- \`${packageManagerRunCmd} dev\`: Start all applications in development mode
6221
6205
  - \`${packageManagerRunCmd} build\`: Build all applications`;
6222
- if (!isBackendSelf) scripts += `
6206
+ scripts += `
6223
6207
  - \`${packageManagerRunCmd} dev:web\`: Start only the web application`;
6224
6208
  if (isConvex) scripts += `
6225
6209
  - \`${packageManagerRunCmd} dev:setup\`: Setup and configure your Convex project`;
6226
- else if (!isBackendNone && !isBackendSelf) scripts += `
6210
+ else if (!isBackendNone) scripts += `
6227
6211
  - \`${packageManagerRunCmd} dev:server\`: Start only the server`;
6228
6212
  scripts += `
6229
6213
  - \`${packageManagerRunCmd} check-types\`: Check TypeScript types across all apps`;
@@ -6234,7 +6218,7 @@ function generateScriptsList(packageManagerRunCmd, database, orm, _auth, hasNati
6234
6218
  - \`${packageManagerRunCmd} db:push\`: Push schema changes to database
6235
6219
  - \`${packageManagerRunCmd} db:studio\`: Open database studio UI`;
6236
6220
  if (database === "sqlite" && orm === "drizzle") scripts += `
6237
- - \`cd ${isBackendSelf ? "apps/web" : "apps/server"} && ${packageManagerRunCmd} db:local\`: Start the local SQLite database`;
6221
+ - \`cd apps/server && ${packageManagerRunCmd} db:local\`: Start the local SQLite database`;
6238
6222
  }
6239
6223
  if (addons.includes("biome")) scripts += `
6240
6224
  - \`${packageManagerRunCmd} check\`: Run Biome formatting and linting`;
@@ -6391,20 +6375,19 @@ async function getDockerStatus(database) {
6391
6375
  async function displayPostInstallInstructions(config) {
6392
6376
  const { api, database, relativePath, packageManager, depsInstalled, orm, addons, runtime, frontend, backend, dbSetup, webDeploy, serverDeploy } = config;
6393
6377
  const isConvex = backend === "convex";
6394
- const isBackendSelf = backend === "self";
6395
6378
  const runCmd = packageManager === "npm" ? "npm run" : packageManager === "pnpm" ? "pnpm run" : "bun run";
6396
6379
  const cdCmd = `cd ${relativePath}`;
6397
6380
  const hasHuskyOrBiome = addons?.includes("husky") || addons?.includes("biome");
6398
- const databaseInstructions = !isConvex && database !== "none" ? await getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup, serverDeploy, backend) : "";
6381
+ const databaseInstructions = !isConvex && database !== "none" ? await getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup, serverDeploy) : "";
6399
6382
  const tauriInstructions = addons?.includes("tauri") ? getTauriInstructions(runCmd) : "";
6400
6383
  const lintingInstructions = hasHuskyOrBiome ? getLintingInstructions(runCmd) : "";
6401
6384
  const nativeInstructions = frontend?.includes("native-nativewind") || frontend?.includes("native-unistyles") ? getNativeInstructions(isConvex) : "";
6402
6385
  const pwaInstructions = addons?.includes("pwa") && frontend?.includes("react-router") ? getPwaInstructions() : "";
6403
6386
  const starlightInstructions = addons?.includes("starlight") ? getStarlightInstructions(runCmd) : "";
6404
6387
  const clerkInstructions = isConvex && config.auth === "clerk" ? getClerkInstructions() : "";
6405
- const polarInstructions = config.payments === "polar" && config.auth === "better-auth" ? getPolarInstructions(backend) : "";
6406
- const wranglerDeployInstructions = getWranglerDeployInstructions(runCmd, webDeploy, serverDeploy, backend);
6407
- const alchemyDeployInstructions = getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend);
6388
+ const polarInstructions = config.payments === "polar" && config.auth === "better-auth" ? getPolarInstructions() : "";
6389
+ const wranglerDeployInstructions = getWranglerDeployInstructions(runCmd, webDeploy, serverDeploy);
6390
+ const alchemyDeployInstructions = getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy);
6408
6391
  const hasWeb = frontend?.some((f) => [
6409
6392
  "tanstack-router",
6410
6393
  "react-router",
@@ -6428,8 +6411,7 @@ async function displayPostInstallInstructions(config) {
6428
6411
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:setup\n${pc.dim(" (this will guide you through Convex project setup)")}\n`;
6429
6412
  output += `${pc.cyan(`${stepCounter++}.`)} Copy environment variables from\n${pc.white(" packages/backend/.env.local")} to ${pc.white("apps/*/.env")}\n`;
6430
6413
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n\n`;
6431
- } else if (isBackendSelf) output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
6432
- else {
6414
+ } else {
6433
6415
  if (runtime !== "workers") output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
6434
6416
  if (runtime === "workers") {
6435
6417
  if (dbSetup === "d1") output += `${pc.yellow("IMPORTANT:")} Complete D1 database setup first\n (see Database commands below)\n`;
@@ -6440,11 +6422,11 @@ async function displayPostInstallInstructions(config) {
6440
6422
  output += `${pc.bold("Your project will be available at:")}\n`;
6441
6423
  if (hasWeb) output += `${pc.cyan("•")} Frontend: http://localhost:${webPort}\n`;
6442
6424
  else if (!hasNative && !addons?.includes("starlight")) output += `${pc.yellow("NOTE:")} You are creating a backend-only app\n (no frontend selected)\n`;
6443
- if (!isConvex && !isBackendSelf) {
6425
+ if (!isConvex) {
6444
6426
  output += `${pc.cyan("•")} Backend API: http://localhost:3000\n`;
6445
- if (api === "orpc") output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/api\n`;
6427
+ if (api === "orpc") if (backend === "self") output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/rpc/api\n`;
6428
+ else output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/api\n`;
6446
6429
  }
6447
- if (isBackendSelf && api === "orpc") output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:${webPort}/rpc/api\n`;
6448
6430
  if (addons?.includes("starlight")) output += `${pc.cyan("•")} Docs: http://localhost:4321\n`;
6449
6431
  if (addons?.includes("fumadocs")) output += `${pc.cyan("•")} Fumadocs: http://localhost:4000\n`;
6450
6432
  if (nativeInstructions) output += `\n${nativeInstructions.trim()}\n`;
@@ -6476,7 +6458,7 @@ function getNativeInstructions(isConvex) {
6476
6458
  function getLintingInstructions(runCmd) {
6477
6459
  return `${pc.bold("Linting and formatting:")}\n${pc.cyan("•")} Format and lint fix: ${`${runCmd} check`}\n`;
6478
6460
  }
6479
- async function getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup, serverDeploy, backend) {
6461
+ async function getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup, serverDeploy) {
6480
6462
  const instructions = [];
6481
6463
  if (dbSetup === "docker") {
6482
6464
  const dockerStatus = await getDockerStatus(database);
@@ -6490,9 +6472,8 @@ async function getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup,
6490
6472
  const packageManager = runCmd === "npm run" ? "npm" : runCmd || "npm";
6491
6473
  instructions.push(`${pc.cyan("1.")} Login to Cloudflare: ${pc.white(`${packageManager} wrangler login`)}`);
6492
6474
  instructions.push(`${pc.cyan("2.")} Create D1 database: ${pc.white(`${packageManager} wrangler d1 create your-database-name`)}`);
6493
- const wranglerPath = backend === "self" ? "apps/web" : "apps/server";
6494
- instructions.push(`${pc.cyan("3.")} Update ${wranglerPath}/wrangler.jsonc with database_id and database_name`);
6495
- instructions.push(`${pc.cyan("4.")} Generate migrations: ${pc.white(`cd ${wranglerPath} && ${runCmd} db:generate`)}`);
6475
+ instructions.push(`${pc.cyan("3.")} Update apps/server/wrangler.jsonc with database_id and database_name`);
6476
+ instructions.push(`${pc.cyan("4.")} Generate migrations: ${pc.white(`cd apps/server && ${runCmd} db:generate`)}`);
6496
6477
  instructions.push(`${pc.cyan("5.")} Apply migrations locally: ${pc.white(`${packageManager} wrangler d1 migrations apply YOUR_DB_NAME --local`)}`);
6497
6478
  instructions.push(`${pc.cyan("6.")} Apply migrations to production: ${pc.white(`${packageManager} wrangler d1 migrations apply YOUR_DB_NAME`)}`);
6498
6479
  }
@@ -6516,10 +6497,7 @@ async function getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup,
6516
6497
  if (dbSetup === "docker") instructions.push(`${pc.cyan("•")} Start docker container: ${`${runCmd} db:start`}`);
6517
6498
  if (dbSetup !== "d1") instructions.push(`${pc.cyan("•")} Apply schema: ${`${runCmd} db:push`}`);
6518
6499
  if (!(dbSetup === "d1" && serverDeploy === "alchemy")) instructions.push(`${pc.cyan("•")} Database UI: ${`${runCmd} db:studio`}`);
6519
- if (database === "sqlite" && dbSetup !== "d1") {
6520
- const dbLocalPath = backend === "self" ? "apps/web" : "apps/server";
6521
- instructions.push(`${pc.cyan("•")} Start local DB (if needed): ${`cd ${dbLocalPath} && ${runCmd} db:local`}`);
6522
- }
6500
+ if (database === "sqlite" && dbSetup !== "d1") instructions.push(`${pc.cyan("•")} Start local DB (if needed): ${`cd apps/server && ${runCmd} db:local`}`);
6523
6501
  } else if (orm === "mongoose") {
6524
6502
  if (dbSetup === "docker") instructions.push(`${pc.cyan("•")} Start docker container: ${`${runCmd} db:start`}`);
6525
6503
  } else if (orm === "none") instructions.push(`${pc.yellow("NOTE:")} Manual database schema setup\n required.`);
@@ -6540,28 +6518,23 @@ function getNoOrmWarning() {
6540
6518
  function getBunWebNativeWarning() {
6541
6519
  return `\n${pc.yellow("WARNING:")} 'bun' might cause issues with web + native apps in a monorepo.\n Use 'pnpm' if problems arise.`;
6542
6520
  }
6543
- function getWranglerDeployInstructions(runCmd, webDeploy, serverDeploy, backend) {
6521
+ function getWranglerDeployInstructions(runCmd, webDeploy, serverDeploy) {
6544
6522
  const instructions = [];
6545
- if (webDeploy === "wrangler") {
6546
- const deployPath = backend === "self" ? "apps/web" : "apps/web";
6547
- instructions.push(`${pc.bold("Deploy web to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd ${deployPath} && ${runCmd} run deploy`}`);
6548
- }
6549
- if (serverDeploy === "wrangler" && backend !== "self") instructions.push(`${pc.bold("Deploy server to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} run deploy`}`);
6523
+ if (webDeploy === "wrangler") instructions.push(`${pc.bold("Deploy web to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/web && ${runCmd} run deploy`}`);
6524
+ if (serverDeploy === "wrangler") instructions.push(`${pc.bold("Deploy server to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} run deploy`}`);
6550
6525
  return instructions.length ? `\n${instructions.join("\n")}` : "";
6551
6526
  }
6552
6527
  function getClerkInstructions() {
6553
6528
  return `${pc.bold("Clerk Authentication Setup:")}\n${pc.cyan("•")} Follow the guide: ${pc.underline("https://docs.convex.dev/auth/clerk")}\n${pc.cyan("•")} Set CLERK_JWT_ISSUER_DOMAIN in Convex Dashboard\n${pc.cyan("•")} Set CLERK_PUBLISHABLE_KEY in apps/*/.env`;
6554
6529
  }
6555
- function getPolarInstructions(backend) {
6556
- const envPath = backend === "self" ? "apps/web/.env" : "apps/server/.env";
6557
- return `${pc.bold("Polar Payments Setup:")}\n${pc.cyan("•")} Get access token & product ID from ${pc.underline("https://sandbox.polar.sh/")}\n${pc.cyan("•")} Set POLAR_ACCESS_TOKEN in ${envPath}`;
6530
+ function getPolarInstructions() {
6531
+ return `${pc.bold("Polar Payments Setup:")}\n${pc.cyan("•")} Get access token & product ID from ${pc.underline("https://sandbox.polar.sh/")}\n${pc.cyan("•")} Set POLAR_ACCESS_TOKEN in apps/server/.env`;
6558
6532
  }
6559
- function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend) {
6533
+ function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy) {
6560
6534
  const instructions = [];
6561
- const isBackendSelf = backend === "self";
6562
6535
  if (webDeploy === "alchemy" && serverDeploy !== "alchemy") instructions.push(`${pc.bold("Deploy web with Alchemy:")}\n${pc.cyan("•")} Dev: ${`cd apps/web && ${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`cd apps/web && ${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`cd apps/web && ${runCmd} destroy`}`);
6563
- else if (serverDeploy === "alchemy" && webDeploy !== "alchemy" && !isBackendSelf) instructions.push(`${pc.bold("Deploy server with Alchemy:")}\n${pc.cyan("•")} Dev: ${`cd apps/server && ${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`cd apps/server && ${runCmd} destroy`}`);
6564
- else if (webDeploy === "alchemy" && (serverDeploy === "alchemy" || isBackendSelf)) instructions.push(`${pc.bold("Deploy with Alchemy:")}\n${pc.cyan("•")} Dev: ${`${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`${runCmd} destroy`}`);
6536
+ else if (serverDeploy === "alchemy" && webDeploy !== "alchemy") instructions.push(`${pc.bold("Deploy server with Alchemy:")}\n${pc.cyan("•")} Dev: ${`cd apps/server && ${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`cd apps/server && ${runCmd} destroy`}`);
6537
+ else if (webDeploy === "alchemy" && serverDeploy === "alchemy") instructions.push(`${pc.bold("Deploy with Alchemy:")}\n${pc.cyan("•")} Dev: ${`${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`${runCmd} destroy`}`);
6565
6538
  return instructions.length ? `\n${instructions.join("\n")}` : "";
6566
6539
  }
6567
6540
 
@@ -6617,21 +6590,12 @@ async function setupWorkspaceDependencies(projectDir, options) {
6617
6590
  projectDir: webPackageDir
6618
6591
  });
6619
6592
  }
6620
- const runtimeDevDeps = getRuntimeDevDeps(options);
6621
6593
  await addPackageDependency({
6622
6594
  dependencies: commonDeps,
6623
- devDependencies: [...commonDevDeps, ...runtimeDevDeps],
6595
+ devDependencies: commonDevDeps,
6624
6596
  projectDir
6625
6597
  });
6626
6598
  }
6627
- function getRuntimeDevDeps(options) {
6628
- const { runtime, backend } = options;
6629
- if (runtime === "none" && backend === "self") return ["@types/node"];
6630
- if (runtime === "node") return ["@types/node"];
6631
- if (runtime === "bun") return ["@types/bun"];
6632
- if (runtime === "workers") return ["@types/node"];
6633
- return [];
6634
- }
6635
6599
 
6636
6600
  //#endregion
6637
6601
  //#region src/helpers/core/project-config.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "2.50.1-canary.58bbe5f6",
3
+ "version": "2.50.1-canary.7ebd503f",
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",
@@ -8,14 +8,14 @@ This is a monorepo with the following structure:
8
8
 
9
9
  {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
10
10
  (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
11
- - **`apps/web/`** - {{#if (eq backend "self")}}Fullstack application{{else}}Frontend application{{/if}}{{#if (includes frontend "tanstack-router")}} (React with TanStack Router){{else
11
+ - **`apps/web/`** - Frontend application{{#if (includes frontend "tanstack-router")}} (React with TanStack Router){{else
12
12
  if (includes frontend "react-router")}} (React with React Router){{else if (includes frontend "next")}} (Next.js){{else
13
13
  if (includes frontend "nuxt")}} (Nuxt.js){{else if (includes frontend "svelte")}} (SvelteKit){{else if (includes
14
14
  frontend "solid")}} (SolidStart){{/if}}
15
15
  {{/if}}
16
16
 
17
17
  {{#if (ne backend "convex")}}
18
- {{#if (and (ne backend "none") (ne backend "self"))}}
18
+ {{#if (ne backend "none")}}
19
19
  - **`apps/server/`** - Backend server{{#if (eq backend "hono")}} (Hono){{else if (eq backend "express")}}
20
20
  (Express){{else if (eq backend "fastify")}} (Fastify){{else if (eq backend "elysia")}} (Elysia){{else if (eq backend
21
21
  "next")}} (Next.js API){{/if}}
@@ -24,18 +24,6 @@ frontend "solid")}} (SolidStart){{/if}}
24
24
  - **`packages/backend/`** - Convex backend functions
25
25
  {{/if}}
26
26
 
27
- {{#if (or (ne backend "none") (ne backend "convex"))}}
28
- {{#if (ne api "none")}}
29
- - **`packages/api/`** - Shared API logic and types
30
- {{/if}}
31
- {{#if (and (ne auth "none") (ne backend "convex"))}}
32
- - **`packages/auth/`** - Authentication logic and utilities
33
- {{/if}}
34
- {{#if (and (ne database "none") (ne orm "none") (ne backend "convex"))}}
35
- - **`packages/db/`** - Database schema and utilities
36
- {{/if}}
37
- {{/if}}
38
-
39
27
  {{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
40
28
  - **`apps/native/`** - React Native mobile app{{#if (includes frontend "native-nativewind")}} (with NativeWind){{else if
41
29
  (includes frontend "native-unistyles")}} (with Unistyles){{/if}}
@@ -44,13 +32,15 @@ frontend "solid")}} (SolidStart){{/if}}
44
32
  ## Available Scripts
45
33
 
46
34
  - `{{packageManager}} run dev` - Start all apps in development mode
47
- {{#if (and (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
48
- (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid")) (ne backend "self"))}}
35
+ {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
36
+ (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
49
37
  - `{{packageManager}} run dev:web` - Start only the web app
50
38
  {{/if}}
51
- {{#if (and (ne backend "none") (ne backend "convex") (ne backend "self"))}}
39
+ {{#if (ne backend "none")}}
40
+ {{#if (ne backend "convex")}}
52
41
  - `{{packageManager}} run dev:server` - Start only the server
53
42
  {{/if}}
43
+ {{/if}}
54
44
  {{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
55
45
  - `{{packageManager}} run dev:native` - Start only the native app
56
46
  {{/if}}
@@ -58,7 +48,7 @@ frontend "solid")}} (SolidStart){{/if}}
58
48
  {{#if (and (ne database "none") (ne orm "none") (ne backend "convex"))}}
59
49
  ## Database Commands
60
50
 
61
- All database operations should be run from the {{#if (eq backend "self")}}web{{else}}server{{/if}} workspace:
51
+ All database operations should be run from the server workspace:
62
52
 
63
53
  - `{{packageManager}} run db:push` - Push schema changes to database
64
54
  - `{{packageManager}} run db:studio` - Open database studio
@@ -67,11 +57,11 @@ All database operations should be run from the {{#if (eq backend "self")}}web{{e
67
57
  - `{{packageManager}} run db:migrate` - Run database migrations
68
58
 
69
59
  {{#if (eq orm "drizzle")}}
70
- Database schema files are located in {{#if (eq backend "self")}}`apps/web/src/db/schema/`{{else}}`apps/server/src/db/schema/`{{/if}}
60
+ Database schema files are located in `apps/server/src/db/schema/`
71
61
  {{else if (eq orm "prisma")}}
72
- Database schema is located in {{#if (eq backend "self")}}`apps/web/prisma/schema.prisma`{{else}}`apps/server/prisma/schema.prisma`{{/if}}
62
+ Database schema is located in `apps/server/prisma/schema.prisma`
73
63
  {{else if (eq orm "mongoose")}}
74
- Database models are located in {{#if (eq backend "self")}}`apps/web/src/db/models/`{{else}}`apps/server/src/db/models/`{{/if}}
64
+ Database models are located in `apps/server/src/db/models/`
75
65
  {{/if}}
76
66
  {{/if}}
77
67
 
@@ -79,10 +69,10 @@ Database models are located in {{#if (eq backend "self")}}`apps/web/src/db/model
79
69
  ## API Structure
80
70
 
81
71
  {{#if (eq api "trpc")}}
82
- - tRPC routers are in {{#if (eq backend "self")}}`packages/api/src/routers/`{{else}}`apps/server/src/routers/`{{/if}}
72
+ - tRPC routers are in `apps/server/src/routers/`
83
73
  - Client-side tRPC utils are in `apps/web/src/utils/trpc.ts`
84
74
  {{else if (eq api "orpc")}}
85
- - oRPC endpoints are in {{#if (eq backend "self")}}`packages/api/src/api/`{{else}}`apps/server/src/api/`{{/if}}
75
+ - oRPC endpoints are in `apps/server/src/api/`
86
76
  - Client-side API utils are in `apps/web/src/utils/api.ts`
87
77
  {{/if}}
88
78
  {{/if}}
@@ -92,7 +82,7 @@ Database models are located in {{#if (eq backend "self")}}`apps/web/src/db/model
92
82
 
93
83
  Authentication is enabled in this project:
94
84
  {{#if (ne backend "convex")}}
95
- - Server auth logic is in {{#if (eq backend "self")}}`packages/auth/src/lib/auth.ts`{{else}}`apps/server/src/lib/auth.ts`{{/if}}
85
+ - Server auth logic is in `apps/server/src/lib/auth.ts`
96
86
  {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
97
87
  (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
98
88
  - Web app auth client is in `apps/web/src/lib/auth-client.ts`
@@ -14,7 +14,9 @@
14
14
  "scripts": {
15
15
  "build": "tsdown"
16
16
  },
17
- "devDependencies": {},
17
+ "devDependencies": {
18
+ "@types/bun": "latest"
19
+ },
18
20
  "peerDependencies": {
19
21
  "typescript": "^5"
20
22
  },
@@ -1,10 +1,10 @@
1
1
  {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "declarationMap": true,
6
- "sourceMap": true,
7
- "outDir": "dist",
8
- "composite": true
9
- }
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "types": [
7
+ "bun"
8
+ ],
9
+ }
10
10
  }
@@ -14,7 +14,9 @@
14
14
  "scripts": {
15
15
  "build": "tsdown"
16
16
  },
17
- "devDependencies": {},
17
+ "devDependencies": {
18
+ "@types/bun": "latest"
19
+ },
18
20
  "peerDependencies": {
19
21
  "typescript": "^5"
20
22
  }
@@ -1,10 +1,13 @@
1
1
  {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "declarationMap": true,
6
- "sourceMap": true,
7
- "outDir": "dist",
8
- "composite": true
9
- }
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "declarationMap": true,
6
+ "sourceMap": true,
7
+ "outDir": "dist",
8
+ "composite": true,
9
+ "types": [
10
+ "bun"
11
+ ]
12
+ }
10
13
  }
@@ -14,7 +14,10 @@
14
14
  "scripts": {
15
15
  "build": "tsdown"
16
16
  },
17
- "devDependencies": {},
17
+ "devDependencies": {
18
+ "@types/bun": "latest",
19
+ "@types/node": "^24.5.2"
20
+ },
18
21
  "peerDependencies": {
19
22
  "typescript": "^5"
20
23
  }
@@ -1,10 +1,13 @@
1
1
  {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "declarationMap": true,
6
- "sourceMap": true,
7
- "outDir": "dist",
8
- "composite": true
9
- }
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "declarationMap": true,
6
+ "sourceMap": true,
7
+ "outDir": "dist",
8
+ "composite": true,
9
+ "types": [
10
+ "bun"
11
+ ]
12
+ }
10
13
  }
@@ -5,8 +5,22 @@
5
5
  "outDir": "dist",
6
6
  "baseUrl": ".",
7
7
  "paths": {
8
- "@/*": ["./src/*"]
8
+ "@/*": ["./src/*"]{{#if (eq orm "prisma")}},
9
+ "prisma": ["node_modules/prisma"]{{/if}}
9
10
  },
11
+ "types": [
12
+ {{#if (eq runtime "node")}}
13
+ "node"
14
+ {{else if (eq runtime "bun")}}
15
+ "bun"
16
+ {{else if (eq runtime "workers")}}
17
+ "node"
18
+ {{else}}
19
+ "node",
20
+ "bun"
21
+ {{/if}}{{#if (eq serverDeploy "alchemy")}},
22
+ "@cloudflare/workers-types"{{/if}}
23
+ ],
10
24
  "jsx": "react-jsx"{{#if (eq backend "hono")}},
11
25
  "jsxImportSource": "hono/jsx"{{/if}}
12
26
  }
@@ -1,34 +1,23 @@
1
1
  {
2
- "$schema": "https://json.schemastore.org/tsconfig",
3
- "compilerOptions": {
4
- "target": "ESNext",
5
- "module": "ESNext",
6
- "moduleResolution": "bundler",
7
- "lib": ["ESNext"],
8
- "verbatimModuleSyntax": true,
9
- "strict": true,
10
- "skipLibCheck": true,
11
- "resolveJsonModule": true,
12
- "allowSyntheticDefaultImports": true,
13
- "esModuleInterop": true,
14
- "forceConsistentCasingInFileNames": true,
15
- "isolatedModules": true,
16
- "noUncheckedIndexedAccess": true,
17
- "noUnusedLocals": true,
18
- "noUnusedParameters": true,
19
- "noFallthroughCasesInSwitch": true,
20
- "types": [
21
- {{#if (eq runtime "node")}}
22
- "node"
23
- {{else if (eq runtime "bun")}}
24
- "bun"
25
- {{else if (eq runtime "workers")}}
26
- "node"
27
- {{else}}
28
- "node",
29
- "bun"
30
- {{/if}}{{#if (eq serverDeploy "alchemy")}},
31
- "@cloudflare/workers-types"{{/if}}
32
- ]
33
- }
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "compilerOptions": {
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "lib": [
8
+ "ESNext"
9
+ ],
10
+ "verbatimModuleSyntax": true,
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "resolveJsonModule": true,
14
+ "allowSyntheticDefaultImports": true,
15
+ "esModuleInterop": true,
16
+ "forceConsistentCasingInFileNames": true,
17
+ "isolatedModules": true,
18
+ "noUncheckedIndexedAccess": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "noFallthroughCasesInSwitch": true
22
+ }
34
23
  }
@@ -14,7 +14,9 @@
14
14
  "scripts": {
15
15
  "build": "tsdown"
16
16
  },
17
- "devDependencies": {},
17
+ "devDependencies": {
18
+ "@types/node": "^24.5.2"
19
+ },
18
20
  "peerDependencies": {
19
21
  "typescript": "^5"
20
22
  }
@@ -1,10 +1,13 @@
1
1
  {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "declarationMap": true,
6
- "sourceMap": true,
7
- "outDir": "dist",
8
- "composite": true
9
- }
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "declarationMap": true,
6
+ "sourceMap": true,
7
+ "outDir": "dist",
8
+ "composite": true,
9
+ "types": [
10
+ "bun"
11
+ ]
12
+ }
10
13
  }