Skip to content

feat(cli): add support for dynamic server name #486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

beeman
Copy link

@beeman beeman commented Aug 10, 2025

Attempt to add support for a dynamic server name instead of using the hardcoded server.

Fixes #485

Summary by CodeRabbit

  • New Features

    • Added support for customizing the backend server directory name throughout project creation, configuration, and templates.
    • Users can now specify a custom server name, which updates all relevant paths, scripts, environment files, and documentation references accordingly.
  • Documentation

    • Updated generated documentation and templates to reflect the dynamic server directory name instead of a fixed "server".
  • Bug Fixes

    • Resolved inconsistencies in paths and references by parameterizing the server directory name.
  • Style

    • Improved consistency across configuration and template files by removing hardcoded server directory references.

Copy link

changeset-bot bot commented Aug 10, 2025

🦋 Changeset detected

Latest commit: 280e377

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
create-better-t-stack Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

coderabbitai bot commented Aug 10, 2025

Walkthrough

This change introduces support for a configurable backend server app name (serverName) throughout the CLI, templates, and project generation logic. All hardcoded references to the "server" directory are replaced with dynamic usage of serverName, affecting configuration, environment files, code templates, and documentation.

Changes

Cohort / File(s) Change Summary
Types and Config Definitions
apps/cli/src/types.ts, apps/cli/src/constants.ts, apps/cli/src/index.ts, apps/cli/src/validation.ts, apps/cli/src/prompts/config-prompts.ts
Added serverName property to types and config objects; updated input schemas and config gathering to support dynamic server directory naming.
Project Generation and Setup Logic
apps/cli/src/helpers/project-generation/*, apps/cli/src/helpers/setup/*, apps/cli/src/utils/display-config.ts, apps/cli/src/utils/generate-reproducible-command.ts
Updated all logic to use serverName for directory paths, script names, and references; propagated serverName through project creation, environment setup, and configuration display.
Database Provider Helpers
apps/cli/src/helpers/database-providers/*
Modified all database setup helpers to accept and use serverName for environment file and directory paths, replacing hardcoded "server" references.
Template Management
apps/cli/src/helpers/project-generation/template-manager.ts
Updated all backend-related template setup functions to accept and use serverName for directory construction.
Documentation and Template Files
apps/cli/templates/**/*
Replaced hardcoded "server" references with {{serverName}} in all relevant code, documentation, and configuration templates for backend and frontend.
Changeset
.changeset/petite-corners-say.md
Added a changeset documenting the addition of dynamic server name support.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant ProjectGenerator
    participant Templates
    participant DatabaseSetup

    User->>CLI: Run project init with --server-name (optional)
    CLI->>ProjectGenerator: Pass serverName in config
    ProjectGenerator->>Templates: Render templates with serverName
    ProjectGenerator->>DatabaseSetup: Setup DB, pass serverName for env paths
    CLI->>User: Display config and instructions with serverName
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Add option to change the default name of the server app and propagate it throughout the CLI and code generation (#485)
Remove hardcoded "server" references in templates, configs, and documentation (#485)
Ensure all generated paths, scripts, and references use the configurable server name (#485)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes detected.

Possibly related PRs

  • Add D1 Database #335: Adds initial D1 database provider support, which this PR extends by making the D1 setup use a dynamic serverName for environment file paths.

Poem

The server once fixed, now dances by name,
"API" or "backend"—it’s never the same!
Through templates and scripts, the change is profound,
With serverName magic, new paths abound.
A hop and a skip, the rabbit approves—
Dynamic directories, the project groove improves!
🐇✨

Note

🔌 MCP (Model Context Protocol) integration is now available in Early Access!

Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@beeman beeman force-pushed the beeman/server-name branch 6 times, most recently from e26adce to aa0b051 Compare August 10, 2025 17:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 23

🔭 Outside diff range comments (10)
apps/cli/src/types.ts (1)

164-179: Persist serverName in BetterTStackConfig for reproducibility

BetterTStackConfig is missing serverName. Without persisting it, repo-local config and reproducible commands will drift from the generated app structure.

 export interface BetterTStackConfig {
   version: string;
   createdAt: string;
   database: Database;
   orm: ORM;
   backend: Backend;
   runtime: Runtime;
   frontend: Frontend[];
   addons: Addons[];
   examples: Examples[];
   auth: boolean;
   packageManager: PackageManager;
   dbSetup: DatabaseSetup;
   api: API;
   webDeploy: WebDeploy;
+  serverName: string;
 }
apps/cli/templates/backend/server/server-base/package.json.hbs (1)

2-9: Align compile output with serverName

The compile script still emits --outfile server. For consistency with the dynamic name and downstream scripts, output should match {{serverName}}.

-    "compile": "bun build --compile --minify --sourcemap --bytecode ./src/index.ts --outfile server"
+    "compile": "bun build --compile --minify --sourcemap --bytecode ./src/index.ts --outfile {{serverName}}"

Optional: If you have any scripts referring to the produced binary, update them accordingly.

apps/cli/src/helpers/setup/backend-setup.ts (1)

57-63: Guard addPackageDependency with serverDir existence to avoid failures with dynamic names.

With a configurable serverName, it’s safer to ensure the computed directory exists before mutating dependencies. If addPackageDependency doesn’t create the directory, this can fail in edge cases.

Apply this change at the call site:

-    await addPackageDependency({
-      dependencies,
-      devDependencies,
-      projectDir: serverDir,
-    });
+    if (await fs.pathExists(serverDir)) {
+      await addPackageDependency({
+        dependencies,
+        devDependencies,
+        projectDir: serverDir,
+      });
+    }

And add the import at the top of this file:

import fs from "fs-extra";
apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts (1)

132-171: Variable shadowing of config — rename to avoid confusion and typing hazards

Inside setupMongoDBAtlas, const config = await initMongoDBAtlas(serverDir); shadows the function parameter config: ProjectConfig. This is brittle and confusing.

-export async function setupMongoDBAtlas(config: ProjectConfig) {
-  const { projectDir, serverName } = config;
+export async function setupMongoDBAtlas(config: ProjectConfig) {
+  const { projectDir, serverName } = config;
   const mainSpinner = spinner();
   mainSpinner.start("Setting up MongoDB Atlas...");
 
   const serverDir = path.join(projectDir, "apps", serverName);
   try {
     await fs.ensureDir(serverDir);
 
     mainSpinner.stop("MongoDB Atlas setup ready");
 
-    const config = await initMongoDBAtlas(serverDir);
+    const atlasConfig = await initMongoDBAtlas(serverDir);
 
-    if (config) {
-      await writeEnvFile(projectDir, serverName, config);
+    if (atlasConfig) {
+      await writeEnvFile(projectDir, serverName, atlasConfig);
       log.success(
         pc.green(
           "MongoDB Atlas setup complete! Connection saved to .env file.",
         ),
       );
     } else {
       log.warn(pc.yellow("Falling back to local MongoDB configuration"));
       await writeEnvFile(projectDir, serverName);
       displayManualSetupInstructions();
     }
   } catch (error) {
     mainSpinner.stop(pc.red("MongoDB Atlas setup failed"));
     consola.error(
       pc.red(
         `Error during MongoDB Atlas setup: ${
           error instanceof Error ? error.message : String(error)
         }`,
       ),
     );
 
     try {
       await writeEnvFile(projectDir, serverName);
       displayManualSetupInstructions();
     } catch {}
   }
 }
apps/cli/src/helpers/database-providers/docker-compose-setup.ts (1)

24-31: Ensure target directory exists and guard serverName

Prevent failures when apps/{serverName} isn’t created yet and avoid invalid names creeping into paths.

Apply within this function:

 async function writeEnvFile(
   projectDir: string,
   database: Database,
   projectName: string,
   serverName: string,
 ) {
-  const envPath = path.join(projectDir, "apps", serverName, ".env");
+  const envPath = path.join(projectDir, "apps", serverName, ".env");
+  // Basic sanity check; full validation should live in input/schema
+  if (!serverName || /[\\/]/.test(serverName)) {
+    throw new Error(`Invalid serverName: "${serverName}"`);
+  }
+  // Ensure directory exists to avoid write failures
+  await fs.ensureDir(path.dirname(envPath));
   const variables: EnvVariable[] = [

Add missing import at top of the file:

import fs from "fs-extra";
apps/cli/src/helpers/database-providers/turso-setup.ts (2)

170-189: Ensure env directory exists and validate serverName

Avoid write failures and reject invalid serverName inputs.

 async function writeEnvFile(
   projectDir: string,
   serverName: string,
   config?: TursoConfig,
 ) {
-  const envPath = path.join(projectDir, "apps", serverName, ".env");
+  const envPath = path.join(projectDir, "apps", serverName, ".env");
+  if (!serverName || /[\\/]/.test(serverName)) {
+    throw new Error(`Invalid serverName: "${serverName}"`);
+  }
+  await fs.ensureDir(path.dirname(envPath));
   const variables: EnvVariable[] = [

Add missing import if not present at top:

import fs from "fs-extra";

265-271: Bug: success can be set even when Turso config retrieval fails

createTursoDatabase returns undefined on details retrieval failure; the loop then writes empty env values and marks success=true. Only proceed when config is truthy.

-        const config = await createTursoDatabase(dbName, selectedGroup);
-        await writeEnvFile(projectDir, serverName, config);
-        success = true;
+        const config = await createTursoDatabase(dbName, selectedGroup);
+        if (!config?.dbUrl || !config?.authToken) {
+          throw new Error("TURSO_CONFIG_MISSING");
+        }
+        await writeEnvFile(projectDir, serverName, config);
+        success = true;

Optionally, also throw inside createTursoDatabase when details retrieval fails:

   } catch (_error) {
     s.stop(pc.red("Failed to retrieve database connection details"));
+    throw new Error("TURSO_CONFIG_MISSING");
   }
apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts (2)

151-168: Avoid duplicate dotenv import and handle missing prisma.config.ts gracefully

Currently the code always prepends import "dotenv/config" and assumes prisma.config.ts exists. Two improvements:

  • Prevent duplicate imports if the file already includes dotenv/config.
  • Only attempt this when the file exists (and ideally only when orm === "prisma").

Suggested inline fix:

 async function addDotenvImportToPrismaConfig(
   projectDir: string,
   serverName: string,
 ) {
   try {
     const prismaConfigPath = path.join(
       projectDir,
-      "apps",
-      serverName,
-      "prisma.config.ts",
+      "apps",
+      serverName,
+      "prisma.config.ts",
     );
-    let content = await fs.readFile(prismaConfigPath, "utf8");
-    content = `import "dotenv/config";\n${content}`;
-    await fs.writeFile(prismaConfigPath, content);
+    if (!(await fs.pathExists(prismaConfigPath))) {
+      return;
+    }
+    let content = await fs.readFile(prismaConfigPath, "utf8");
+    if (!content.includes('import "dotenv/config"')) {
+      content = `import "dotenv/config";\n${content}`;
+      await fs.writeFile(prismaConfigPath, content);
+    }
   } catch (_error) {
     consola.error("Failed to update prisma.config.ts");
   }
 }

If preferred, you can also pass orm into this function and early-return when orm !== "prisma".


223-293: Gate Prisma-specific mutations behind orm === "prisma"

addDotenvImportToPrismaConfig is executed regardless of the selected ORM. For Drizzle/Mongoose, this produces unnecessary errors/noise if prisma.config.ts doesn’t exist.

Apply:

-    if (prismaConfig) {
-      await writeEnvFile(projectDir, serverName, prismaConfig);
-
-      await addDotenvImportToPrismaConfig(projectDir, serverName);
-
-      if (orm === "prisma") {
-        await addPrismaAccelerateExtension(serverDir);
-      }
+    if (prismaConfig) {
+      await writeEnvFile(projectDir, serverName, prismaConfig);
+      if (orm === "prisma") {
+        await addDotenvImportToPrismaConfig(projectDir, serverName);
+        await addPrismaAccelerateExtension(serverDir);
+      }
     } else {
       await writeEnvFile(projectDir, serverName);
       displayManualSetupInstructions(serverName);
     }
apps/cli/src/helpers/database-providers/supabase-setup.ts (1)

165-223: Bug: serverDir still hardcoded to "server"

serverDir should use the provided serverName. Otherwise, the Supabase CLI runs in the wrong directory when serverName !== "server".

Fix:

-  const { projectDir, packageManager, serverName } = config;
+  const { projectDir, packageManager, serverName } = config;

-  const serverDir = path.join(projectDir, "apps", "server");
+  const serverDir = path.join(projectDir, "apps", serverName);
🧹 Nitpick comments (15)
.changeset/petite-corners-say.md (1)

1-6: Confirm non-breaking semantics for minor release

If serverName is required on CLI input or templates break when omitted, this should be a major bump. If defaults preserve behavior when unspecified, minor is correct. Please confirm.

apps/cli/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs (1)

5-5: LGTM: dynamic serverName type import is correct; minor consistency note

  • Using import type { AppRouter } from '../../../{{serverName}}/src/routers' is the right pattern for clients.
  • Keeping the import at the directory (without /index) aligns with TS module resolution and avoids path churn.

Optional: ensure ORPC templates use the same pattern (importing a type alias instead of typeof over a type-only import) for consistency.

Also applies to: 50-50, 56-56

apps/cli/src/validation.ts (1)

99-101: Add a small test around serverName flag

Add unit tests for processAndValidateFlags to assert:

  • Valid serverName is accepted and set.
  • Invalid names (e.g., containing slashes or spaces) are rejected with an error.

I can draft the tests if you share the existing test harness for validation.ts.

apps/cli/src/helpers/database-providers/d1-setup.ts (1)

11-11: Optional: derive envPath from a serverDir variable to reduce duplication.

This keeps path construction consistent with other helpers and eases future maintenance.

- const envPath = path.join(projectDir, "apps", serverName, ".env");
+ const serverDir = path.join(projectDir, "apps", serverName);
+ const envPath = path.join(serverDir, ".env");
apps/cli/src/helpers/setup/examples-setup.ts (1)

8-8: Guard against empty/undefined serverName when constructing serverDir

Use a defensive fallback to avoid resolving to apps/ or apps/undefined if serverName is missing.

-    const serverDir = path.join(projectDir, "apps", serverName);
+    const serverDir = path.join(projectDir, "apps", serverName?.trim() || "server");

Also applies to: 22-22

apps/cli/src/helpers/project-generation/create-project.ts (1)

45-53: Passing both serverName and options is redundant

These helpers can read serverName from options. Passing it twice increases the chance of drift.

  • Prefer a consistent convention: either pass a single options bag everywhere or consistently pass decomposed arguments. If you opt for the former, remove the serverName positional arg and read from options.serverName inside those helpers (less surface area to update later).
apps/cli/src/helpers/project-generation/command-handlers.ts (1)

62-66: Ensure projectDirectory is correct and serverName is propagated

  • Good: serverName is forwarded into cliInput.
  • Potential issue: projectDirectory is set to input.projectName. That looks wrong; most flows expect a resolved path (e.g., finalResolvedPath). If this value is used downstream (e.g., flag processing), it might cause confusion.
-const cliInput = {
-  ...input,
-  projectDirectory: input.projectName,
-  serverName: input.serverName,
-};
+const cliInput = {
+  ...input,
+  projectDirectory: finalResolvedPath,
+  serverName: input.serverName,
+};
apps/cli/src/helpers/setup/db-setup.ts (1)

30-33: Minor: avoid recomputing serverDir

You compute serverDir twice. Compute once near the top for clarity.

-const s = spinner();
-const serverDir = path.join(projectDir, "apps", serverName);
+const s = spinner();
+const serverDir = path.join(projectDir, "apps", serverName);

Then reuse serverDir above where needed (remove the earlier duplicate).

apps/cli/src/helpers/setup/runtime-setup.ts (1)

57-60: Nit: quote path in manual command for safety

Quoting protects paths when serverName contains spaces or special chars.

-      `Note: You can manually run 'cd apps/${serverName} && ${managerCmd} cf-typegen' in the project directory later`,
+      `Note: You can manually run 'cd "apps/${serverName}" && ${managerCmd} cf-typegen' in the project directory later`,
apps/cli/src/helpers/database-providers/turso-setup.ts (1)

191-201: Nit: quote the .env path in manual instructions

Improves readability and safety for atypical names.

-4. Add these credentials to the .env file in apps/${serverName}/.env
+4. Add these credentials to the .env file in "apps/${serverName}/.env"
apps/cli/src/helpers/project-generation/project-config.ts (1)

70-71: Add backward-compatible alias script dev:server

Keeps existing docs/automation working while enabling dev:${serverName}.

   scripts[`dev:${options.serverName}`] = serverDevScript;
+  if (options.serverName !== "server") {
+    scripts["dev:server"] = serverDevScript;
+  }

Apply at each package-manager/turborepo block where dev:${options.serverName} is set.

Also applies to: 97-98, 129-130, 163-164

apps/cli/src/helpers/project-generation/post-installation.ts (2)

127-130: Nit: quote path in cf-typegen step

Handles spaces or unusual names safely.

-)} cd apps/${serverName} && ${runCmd} run cf-typegen\n\n`;
+)} cd "apps/${serverName}" && ${runCmd} run cf-typegen\n\n`;

299-301: Nit: quote path in local DB command

Minor readability and safety improvement.

-      )} Start local DB (if needed): ${`cd apps/${serverName} && ${runCmd} db:local`}`,
+      )} Start local DB (if needed): ${`cd "apps/${serverName}" && ${runCmd} db:local`}`,
apps/cli/src/helpers/database-providers/supabase-setup.ts (1)

142-162: Minor: remove stray double quotes in the heading

The heading string includes quotes, which render oddly in console logs.

-  `"Manual Supabase Setup Instructions:"
+  `Manual Supabase Setup Instructions:
apps/cli/src/helpers/project-generation/template-manager.ts (1)

243-251: Avoid duplicating serverName in both params and context

These functions now take serverName while context already includes serverName. Two sources of truth increase the risk of mismatch and propagate signature churn.

Prefer deriving serverName from context within each function:

-export async function setupBackendFramework(
-  projectDir: string,
-  serverName: string,
-  context: ProjectConfig,
-) {
+export async function setupBackendFramework(
+  projectDir: string,
+  context: ProjectConfig,
+) {
+  const { serverName } = context;

Do similarly for setupDbOrmTemplates, setupAuthTemplate, setupExamplesTemplate, and setupDockerComposeTemplates. This reduces boilerplate and ensures consistency.

Also applies to: 333-337, 359-367, 572-586, 829-839

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6cf5c9 and 280e377.

📒 Files selected for processing (50)
  • .changeset/petite-corners-say.md (1 hunks)
  • apps/cli/src/constants.ts (1 hunks)
  • apps/cli/src/helpers/database-providers/d1-setup.ts (1 hunks)
  • apps/cli/src/helpers/database-providers/docker-compose-setup.ts (2 hunks)
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts (4 hunks)
  • apps/cli/src/helpers/database-providers/neon-setup.ts (6 hunks)
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts (7 hunks)
  • apps/cli/src/helpers/database-providers/supabase-setup.ts (5 hunks)
  • apps/cli/src/helpers/database-providers/turso-setup.ts (6 hunks)
  • apps/cli/src/helpers/project-generation/command-handlers.ts (3 hunks)
  • apps/cli/src/helpers/project-generation/create-project.ts (1 hunks)
  • apps/cli/src/helpers/project-generation/create-readme.ts (14 hunks)
  • apps/cli/src/helpers/project-generation/env-setup.ts (2 hunks)
  • apps/cli/src/helpers/project-generation/post-installation.ts (6 hunks)
  • apps/cli/src/helpers/project-generation/project-config.ts (6 hunks)
  • apps/cli/src/helpers/project-generation/template-manager.ts (7 hunks)
  • apps/cli/src/helpers/setup/api-setup.ts (2 hunks)
  • apps/cli/src/helpers/setup/auth-setup.ts (1 hunks)
  • apps/cli/src/helpers/setup/backend-setup.ts (1 hunks)
  • apps/cli/src/helpers/setup/db-setup.ts (2 hunks)
  • apps/cli/src/helpers/setup/examples-setup.ts (2 hunks)
  • apps/cli/src/helpers/setup/runtime-setup.ts (4 hunks)
  • apps/cli/src/index.ts (1 hunks)
  • apps/cli/src/prompts/config-prompts.ts (2 hunks)
  • apps/cli/src/types.ts (2 hunks)
  • apps/cli/src/utils/display-config.ts (1 hunks)
  • apps/cli/src/utils/generate-reproducible-command.ts (1 hunks)
  • apps/cli/src/validation.ts (1 hunks)
  • apps/cli/templates/addons/vibe-rules/.bts/rules.md.hbs (5 hunks)
  • apps/cli/templates/api/orpc/native/utils/orpc.ts.hbs (1 hunks)
  • apps/cli/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs (1 hunks)
  • apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs (1 hunks)
  • apps/cli/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs (1 hunks)
  • apps/cli/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs (1 hunks)
  • apps/cli/templates/api/trpc/native/utils/trpc.ts.hbs (1 hunks)
  • apps/cli/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs (2 hunks)
  • apps/cli/templates/backend/server/next/package.json.hbs (1 hunks)
  • apps/cli/templates/backend/server/server-base/package.json.hbs (1 hunks)
  • apps/cli/templates/frontend/native/nativewind/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/native/unistyles/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/nuxt/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/react/next/tsconfig.json.hbs (2 hunks)
  • apps/cli/templates/frontend/react/react-router/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/react/tanstack-router/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs (1 hunks)
  • apps/cli/templates/frontend/react/tanstack-start/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/solid/tsconfig.json.hbs (1 hunks)
  • apps/cli/templates/frontend/svelte/tsconfig.json.hbs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
apps/cli/src/helpers/project-generation/command-handlers.ts (1)
apps/cli/src/types.ts (1)
  • CreateInput (111-128)
apps/cli/src/helpers/database-providers/supabase-setup.ts (1)
apps/cli/src/types.ts (1)
  • ProjectConfig (143-162)
apps/cli/src/helpers/project-generation/template-manager.ts (1)
apps/cli/src/types.ts (1)
  • ProjectConfig (143-162)
🔇 Additional comments (42)
apps/cli/src/constants.ts (2)

28-28: Good default for serverName

Adding serverName: "server" to DEFAULT_CONFIG is the right baseline for back-compat and UX.


28-28: No lingering hardcoded “server” paths in runtime code
All matches are confined to documentation (apps/web/content/docs/*.mdx) and CLI scaffolding templates (apps/cli/templates/**/*.hbs, template-manager.ts). These internal references drive project generation and docs— they don’t affect the dynamic serverName constant or runtime paths.
No further action required.

apps/cli/src/types.ts (1)

161-162: ProjectConfig: serverName inclusion looks good

Including serverName on ProjectConfig is necessary for downstream helpers/templates.

apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs (1)

20-21: LGTM: Type-only import and tsconfig configuration are correct

  • The import type { AppRouter } from "../../{{serverName}}/src/routers"; change avoids bundling server code while still providing type safety.
  • The tsconfig.json.hbs for frontend/react/tanstack-start includes both:
    • "paths": { "@/*": ["./src/*"] }
    • "references": [{ "path": "../{{serverName}}" }]
  • A search across all CLI templates found no remaining hardcoded ../../server/ imports.

These updates ensure proper type resolution in editors and CI without pulling in server runtime.

apps/cli/templates/frontend/nuxt/tsconfig.json.hbs (1)

16-21: Server tsconfig “composite” flag confirmed

The dynamic ../{{serverName}} reference in apps/cli/templates/frontend/nuxt/tsconfig.json.hbs is correctly guarded by unless (convex|none), and we’ve verified that every server tsconfig.json.hbs under apps/cli/templates/backend/server includes "composite": true. No further changes needed.

apps/cli/templates/api/orpc/native/utils/orpc.ts.hbs (1)

6-6: Good: import path parameterized with serverName

The type-only import to ../../{{serverName}}/src/routers aligns with the dynamic server name and keeps bundling type-only. LGTM.

apps/cli/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs (1)

12-12: Good: dynamic router type import

Switching ../../../server/... to ../../../{{serverName}}/... is consistent with the PR goal and correctly scoped under the ORPC branch. Looks good.

apps/cli/templates/frontend/react/react-router/tsconfig.json.hbs (1)

29-29: Server tsconfig templates include "composite": true

Both backend server templates already enable project references:

  • apps/cli/templates/backend/server/next/tsconfig.json.hbs (line 16)
  • apps/cli/templates/backend/server/server-base/tsconfig.json.hbs (line 31)

No further changes needed—the path: "../{{serverName}}" in the React-Router frontend tsconfig will resolve without errors.

apps/cli/templates/frontend/solid/tsconfig.json.hbs (1)

31-31: Composite setting verified in server TSConfig templates

I checked the apps/cli/templates/backend/server/*/tsconfig.json.hbs files and confirmed they all include "composite": true. No changes are needed here—your project reference will work as expected.

apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs (2)

6-6: LGTM: dynamic serverName path

Using {{serverName}} in the type-only import is correct and keeps runtime bundles clean.


6-6: No hardcoded ‘server’ paths remain in templates
I searched for /server/src/routers and "../server" under apps/cli/templates and found no occurrences—templates are clean.

apps/cli/templates/api/trpc/native/utils/trpc.ts.hbs (1)

7-7: LGTM: type-only import uses {{serverName}}

Path parametrization is correct and remains type-only, so it won’t affect runtime bundling.

apps/cli/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs (1)

3-3: LGTM: Nuxt ORPC type import updated

Dynamic {{serverName}} path aligns with the rest of the templates.

apps/cli/templates/frontend/native/unistyles/tsconfig.json.hbs (1)

14-15: LGTM: TS project reference updated

Using ../{{serverName}} keeps native TS project references aligned with the configurable server directory.

apps/cli/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs (1)

31-31: LGTM: dynamic import path matches serverName

The switch to "../../../{{serverName}}/src/routers" aligns with the dynamic server name goal and the tsconfig project references.

Ensure serverName is a valid folder segment (no spaces or special chars) to keep this import resolvable. Combined with the tsconfig "references" change, types should resolve across packages.

apps/cli/templates/frontend/react/next/tsconfig.json.hbs (1)

32-33: Template now respects serverName in include and references — looks good.

Paths will resolve relative to the web app as before, now parameterized by {{serverName}}.

Also applies to: 41-42

apps/cli/src/helpers/database-providers/d1-setup.ts (1)

9-9: .env path uses serverName — correct and consistent with PR intent.

Also applies to: 11-11

apps/cli/src/helpers/setup/backend-setup.ts (1)

7-7: Using serverName in serverDir is correct and aligns with the new config.

Also applies to: 14-14

apps/cli/src/helpers/setup/api-setup.ts (2)

8-16: LGTM: serverDir now derived from serverName with existence check before use.

The dynamic path and fs.pathExists check mitigate errors when the server app name is customized.

Also applies to: 31-31


8-16: Confirm package naming expectations with dynamic serverName.

Elsewhere in this file, the workspace dependency name is computed as @${projectName}/backend. If the folder name is now dynamic (serverName), confirm whether the package name should remain backend by design (folder and package can differ) or follow serverName.

apps/cli/src/prompts/config-prompts.ts (1)

53-53: No serverName parameter in gatherConfig—original comment not applicable
The current signature of gatherConfig in apps/cli/src/prompts/config-prompts.ts is:

export async function gatherConfig(
  flags: Partial<ProjectConfig>,
  projectName: string,
  projectDir: string,
) {  }

All call sites (e.g. in apps/cli/src/helpers/project-generation/command-handlers.ts) use exactly these three arguments, so there is no breaking positional change and no serverName parameter to default. You can ignore the suggestion to add a serverName default here.

Likely an incorrect or invalid review comment.

apps/cli/templates/frontend/react/tanstack-router/tsconfig.json.hbs (1)

20-20: LGTM: dynamic reference to serverName is correct and gated

Using "../{{serverName}}" under {{#unless (or (eq backend "convex") (eq backend "none"))}} is correct and prevents invalid references when no backend is generated.

apps/cli/src/helpers/project-generation/command-handlers.ts (2)

108-114: gatherConfig signature and call-site alignment confirmed

The invocation in apps/cli/src/helpers/project-generation/command-handlers.ts matches the updated signature in apps/cli/src/prompts/config-prompts.ts (flags, projectName, projectDir, serverName, relativePath). No further changes needed.


28-29: serverName integration verified – please confirm CLI validation

  • ProjectConfig includes serverName (line 161 in apps/cli/src/types.ts).
  • DEFAULT_CONFIG provides serverName: "server" (line 28 in apps/cli/src/constants.ts).
  • The handler’s input type extends CreateInput & { serverName: string } inline—consider consolidating this in CreateInput or reusing CLIInput for consistency.
  • No changes detected in prompt/validation logic for serverName—ensure any interactive flows or schema validations set and validate this new field.
apps/cli/templates/addons/vibe-rules/.bts/rules.md.hbs (3)

19-22: Docs updated to dynamic apps/{{serverName}}/ — looks good

Paths render correctly for different backends.


51-65: DB paths reflect {{serverName}} — looks consistent across ORMs


71-77: API paths reflect {{serverName}} — looks consistent

apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts (1)

89-96: Dynamic .env path — good

Using apps/{serverName}/.env aligns with the rest of the refactor.

apps/cli/src/helpers/database-providers/docker-compose-setup.ts (1)

30-31: LGTM: dynamic env path uses serverName correctly

apps/{serverName}/.env is constructed properly and aligns with the PR goal.

apps/cli/src/helpers/setup/runtime-setup.ts (1)

16-17: LGTM: serverDir now respects serverName

Dynamic pathing is correct for both setupRuntime and generateCloudflareWorkerTypes.

Also applies to: 37-38

apps/cli/src/helpers/project-generation/project-config.ts (2)

230-234: LGTM: dynamic path to server package.json

apps/${options.serverName}/package.json resolves correctly.


34-38: Confirm generated server package.json name aligns with serverName

I didn’t find a dedicated package.json template under the project-generation helpers, so please verify that your scaffolding logic writes the "name" field in apps/${serverName}/package.json exactly as options.serverName. This is critical for workspace filters (e.g. --filter ${serverName}) and script shortcuts (e.g. dev:${serverName}) to work reliably.

• Check under apps/cli/src/helpers/project-generation (especially in template-manager.ts or any template files) that the generated package.json uses
"name": "${serverName}"
• Update your template or inline generator if it’s still hardcoded or missing this placeholder

apps/cli/src/helpers/project-generation/post-installation.ts (1)

39-47: LGTM: database instruction helper now receives serverName

Propagating serverName enables correct, dynamic paths in guidance.

apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts (2)

129-149: Env path correctly parameterized with serverName

apps/${serverName}/.env resolution is correct. No functional concerns.


170-179: Instructions correctly reflect dynamic serverName

The manual setup path uses apps/${serverName}/.env; looks good.

apps/cli/src/helpers/database-providers/supabase-setup.ts (1)

14-44: Env path parameterization looks good

apps/${serverName}/.env path and variable handling are correct. Good error reporting.

apps/cli/src/helpers/database-providers/neon-setup.ts (3)

103-121: Env writing with serverName is correct

apps/${serverName}/.env is resolved properly and values are sensible defaults.


123-152: Neon quick-setup uses serverName directory correctly

Good: neondb runs with cwd set to apps/${serverName}.


165-236: Good parameterization and fallback flow

Destructuring serverName and usage across branches look correct. The fallback to write .env and show manual instructions is appropriate.

apps/cli/src/helpers/project-generation/create-readme.ts (3)

30-31: Dynamic serverName wiring in README content looks consistent

serverName is correctly destructured and passed into database setup, project structure, and scripts sections. Good coverage.

Also applies to: 101-109, 128-137, 149-150


255-256: Project structure correctly reflects dynamic backend folder name

The backend app folder is shown as apps/${serverName}/ with descriptive comment. Looks good.

Also applies to: 324-327


479-486: Database setup section correctly parameterized

Commands and .env paths use apps/${serverName}. Good clarity for users across SQLite/Postgres/MySQL/MongoDB.

Also applies to: 507-513, 525-525, 537-537, 549-549

Comment on lines +9 to 10
const { database, projectDir, projectName, serverName } = config;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify serverName is validated by the CLI schema

To avoid path traversal or invalid script keys elsewhere, ensure serverName is constrained (e.g., /^[a-z0-9_-]+$/i).

Also applies to: 28-31


🏁 Script executed:

#!/bin/bash
# Search for serverName validation in Zod schemas/types and prompt files
rg -n --no-heading "serverName" -A 6 -B 6 apps/cli/src | sed -n '1,200p'

Length of output: 12769


Add regex validation for serverName in the CLI input schema

The CLI currently accepts any string for serverName (see apps/cli/src/index.ts:61), so path traversal or invalid folder names aren’t prevented. We should constrain it to alphanumeric, hyphens, and underscores:

• In apps/cli/src/index.ts, update the input schema:

--- a/apps/cli/src/index.ts
+++ b/apps/cli/src/index.ts
@@ input: {
-  serverName: z.string().default("server"),
+  serverName: z.string()
+    .regex(/^[a-z0-9_-]+$/i, {
+      message: "serverName may only contain letters, numbers, hyphens, or underscores",
+    })
+    .default("server"),

This ensures any downstream uses—including docker‐compose setups—receive a safe, validated serverName.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/cli/src/index.ts around line 61, the CLI input schema for serverName
currently allows any string, which risks path traversal or invalid folder names.
Update the input schema to add a regex validation that restricts serverName to
only alphanumeric characters, hyphens, and underscores. This will ensure that
all downstream uses, including in
apps/cli/src/helpers/database-providers/docker-compose-setup.ts, receive a
validated and safe serverName value.

Comment on lines +154 to 163
function displayManualSetupInstructions(serverName: string) {
log.info(`Manual Neon PostgreSQL Setup Instructions:
1. Visit https://neon.tech and create an account
2. Create a new project from the dashboard
3. Get your connection string
4. Add the database URL to the .env file in apps/server/.env
4. Add the database URL to the .env file in apps/${serverName}}/.env
DATABASE_URL="your_connection_string"`);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Typo in manual instruction path (extra curly brace)

There’s an extra closing brace in the path, resulting in apps/${serverName}}/.env.

Apply:

-4. Add the database URL to the .env file in apps/${serverName}}/.env
+4. Add the database URL to the .env file in apps/${serverName}/.env
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function displayManualSetupInstructions(serverName: string) {
log.info(`Manual Neon PostgreSQL Setup Instructions:
1. Visit https://neon.tech and create an account
2. Create a new project from the dashboard
3. Get your connection string
4. Add the database URL to the .env file in apps/server/.env
4. Add the database URL to the .env file in apps/${serverName}}/.env
DATABASE_URL="your_connection_string"`);
}
function displayManualSetupInstructions(serverName: string) {
log.info(`Manual Neon PostgreSQL Setup Instructions:
1. Visit https://neon.tech and create an account
2. Create a new project from the dashboard
3. Get your connection string
4. Add the database URL to the .env file in apps/${serverName}/.env
DATABASE_URL="your_connection_string"`);
}
🤖 Prompt for AI Agents
In apps/cli/src/helpers/database-providers/neon-setup.ts around lines 154 to
163, there is an extra closing curly brace in the template string for the path
apps/${serverName}}/.env. Remove the extra closing brace so the path correctly
reads apps/${serverName}/.env.

Comment on lines +28 to 29
input: CreateInput & { projectName?: string; serverName: string },
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Validate serverName for filesystem/workspace safety

Enforce a conservative pattern (letters, numbers, dashes) and disallow spaces/slashes to prevent invalid directory/workspace/script keys.

Example (centralize in validation):

const valid = /^[a-z0-9][a-z0-9-]*$/i.test(input.serverName);
if (!valid) {
  exitWithError("serverName must match /^[a-z0-9][a-z0-9-]*$/i");
}
🤖 Prompt for AI Agents
In apps/cli/src/helpers/project-generation/command-handlers.ts around lines 28
to 29, the serverName input is not validated for safe filesystem and workspace
usage. Add a validation step that checks serverName against a regex pattern
allowing only letters, numbers, and dashes, disallowing spaces and slashes. If
the validation fails, immediately exit with an error message indicating the
allowed pattern. Centralize this validation logic for reuse if possible.

Comment on lines +37 to +38
const { backend, projectDir, serverName } = options;
const isConvex = backend === "convex";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Default serverName to avoid apps/undefined paths

If serverName is missing from options, path joins will resolve to apps/undefined. Add a safe default.

-export async function createProject(options: ProjectConfig) {
-  const { backend, projectDir, serverName } = options;
+export async function createProject(options: ProjectConfig) {
+  const { backend, projectDir, serverName = "server" } = options;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { backend, projectDir, serverName } = options;
const isConvex = backend === "convex";
export async function createProject(options: ProjectConfig) {
const { backend, projectDir, serverName = "server" } = options;
const isConvex = backend === "convex";
🤖 Prompt for AI Agents
In apps/cli/src/helpers/project-generation/create-project.ts around lines 37 to
38, the variable serverName is destructured from options without a default,
which can cause path joins to use 'undefined' if serverName is missing. Fix this
by assigning a safe default value to serverName during destructuring, such as an
empty string or a meaningful default name, to prevent invalid paths like
'apps/undefined'.

Comment on lines +582 to 583
serverName: string,
): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify dev:${serverName} script exists across templates

The README references a dynamic script name dev:${serverName} and a local DB command under apps/${serverName}. Ensure template package.json files define these script keys dynamically (no lingering dev:server).

Run this script to check for any hardcoded dev:server remnants and presence of dynamic placeholders:

Also applies to: 598-599, 616-616


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for hardcoded dev:server scripts (should be none):"
rg -n --hidden -S 'dev:server' apps/cli/templates || true

echo
echo "Searching for dynamic dev scripts using serverName placeholder:"
rg -n --hidden -S 'dev:{{serverName}}' apps/cli/templates || true

echo
echo "Searching for hardcoded apps/server paths (should be replaced):"
rg -n --hidden -S 'apps/server' apps/cli | sed -n '1,200p' || true

Length of output: 734


To be sure the placeholder really exists in your templates, let’s search with a fixed‐string (no regex) for both the full and generic placeholder patterns:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for literal dynamic dev script placeholder 'dev:{{serverName}}':"
rg -n -F 'dev:{{serverName}}' apps/cli/templates || true

echo
echo "Searching for any dev:{{…}} placeholder in templates:"
rg -n -F 'dev:{{' apps/cli/templates || true

Length of output: 413


Add dynamic dev:${serverName} script entries to your templates

Our searches didn’t find any dev:{{serverName}} placeholders nor hard-coded dev:server scripts in apps/cli/templates. You’ll need to update your package.json templates to include the dynamic script name and replace any lingering apps/server paths:

• In apps/cli/templates//package.json
– Under "scripts", add something like
"dev:{{serverName}}": "cd apps/{{serverName}} && npm run dev"
• In apps/cli/templates/
/README.md (if it references dev:${serverName})
• Replace any hard-coded apps/server occurrences with apps/{{serverName}}

🤖 Prompt for AI Agents
In apps/cli/src/helpers/project-generation/create-readme.ts around lines 582 to
583, update the package.json templates in apps/cli/templates to include a
dynamic script entry named dev:${serverName} under the "scripts" section, with
the command "cd apps/${serverName} && npm run dev". Also, check README.md files
in the templates for any references to dev:${serverName} and update them
accordingly. Finally, replace any hard-coded paths like apps/server with
apps/${serverName} to ensure all references are dynamic and consistent.

@@ -4,7 +4,7 @@ import { RPCLink } from "@orpc/client/fetch";
import type { RouterClient } from "@orpc/server";
import { createTanstackQueryUtils } from "@orpc/tanstack-query";
import { QueryCache, QueryClient } from "@tanstack/svelte-query";
import type { appRouter } from "../../../server/src/routers/index";
import type { appRouter } from "../../../{{serverName}}/src/routers/index";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Fix: import type + typeof appRouter is invalid; switch to a proper exported type alias or use a value import

Current pattern imports type { appRouter } and then uses typeof appRouter in a generic. This will fail compilation (appRouter cannot be used as a value because it was imported using 'import type'). Using a non-type import risks bundling server code into the client (esp. with verbatimModuleSyntax: true).

Recommended (safe) approach: export a type alias from the server and consume that type here.

  • In the server routers module, ensure you export:
    export type AppRouter = typeof appRouter

  • Then update this template as follows:

-import type { appRouter } from "../../../{{serverName}}/src/routers/index";
+import type { AppRouter } from "../../../{{serverName}}/src/routers";

And update the client type usage:

-export const client: RouterClient<typeof appRouter> = createORPCClient(link);
+export const client: RouterClient<AppRouter> = createORPCClient(link);

Notes:

  • Drop the explicit /index for consistency with other templates importing from /src/routers.
  • If you cannot add the AppRouter export server-side, fallback is to import the value (riskier for bundling):
-import type { appRouter } from "../../../{{serverName}}/src/routers/index";
+import { appRouter } from "../../../{{serverName}}/src/routers";

…but this may be retained at runtime and break in the browser if verbatimModuleSyntax is enabled.

Run to verify the server exports the type alias:

I can prep a small patch to add/export AppRouter in the server router template if it’s not there yet.

Also applies to: 29-29


🏁 Script executed:

#!/bin/bash
# Expect at least one export of AppRouter type somewhere under templates or server package
rg -n -S $'export type AppRouter\\s*=\\s*typeof\\s+appRouter' || true
# Also confirm appRouter is exported
rg -n -S $'export\\s+(const|let|var)\\s+appRouter\\b' || true

Length of output: 770


Use the exported AppRouter type alias instead of importing appRouter with typeof

The server‐side routers template (apps/cli/templates/backend/server/server-base/src/routers/index.ts) already includes:

export const appRouter =   
export type AppRouter = typeof appRouter;

so you can import AppRouter directly and avoid the invalid import type { appRouter } + typeof appRouter pattern.

Apps/cli/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs:

  • Line 7: replace the type import of appRouter with AppRouter
  • Line 29: use AppRouter in the RouterClient generic
--- a/apps/cli/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs
+++ b/apps/cli/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs
@@ -7,7 +7,7 @@
- import type { appRouter } from "../../../{{serverName}}/src/routers/index";
+ import type { AppRouter } from "../../../{{serverName}}/src/routers";

 // …later in the file…
-export const client: RouterClient<typeof appRouter> = createORPCClient(link);
+export const client: RouterClient<AppRouter>         = createORPCClient(link);

This ensures the import is purely a type and compiles correctly without pulling server code into the client bundle.

🤖 Prompt for AI Agents
In apps/cli/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs at line 7, replace
the import of the runtime `appRouter` with the type alias `AppRouter` imported
directly from the server router index file. Then at line 29, update the generic
type parameter of `RouterClient` to use `AppRouter` instead of `typeof
appRouter`. This change ensures only the type is imported, preventing server
code from being bundled into the client.

@@ -1,5 +1,5 @@
{
"name": "server",
"name": "{{serverName}}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ensure serverName is a valid npm package name

"name": "{{serverName}}" is correct, but invalid names (spaces/uppercase/special chars) will break npm/yarn. Enforce/normalize at input time.

  • If not already, sanitize in CLI using validate-npm-package-name or slugify helpers.
  • Quick scan:

🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "validate-npm-package-name|normalize-npm-package-name|slugify|kebabCase|paramCase" apps/cli/src || echo "No obvious package-name validation found."

Length of output: 216


Add npm package name validation for serverName
Invalid package names (spaces, uppercase letters, special characters) will break npm/yarn. We need to enforce or normalize serverName at input time in the CLI.

  • Where to fix

    • apps/cli/src/commands/init (or wherever you prompt for serverName)
    • apps/cli/templates/backend/server/next/package.json.hbs (uses {{serverName}})
  • What to do

    1. Install and import a validator/slugifier, e.g.:
      npm install --save validate-npm-package-name slugify
    2. In your prompt handler, after reading the raw name:
      import validate from 'validate-npm-package-name';
      import slugify from 'slugify';
      
      const rawName = await prompt('Server name:');
      const normalized = slugify(rawName, { lower: true, strict: true });
      const { validForNewPackages } = validate(normalized);
      
      if (!validForNewPackages) {
        throw new Error(
          `'${rawName}' is not a valid npm package name. Please use letters, numbers, dashes only.`
        );
      }
      // pass `normalized` into the template context as serverName
    3. Update the template context to use this sanitized serverName.

This guarantees that the generated package.json always has a valid "name": "{{serverName}}".

🤖 Prompt for AI Agents
In apps/cli/templates/backend/server/next/package.json.hbs at line 2, the
serverName used as the npm package name is not validated, which can cause issues
with invalid names. To fix this, add npm package name validation and
normalization in the CLI prompt code (e.g., apps/cli/src/commands/init). Install
and import 'validate-npm-package-name' and 'slugify', then after reading the raw
serverName input, normalize it using slugify with lowercase and strict options,
validate it with validate-npm-package-name, and if invalid, throw an error.
Finally, pass the sanitized serverName into the template context so the
package.json always has a valid name field.

Comment on lines 18 to 22
{{#unless (or (eq backend "convex") (eq backend "none"))}}
"references": [{
"path": "../server"
"path": "../{{serverName}}"
}]
{{/unless}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Prevent dangling comma when the block is omitted; always emit a references array

With the current placement, if backend is "convex" or "none", this conditional block is not rendered and the trailing comma after "include" remains, potentially producing invalid JSON for some parsers. Safer to always emit "references": [] and conditionally insert the entry.

Apply:

-  {{#unless (or (eq backend "convex") (eq backend "none"))}}
-  "references": [{
-    "path": "../{{serverName}}"
-  }]
-  {{/unless}}
+  "references": [
+    {{#unless (or (eq backend "convex") (eq backend "none"))}}
+    { "path": "../{{serverName}}" }
+    {{/unless}}
+  ]

Verification suggestion:

  • Generate this template with backend=convex and backend=none to confirm no trailing comma remains and the file parses in TS/Expo toolchains.

🏁 Script executed:

#!/bin/bash
set -e

# Locate the tsconfig.json.hbs template
FILE=$(fd tsconfig.json.hbs -t f)

echo "Found file: $FILE"
echo "----- Content around lines 1-50 -----"
sed -n '1,50p' "$FILE"
echo "------------------------------------"

Length of output: 3529


🏁 Script executed:

#!/bin/bash
# Print the first 200 lines of the nativewind tsconfig template for inspection
sed -n '1,200p' apps/cli/templates/frontend/native/nativewind/tsconfig.json.hbs

Length of output: 480


Wrap the references field in an array to avoid a dangling comma in tsconfig.json

To guarantee valid JSONC when the block is omitted, always emit a references array and conditionally include its entry.

• File needing update:
– apps/cli/templates/frontend/native/nativewind/tsconfig.json.hbs

Apply this diff:

   "include": [
     "**/*.ts",
     "**/*.tsx",
     ".expo/types/**/*.ts",
     "expo-env.d.ts",
     "nativewind-env.d.ts"
-  ],
-  {{#unless (or (eq backend "convex") (eq backend "none"))}}
-  "references": [{
-    "path": "../{{serverName}}"
-  }]
-  {{/unless}}
+  ],
+  "references": [
+    {{#unless (or (eq backend "convex") (eq backend "none"))}}
+    { "path": "../{{serverName}}" }
+    {{/unless}}
+  ]
 }

Verification suggestion: generate this template with backend="convex" and backend="none" and confirm the output parses cleanly in both the TypeScript and Expo toolchains.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{#unless (or (eq backend "convex") (eq backend "none"))}}
"references": [{
"path": "../server"
"path": "../{{serverName}}"
}]
{{/unless}}
"include": [
"**/*.ts",
"**/*.tsx",
".expo/types/**/*.ts",
"expo-env.d.ts",
"nativewind-env.d.ts"
],
"references": [
{{#unless (or (eq backend "convex") (eq backend "none"))}}
{ "path": "../{{serverName}}" }
{{/unless}}
]
}
🤖 Prompt for AI Agents
In apps/cli/templates/frontend/native/nativewind/tsconfig.json.hbs around lines
18 to 22, the references field is conditionally included without always wrapping
it in an array, which can cause a dangling comma and invalid JSONC. To fix this,
always emit the references field as an array and conditionally include the path
entry inside it only when backend is not "convex" or "none". This ensures valid
JSONC output regardless of the backend value.

Comment on lines 28 to 32
{{#unless (or (eq backend "convex") (eq backend "none"))}}
"references": [{
"path": "../server"
"path": "../{{serverName}}"
}]
{{/unless}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Avoid dangling comma; always include "references" as an array

If the conditional doesn't render, the comma after "compilerOptions" becomes trailing. Emit an empty references array and conditionally add the project path.

-  {{#unless (or (eq backend "convex") (eq backend "none"))}}
-  "references": [{
-    "path": "../{{serverName}}"
-  }]
-  {{/unless}}
+  "references": [
+    {{#unless (or (eq backend "convex") (eq backend "none"))}}
+    { "path": "../{{serverName}}" }
+    {{/unless}}
+  ]

Also confirm the path "../{{serverName}}" points at the server project's tsconfig.json (project references expect the referenced project's tsconfig location).


🏁 Script executed:

#!/bin/bash
# Locate the tsconfig.json.hbs template
fd tsconfig.json.hbs -t f

# Show surrounding lines for compilerOptions and references
rg -n 'compilerOptions' -A5 -B5 apps/cli/templates/frontend/react/tanstack-start/tsconfig.json.hbs
rg -n 'references' -A5 -B5 apps/cli/templates/frontend/react/tanstack-start/tsconfig.json.hbs

Length of output: 1322


Always emit an empty references array to avoid trailing‐comma errors
When the {{#unless…}} block doesn’t render, the comma after compilerOptions becomes dangling and produces invalid JSON. Wrapping the entire references array around the conditional guarantees valid output.

• File to update:
apps/cli/templates/frontend/react/tanstack-start/tsconfig.json.hbs

• Replace lines 28–32 with:

-  {{#unless (or (eq backend "convex") (eq backend "none"))}}
-  "references": [{
-    "path": "../{{serverName}}"
-  }]
-  {{/unless}}
+  "references": [
+    {{#unless (or (eq backend "convex") (eq backend "none"))}}
+    { "path": "../{{serverName}}" }
+    {{/unless}}
+  ]

• Verify that ../{{serverName}} correctly points at the generated server project’s tsconfig.json (project references resolve to the referenced tsconfig location).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{#unless (or (eq backend "convex") (eq backend "none"))}}
"references": [{
"path": "../server"
"path": "../{{serverName}}"
}]
{{/unless}}
"references": [
{{#unless (or (eq backend "convex") (eq backend "none"))}}
{ "path": "../{{serverName}}" }
{{/unless}}
]
🤖 Prompt for AI Agents
In apps/cli/templates/frontend/react/tanstack-start/tsconfig.json.hbs around
lines 28 to 32, always emit the "references" array even if empty to prevent
trailing comma errors in JSON. Wrap the entire "references" array in the
conditional block so it outputs either an empty array or an array with the
server path. Also verify that "../{{serverName}}" correctly points to the server
project's tsconfig.json for proper project reference resolution.

Comment on lines 13 to 18
},
{{#unless (or (eq backend "convex") (eq backend "none"))}}
"references": [{
"path": "../server"
"path": "../{{serverName}}"
}]
{{/unless}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bug: trailing comma renders invalid JSON when the block is omitted

The comma after "compilerOptions" makes the file invalid JSON when backend is convex/none (the conditional references block is removed). Move the comma into the conditional.

Apply:

-  },
-      {{#unless (or (eq backend "convex") (eq backend "none"))}}
-  "references": [{
+  }
+  {{#unless (or (eq backend "convex") (eq backend "none"))}}
+  ,
+  "references": [{
     "path": "../{{serverName}}"
   }]
-  {{/unless}}
+  {{/unless}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
},
{{#unless (or (eq backend "convex") (eq backend "none"))}}
"references": [{
"path": "../server"
"path": "../{{serverName}}"
}]
{{/unless}}
}
{{#unless (or (eq backend "convex") (eq backend "none"))}}
,
"references": [{
"path": "../{{serverName}}"
}]
{{/unless}}
🤖 Prompt for AI Agents
In apps/cli/templates/frontend/svelte/tsconfig.json.hbs around lines 13 to 18,
the comma after "compilerOptions" causes invalid JSON when the conditional
"references" block is omitted for backend values "convex" or "none". To fix
this, move the comma inside the conditional block so it only appears when the
"references" array is included, ensuring valid JSON output in all cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: option to change the default name of the server app.
1 participant