Skip to content

Conversation

@AmanVarshney01
Copy link
Owner

@AmanVarshney01 AmanVarshney01 commented Dec 24, 2025

Summary by CodeRabbit

  • New Features

    • Programmatic API renamed to create() with richer options (template, payments, manual-db, etc.).
    • Payments support added (Polar).
    • PlanetScale DB setup and new "self" backend option.
    • New native frontends: bare, uniwind, unistyles.
    • Added centralized env package for unified environment handling.
  • Improvements

    • Added --manual-db and --payments CLI flags; streamlined CLI options.
    • Replaced Wrangler references with Alchemy for deploy guidance.
    • Silent mode enhanced for programmatic usage.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 24, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
create-better-t-stack-web Ready Ready Preview, Comment Dec 25, 2025 10:03pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

Important

Review skipped

Too many files!

40 files out of 190 files are above the max files limit of 150.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Replaces numerous execa shell-invocations with execa's $ helper and an args-based package-runner; adds a centralized env package (packages/env) and switches templates to import env.* instead of process.env/import.meta.env; renames programmatic API from init → create (with silent option) and adjusts templates, docs, and tests accordingly.

Changes

Cohort / File(s) Summary
Addon Setup Refactoring
apps/cli/src/helpers/addons/* (e.g. fumadocs-setup.ts, oxlint-setup.ts, ruler-setup.ts, starlight-setup.ts, tauri-setup.ts, tui-setup.ts, ultracite-setup.ts, wxt-setup.ts)
Replaced execa command strings with the $ template helper and switched from getPackageExecutionCommandgetPackageExecutionArgs; removed shell:true-style invocations.
Core CLI & Handlers
apps/cli/src/helpers/core/command-handlers.ts, create-project.ts, convex-codegen.ts, project-config.ts
Added silent programmatic flag and CreateProjectOptions; propagate silent to suppress UI output; swapped execa usage to $/args pattern in codegen and package-manager version checks.
Template Manager & Env Package
apps/cli/src/helpers/core/template-manager.ts, apps/cli/src/helpers/core/workspace-setup.ts, apps/cli/src/utils/setup-catalogs.ts
Added setupEnvPackage (duplicate declarations need attention), consolidated env.d.ts handling to packages/env, integrated @<project>/env as a dependency across workspace packages, and included packages/env in setupCatalogs.
Package Runner Utilities
apps/cli/src/utils/package-runner.ts
Added getPackageExecutionArgs(packageManager, commandWithArgs): string[] and getPackageRunnerPrefix(packageManager) to build non-shell argument arrays for pnpm/bun/npx runners.
Database Provider Changes
apps/cli/src/helpers/database-providers/* (e.g. neon-setup.ts, prisma-postgres-setup.ts, supabase-setup.ts, mongodb-atlas-setup.ts)
Migrated from shell command strings to $ + getPackageExecutionArgs; removed shell:true, adjusted error handling and arg splitting where applicable.
CLI Utilities & Error Handling
apps/cli/src/utils/command-exists.ts, open-url.ts, errors.ts
Replaced execa calls with $ template helper; removed programmatic exit branching—error helpers now always throw after logging.
Programmatic API & Entrypoint
apps/cli/src/index.ts, apps/cli/test/test-utils.ts
Renamed public API from initcreate (changed signature/return shape), updated docs/tests to call create(...); removed several test exports and BTS_PROGRAMMATIC handling.
Env Package Templates
apps/cli/templates/packages/env/* (package.json.hbs, src/native.ts.hbs, src/server.ts.hbs, src/web.ts.hbs, tsconfig)
Added new env package templates that export typed env via t3-oss env helpers with conditional schemas for server/web/native runtimes.
Templates: Env & URL Sourcing
many template files under apps/cli/templates/* (auth, api/orpc, api/trpc, backend server, db, frontend, examples, payments)
Replaced usages of process.env / import.meta.env with imports from @{{projectName}}/env/*; added orpc export in ORPC templates and small type adjustments.
Types & Packages
apps/cli/src/types.ts, packages/types/src/*, apps/web/src/lib/types.ts
Consolidated wildcard re-exports (export *) and removed TechCategory from packages/types (moved inline in web app).
Constants & Dependency Versions
apps/cli/src/constants.ts
Updated dependencyVersionMap (alchemy → ^0.82.1) and added @t3-oss/env-core, @t3-oss/env-nextjs, @t3-oss/env-nuxt entries.
Env Setup Adjustments
apps/cli/src/helpers/core/env-setup.ts
Removed previously-added PORT=3001 client var for Next.js.
Docs & CLI Options
apps/web/content/docs/cli/*, apps/web/content/docs/index.mdx, apps/web/content/docs/cli/options.mdx, programmatic-api.mdx
Updated CLI docs to reflect create API, new flags/options (template, manual-db, payments, planetscale, self backend), removed wrangler in favor of alchemy, and updated programmatic examples.
Misc & Formatting
apps/cli/src/utils/template-processor.ts, various tsconfig templates, small formatting changes
Small formatting/whitespace edits and added new tsconfig templates for base and env package.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • #692 — Related env/package and template-manager changes (overlaps in env package scaffolding and template wiring).
  • #494 — Related programmatic API migration (init → create) and handler/type changes.
  • #700 — Related template handling and template field additions used by the new create flow.

Suggested labels

preview

Poem

🐰 With a twitch and a hop I tidy the stack,

Commands now sing with $ on the track,
Env lives in packages, neat and polite,
create() whispers softly and hides the loud fight,
Templates feel lighter — the rabbit says: "Nice!" 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.95% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(cli): add env package' accurately describes the main objective of the PR, which introduces a new environment package to the CLI. The change is central to the entire changeset.

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

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 15

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs (1)

36-42: Empty string fallback may mask missing DATABASE_URL in workers runtime.

Using env.DATABASE_URL || "" will pass an empty string to neon() or drizzle() if the environment variable is missing, resulting in a cryptic connection error rather than a clear validation failure. The non-workers path benefits from the env package's validation, but the workers path does not.

Consider adding explicit validation or throwing a descriptive error when DATABASE_URL is missing in the workers runtime.

🔎 Proposed improvement
-const sql = neon(env.DATABASE_URL || "");
+if (!env.DATABASE_URL) {
+  throw new Error("DATABASE_URL environment variable is required");
+}
+const sql = neon(env.DATABASE_URL);

Similarly for the non-Neon workers path:

-export const db = drizzle(env.DATABASE_URL || "", { schema });
+if (!env.DATABASE_URL) {
+  throw new Error("DATABASE_URL environment variable is required");
+}
+export const db = drizzle(env.DATABASE_URL, { schema });
apps/cli/src/helpers/database-providers/neon-setup.ts (1)

59-66: User-provided projectName may break argument parsing if it contains spaces.

The projectName from user input is directly interpolated into the command string (line 60), which is then split by spaces in getPackageExecutionArgs. If a user enters a project name with spaces (e.g., "My Project"), it will be incorrectly split into multiple arguments.

Consider validating the project name or using getPackageRunnerPrefix with explicit argument construction.

🔎 Proposed fix using getPackageRunnerPrefix
+import { getPackageRunnerPrefix } from "../../utils/package-runner";

 async function createNeonProject(
   projectName: string,
   regionId: string,
   packageManager: PackageManager,
 ) {
   try {
-    const commandArgsString = `neonctl@latest projects create --name ${projectName} --region-id ${regionId} --output json`;
-    const { stdout } = await executeNeonCommand(
-      packageManager,
-      commandArgsString,
-      `Creating Neon project "${projectName}"...`,
-    );
+    const prefix = getPackageRunnerPrefix(packageManager);
+    const args = [...prefix, "neonctl@latest", "projects", "create", "--name", projectName, "--region-id", regionId, "--output", "json"];
+    
+    const s = spinner();
+    s.start(`Creating Neon project "${projectName}"...`);
+    const { stdout } = await $`${args}`;
+    s.stop(pc.green(`Created Neon project "${projectName}"`));
♻️ Duplicate comments (2)
apps/cli/src/helpers/addons/tui-setup.ts (1)

3-3: Same pattern as ultracite-setup.ts.

This file follows the same execa $ helper pattern. See the verification comment in ultracite-setup.ts regarding alignment with the Bun.$ coding guideline.

Also applies to: 8-8, 46-54

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

4-4: Same execa pattern as other addon setup files.

This file follows the same execa $ helper pattern with getPackageRunnerPrefix. See the verification comment in ultracite-setup.ts regarding alignment with the Bun.$ coding guideline.

The command construction looks correct - tauri init receives the before-dev/build commands as string arguments.

Also applies to: 9-9, 67-78

🧹 Nitpick comments (8)
apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs (2)

261-262: Consider adding a more helpful error message for the "none" ORM case.

The empty string for database will cause a runtime error. Consider using a configuration that provides a clearer error message or a comment explaining what the user needs to do.

Suggested improvement
 export const auth = betterAuth({
-	database: "", // Invalid configuration
+	database: undefined as never, // TODO: Configure your database adapter - see https://www.better-auth.com/docs/concepts/database

Alternatively, throw a descriptive error:

	database: (() => { throw new Error("No ORM selected. Please configure a database adapter for better-auth."); })(),

18-23: Consider extracting repeated trustedOrigins logic into a Handlebars partial.

The trustedOrigins configuration is duplicated across all 5 ORM/runtime blocks with identical logic. The same applies to emailAndPassword, advanced, and plugins sections. While this is common in templates, it increases maintenance burden—any change to these sections requires updates in multiple places.

This is a nice-to-have improvement for maintainability. You could create partials like {{> trustedOrigins }} and {{> polarPlugins }} to centralize the repeated logic.

Also applies to: 80-85, 141-146, 210-215, 263-268

apps/cli/templates/payments/polar/server/base/src/lib/payments.ts.hbs (1)

6-6: Consider making the Polar server environment configurable.

The server: "sandbox" is hardcoded. For production deployments, users will need to change this to "production". Consider sourcing this from an env variable (e.g., env.POLAR_SERVER || "sandbox") or adding a comment indicating this needs to be changed for production.

apps/cli/test/test-utils.ts (1)

79-83: Consider updating references from tRPC to oRPC.

The comment mentions "tRPC test" but the implementation uses oRPC (createRouterClient from @orpc/server). Consider renaming runTRPCTest to runORPCTest and updating the comment for clarity.

apps/cli/src/utils/package-runner.ts (1)

33-46: Space-splitting may break arguments containing spaces.

The commandWithArgs.split(" ") approach will incorrectly split arguments that contain spaces (e.g., file paths like "my file.ts" or values with spaces). This could cause subtle failures when users have spaces in paths or arguments.

Consider documenting this limitation clearly, or use getPackageRunnerPrefix consistently for all callers to avoid this pitfall.

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

35-52: Consider adding cwd context to executeNeonCommand.

The executeNeonCommand function executes without specifying cwd, meaning it runs in the current working directory rather than the project directory. This differs from setupWithNeonDb which explicitly sets cwd: targetDir. While this may work in practice, it's inconsistent.

🔎 Proposed change
 async function executeNeonCommand(
   packageManager: PackageManager,
   commandArgsString: string,
   spinnerText?: string,
+  cwd?: string,
 ) {
   const s = spinner();
   try {
     const args = getPackageExecutionArgs(packageManager, commandArgsString);

     if (spinnerText) s.start(spinnerText);
-    const result = await $`${args}`;
+    const result = cwd ? await $({ cwd })`${args}` : await $`${args}`;
     if (spinnerText) s.stop(pc.green(spinnerText.replace("...", "").replace("ing ", "ed ").trim()));
     return result;
   } catch (error) {
apps/cli/src/helpers/core/template-manager.ts (1)

266-328: LGTM! Well-structured conditional env package setup.

The logic correctly:

  • Skips env package generation when there's no frontend and backend is "none"
  • Only generates server.ts for non-convex, non-none backends with non-workers runtime
  • Conditionally includes web/native env files based on frontend configuration

One minor observation: the src directory is ensured multiple times (lines 306, 315, 324). Consider consolidating:

🔎 Optional consolidation
+  const srcDir = path.join(envPackageDir, "src");
+  const needsSrcDir = needsServerEnv || hasWebFrontend || hasNative;
+  if (needsSrcDir) {
+    await fs.ensureDir(srcDir);
+  }
+
   if (needsServerEnv) {
     const serverSrc = path.join(envBaseDir, "src/server.ts.hbs");
     if (await fs.pathExists(serverSrc)) {
-      await fs.ensureDir(path.join(envPackageDir, "src"));
       await processAndCopyFiles("src/server.ts.hbs", envBaseDir, envPackageDir, context);
     }
   }
apps/cli/src/index.ts (1)

198-227: Good programmatic API design with safe defaults.

The create function appropriately:

  • Forces silent mode for programmatic use
  • Disables analytics by default (privacy-respecting)
  • Uses "error" for directory conflicts (fail-fast behavior)
  • Wraps handler in try/catch for graceful error handling

However, the error fallback at line 219 uses an unsafe type assertion:

projectConfig: {} as ProjectConfig,

If callers access properties on projectConfig when success: false, they'll get undefined instead of the expected types.

🔎 Consider using a partial or null pattern
-      projectConfig: {} as ProjectConfig,
+      projectConfig: null,

Then update the InitResult type to use projectConfig: ProjectConfig | null or a discriminated union where success: false has no projectConfig.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f91d2cd and bdc7480.

📒 Files selected for processing (69)
  • apps/cli/src/helpers/addons/fumadocs-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/addons/ruler-setup.ts
  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/helpers/addons/tauri-setup.ts
  • apps/cli/src/helpers/addons/tui-setup.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/src/helpers/core/create-project.ts
  • apps/cli/src/helpers/core/project-config.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/helpers/database-providers/neon-setup.ts
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/utils/command-exists.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/utils/open-url.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/utils/template-processor.ts
  • apps/cli/templates/api/orpc/native/utils/orpc.ts.hbs
  • apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs
  • apps/cli/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs
  • apps/cli/templates/api/trpc/native/utils/trpc.ts.hbs
  • apps/cli/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs
  • apps/cli/templates/auth/better-auth/native/base/lib/auth-client.ts.hbs
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs
  • apps/cli/templates/auth/better-auth/web/solid/src/lib/auth-client.ts.hbs
  • apps/cli/templates/backend/server/elysia/src/index.ts.hbs
  • apps/cli/templates/backend/server/express/src/index.ts.hbs
  • apps/cli/templates/backend/server/fastify/src/index.ts.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/mongoose/mongodb/src/index.ts.hbs
  • apps/cli/templates/db/prisma/mysql/prisma.config.ts.hbs
  • apps/cli/templates/db/prisma/mysql/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/next/src/app/ai/page.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/react-router/src/routes/ai.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/react/next/src/components/providers.tsx.hbs
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs
  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/templates/packages/env/src/native.ts.hbs
  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/payments/polar/server/base/src/lib/payments.ts.hbs
  • apps/cli/test/test-utils.ts
💤 Files with no reviewable changes (1)
  • apps/cli/src/utils/template-processor.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions

Files:

  • apps/cli/src/utils/command-exists.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/addons/fumadocs-setup.ts
  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/utils/open-url.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/helpers/addons/ruler-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/helpers/addons/tui-setup.ts
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/src/helpers/database-providers/neon-setup.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/helpers/addons/tauri-setup.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/helpers/core/project-config.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/helpers/core/create-project.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations
Do not use explicit return types

Files:

  • apps/cli/src/utils/command-exists.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/addons/fumadocs-setup.ts
  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/utils/open-url.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/helpers/addons/ruler-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/helpers/addons/tui-setup.ts
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/src/helpers/database-providers/neon-setup.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/helpers/addons/tauri-setup.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/helpers/core/project-config.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/helpers/core/create-project.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{ts,tsx,js,jsx}: Use bun <file> instead of node <file> or ts-node <file> for running TypeScript/JavaScript files
Bun automatically loads .env files, so don't use the dotenv package
Use Bun.serve() which supports WebSockets, HTTPS, and routes instead of express
Use bun:sqlite module for SQLite instead of better-sqlite3
Use Bun.redis for Redis instead of ioredis
Use Bun.sql for Postgres instead of pg or postgres.js
Use built-in WebSocket instead of the ws package
Prefer Bun.file over node:fs readFile/writeFile methods
Use Bun.$ template literal syntax instead of execa for shell command execution
Import .css files directly in TypeScript/JavaScript files; Bun's CSS bundler will handle bundling
Run server with bun --hot <file> to enable hot reloading during development

Files:

  • apps/cli/src/utils/command-exists.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/addons/fumadocs-setup.ts
  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/utils/open-url.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/helpers/addons/ruler-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/helpers/addons/tui-setup.ts
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/src/helpers/database-providers/neon-setup.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/helpers/addons/tauri-setup.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/helpers/core/project-config.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/helpers/core/create-project.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file> instead of webpack or esbuild for bundling TypeScript, JavaScript, and CSS files

Files:

  • apps/cli/src/utils/command-exists.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/addons/fumadocs-setup.ts
  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/utils/open-url.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/helpers/addons/ruler-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/helpers/addons/tui-setup.ts
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/src/helpers/database-providers/neon-setup.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/helpers/addons/tauri-setup.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/helpers/core/project-config.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/helpers/core/create-project.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
**/*.{html,tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use HTML imports with Bun.serve() for frontend instead of Vite

Files:

  • apps/cli/src/utils/command-exists.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/addons/fumadocs-setup.ts
  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/utils/open-url.ts
  • apps/cli/src/helpers/core/command-handlers.ts
  • apps/cli/src/helpers/addons/ruler-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/helpers/addons/tui-setup.ts
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/src/helpers/database-providers/neon-setup.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/helpers/addons/tauri-setup.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/helpers/core/project-config.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/utils/errors.ts
  • apps/cli/src/helpers/core/create-project.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.hbs: In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle
Escape the '{{' in Handlebars templates like '{{'

Files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/payments/polar/server/base/src/lib/payments.ts.hbs
  • apps/cli/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs
  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/next/src/app/ai/page.tsx.hbs
  • apps/cli/templates/backend/server/elysia/src/index.ts.hbs
  • apps/cli/templates/db/mongoose/mongodb/src/index.ts.hbs
  • apps/cli/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs
  • apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs
  • apps/cli/templates/packages/env/src/native.ts.hbs
  • apps/cli/templates/frontend/react/next/src/components/providers.tsx.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/backend/server/fastify/src/index.ts.hbs
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/backend/server/express/src/index.ts.hbs
  • apps/cli/templates/api/orpc/native/utils/orpc.ts.hbs
  • apps/cli/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs
  • apps/cli/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs
  • apps/cli/templates/db/prisma/mysql/prisma.config.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/auth/better-auth/native/base/lib/auth-client.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/api/trpc/native/utils/trpc.ts.hbs
  • apps/cli/templates/examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/db/prisma/mysql/src/index.ts.hbs
  • apps/cli/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/react-router/src/routes/ai.tsx.hbs
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/auth/better-auth/web/solid/src/lib/auth-client.ts.hbs
  • apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
🧠 Learnings (30)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution

Applied to files:

  • apps/cli/src/utils/command-exists.ts
  • apps/cli/src/utils/package-runner.ts
  • apps/cli/src/helpers/addons/fumadocs-setup.ts
  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/utils/open-url.ts
  • apps/cli/src/helpers/addons/ruler-setup.ts
  • apps/cli/src/helpers/addons/tui-setup.ts
  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/src/helpers/database-providers/neon-setup.ts
  • apps/cli/src/helpers/database-providers/supabase-setup.ts
  • apps/cli/src/helpers/database-providers/mongodb-atlas-setup.ts
  • apps/cli/src/helpers/addons/tauri-setup.ts
  • apps/cli/src/helpers/addons/ultracite-setup.ts
  • apps/cli/src/helpers/core/project-config.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/schema.ts : Always define your schema in convex/schema.ts and import schema definition functions from convex/server

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to package.json : Use `bun run <script>` instead of `npm run <script>`, `yarn run <script>`, or `pnpm run <script>`

Applied to files:

  • apps/cli/src/utils/package-runner.ts
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Use query, mutation, and action to define public functions; use internalQuery, internalMutation, and internalAction to define private, internal functions

Applied to files:

  • apps/cli/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
  • apps/cli/templates/api/orpc/native/utils/orpc.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs
  • apps/cli/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{html,tsx,ts,jsx,js} : Use HTML imports with `Bun.serve()` for frontend instead of Vite

Applied to files:

  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs
  • apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs
  • apps/cli/templates/examples/ai/web/react/react-router/src/routes/ai.tsx.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Convex uses file-based routing; a public function defined in convex/example.ts named f has function reference api.example.f

Applied to files:

  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

Applied to files:

  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/templates/backend/server/elysia/src/index.ts.hbs
  • apps/cli/templates/frontend/react/next/src/components/providers.tsx.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/backend/server/fastify/src/index.ts.hbs
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/backend/server/express/src/index.ts.hbs
  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/templates/db/prisma/mysql/prisma.config.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Use the api object from convex/_generated/api.ts to call public functions registered with query, mutation, or action

Applied to files:

  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Thoughtfully organize files with public query, mutation, or action functions within the convex/ directory using file-based routing

Applied to files:

  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Use the internal object from convex/_generated/api.ts to call internal/private functions registered with internalQuery, internalMutation, or internalAction

Applied to files:

  • apps/cli/templates/frontend/react/tanstack-router/src/main.tsx.hbs
  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
📚 Learning: 2025-12-18T19:15:55.011Z
Learnt from: therealsamyak
Repo: AmanVarshney01/create-better-t-stack PR: 711
File: apps/cli/src/helpers/addons/ultracite-setup.ts:200-205
Timestamp: 2025-12-18T19:15:55.011Z
Learning: In apps/cli/src/helpers/addons/ultracite-setup.ts, the Ultracite CLI's `--integrations` flag requires git hooks to be passed as a single space-separated string (e.g., `gitHooks.join(" ")`) rather than using the spread operator like other Ultracite flags. This has been tested and confirmed to work.

Applied to files:

  • apps/cli/src/helpers/addons/starlight-setup.ts
  • apps/cli/src/helpers/addons/oxlint-setup.ts
  • apps/cli/src/helpers/addons/wxt-setup.ts
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.serve()` which supports WebSockets, HTTPS, and routes instead of `express`

Applied to files:

  • apps/cli/templates/backend/server/elysia/src/index.ts.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/backend/server/fastify/src/index.ts.hbs
  • apps/cli/templates/backend/server/express/src/index.ts.hbs
📚 Learning: 2025-06-08T17:57:33.083Z
Learnt from: Vijayabaskar56
Repo: AmanVarshney01/create-better-t-stack PR: 310
File: apps/cli/templates/frontend/angular/src/app.component.html:1-7
Timestamp: 2025-06-08T17:57:33.083Z
Learning: For NgxSonnerToaster in the Angular template, it's sufficient to import it directly in the app-root component's imports array rather than in a module, following the standalone component approach.

Applied to files:

  • apps/cli/templates/frontend/react/next/src/components/providers.tsx.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Run server with `bun --hot <file>` to enable hot reloading during development

Applied to files:

  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun <file>` instead of `node <file>` or `ts-node <file>` for running TypeScript/JavaScript files

Applied to files:

  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.redis` for Redis instead of `ioredis`

Applied to files:

  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.sql` for Postgres instead of `pg` or `postgres.js`

Applied to files:

  • apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : ALWAYS use the new function syntax for Convex functions with explicit args, returns, and handler properties

Applied to files:

  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/templates/frontend/react/react-router/src/root.tsx.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : ONLY call an action from another action if you need to cross runtimes; otherwise, pull out shared code into a helper async function and call that directly

Applied to files:

  • apps/cli/src/helpers/core/convex-codegen.ts
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Always add 'use node'; to the top of files containing actions that use Node.js built-in modules

Applied to files:

  • apps/cli/src/helpers/core/convex-codegen.ts
  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : A private function defined in convex/example.ts named g has function reference internal.example.g; nested files follow the directory structure

Applied to files:

  • apps/cli/src/helpers/core/convex-codegen.ts
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Use ctx.runQuery to call a query from a query, mutation, or action; use ctx.runMutation to call a mutation from a mutation or action; use ctx.runAction to call an action from an action

Applied to files:

  • apps/cli/src/helpers/core/convex-codegen.ts
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Convex storage stores items as Blob objects; you must convert all items to/from a Blob when using Convex storage

Applied to files:

  • apps/cli/templates/frontend/native/bare/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/uniwind/app/_layout.tsx.hbs
  • apps/cli/templates/frontend/native/unistyles/app/_layout.tsx.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun:sqlite` module for SQLite instead of `better-sqlite3`

Applied to files:

  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Use query, mutation, and action to register public functions that are part of the public API; do NOT use these for sensitive internal functions

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Try to use as few calls from actions to queries and mutations as possible to reduce race condition risks from multiple transactions

Applied to files:

  • apps/cli/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs
  • apps/cli/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx,css} : Use `bun build <file>` instead of `webpack` or `esbuild` for bundling TypeScript, JavaScript, and CSS files

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-18T19:15:48.478Z
Learnt from: therealsamyak
Repo: AmanVarshney01/create-better-t-stack PR: 711
File: apps/cli/src/helpers/addons/ultracite-setup.ts:200-205
Timestamp: 2025-12-18T19:15:48.478Z
Learning: In apps/cli/src/helpers/addons/ultracite-setup.ts, when passing the Ultracite CLI --integrations flag, supply git hooks as a single space-separated string (e.g., gitHooks.join(" ")) rather than spreading the array like other Ultracite flags. This has been tested and confirmed to work. Ensure the code uses a single string created by joining the gitHooks array with spaces for the --integrations argument.

Applied to files:

  • apps/cli/src/helpers/addons/ultracite-setup.ts
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle

Applied to files:

  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
🧬 Code graph analysis (15)
apps/cli/src/utils/package-runner.ts (2)
apps/cli/src/index.ts (1)
  • PackageManager (249-249)
apps/cli/test/test-utils.ts (1)
  • PackageManager (218-218)
apps/cli/src/helpers/addons/fumadocs-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/helpers/addons/starlight-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/helpers/core/command-handlers.ts (7)
apps/cli/src/index.ts (1)
  • CreateInput (256-256)
apps/cli/src/types.ts (1)
  • CreateInput (64-64)
apps/cli/src/utils/render-title.ts (1)
  • renderTitle (33-48)
apps/cli/src/utils/display-config.ts (1)
  • displayConfig (4-96)
apps/cli/src/validation.ts (1)
  • processAndValidateFlags (42-82)
apps/cli/src/utils/generate-reproducible-command.ts (1)
  • generateReproducibleCommand (3-53)
apps/cli/src/utils/analytics.ts (1)
  • trackProjectCreation (21-39)
apps/cli/src/helpers/addons/ruler-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/index.ts (1)
apps/cli/src/helpers/core/command-handlers.ts (1)
  • createProjectHandler (38-222)
apps/cli/src/helpers/addons/tui-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/helpers/addons/oxlint-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/helpers/database-providers/neon-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/helpers/core/workspace-setup.ts (1)
apps/cli/src/utils/add-package-deps.ts (1)
  • addPackageDependency (6-57)
apps/cli/src/helpers/addons/tauri-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageRunnerPrefix (60-71)
apps/cli/src/helpers/addons/ultracite-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)
apps/cli/src/helpers/core/create-project.ts (4)
apps/cli/src/index.ts (1)
  • ProjectConfig (258-258)
apps/cli/src/types.ts (1)
  • ProjectConfig (67-67)
apps/cli/src/helpers/core/post-installation.ts (1)
  • displayPostInstallInstructions (5-191)
apps/cli/src/utils/errors.ts (1)
  • exitWithError (5-8)
apps/cli/src/helpers/addons/wxt-setup.ts (1)
apps/cli/src/utils/package-runner.ts (1)
  • getPackageExecutionArgs (33-46)

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: 1

🧹 Nitpick comments (2)
apps/cli/src/index.ts (2)

202-209: Consider stronger type safety for input construction.

The type assertion as CreateInput & { projectName?: string } at line 209 forces Partial<CreateInput> into CreateInput, potentially hiding missing required fields. While createProjectHandler may handle defaults internally, this reduces compile-time type safety.

Consider one of these approaches:

  1. Update createProjectHandler to accept Partial<CreateInput> explicitly
  2. Build a complete CreateInput object by merging with a defaults object
  3. Create a separate type for the programmatic API that makes optionality explicit

214-224: Verify empty ProjectConfig cast is acceptable for error cases.

Line 217 casts an empty object as ProjectConfig. Consumers expecting valid project configuration fields in error cases may encounter runtime issues when accessing properties on this empty object.

Consider either:

  1. Populating minimal valid ProjectConfig fields (e.g., projectName, projectDir with empty/default values)
  2. Making projectConfig optional in the InitResult type for error cases
  3. Documenting that projectConfig should not be used when success is false
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bdc7480 and 3bc7c22.

📒 Files selected for processing (1)
  • apps/cli/src/index.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions

Files:

  • apps/cli/src/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations
Do not use explicit return types

Files:

  • apps/cli/src/index.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{ts,tsx,js,jsx}: Use bun <file> instead of node <file> or ts-node <file> for running TypeScript/JavaScript files
Bun automatically loads .env files, so don't use the dotenv package
Use Bun.serve() which supports WebSockets, HTTPS, and routes instead of express
Use bun:sqlite module for SQLite instead of better-sqlite3
Use Bun.redis for Redis instead of ioredis
Use Bun.sql for Postgres instead of pg or postgres.js
Use built-in WebSocket instead of the ws package
Prefer Bun.file over node:fs readFile/writeFile methods
Use Bun.$ template literal syntax instead of execa for shell command execution
Import .css files directly in TypeScript/JavaScript files; Bun's CSS bundler will handle bundling
Run server with bun --hot <file> to enable hot reloading during development

Files:

  • apps/cli/src/index.ts
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file> instead of webpack or esbuild for bundling TypeScript, JavaScript, and CSS files

Files:

  • apps/cli/src/index.ts
**/*.{html,tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use HTML imports with Bun.serve() for frontend instead of Vite

Files:

  • apps/cli/src/index.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
🧬 Code graph analysis (1)
apps/cli/src/index.ts (2)
apps/cli/src/types.ts (3)
  • CreateInput (64-64)
  • InitResult (69-69)
  • ProjectConfig (67-67)
apps/cli/src/helpers/core/command-handlers.ts (1)
  • createProjectHandler (38-222)
🔇 Additional comments (2)
apps/cli/src/index.ts (2)

52-52: LGTM! Router key renamed to align with new API.

The router key change from init to create is consistent with the PR's objective to standardize the API surface.


211-224: Well-structured error handling for programmatic API.

The try-catch block ensures consistent InitResult return shape for both success and failure cases, which is appropriate for a programmatic API. The silent mode and disabled analytics are sensible defaults for non-interactive usage.

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: 0

♻️ Duplicate comments (2)
apps/cli/src/index.ts (1)

199-202: Remove explicit return type annotation.

The function signature includes an explicit return type : Promise<InitResult>, which violates the TypeScript coding guidelines.

apps/cli/templates/packages/env/package.json.hbs (1)

6-16: Trailing commas will produce invalid JSON in most scenarios.

The conditional exports generate invalid JSON when the last rendered export has a trailing comma. For example:

  • If only ./server is exported: "./server": "./src/server.ts",} (invalid)
  • If only ./web is exported: "./web": "./src/web.ts",} (invalid)
  • If ./server and ./web but no ./native: "./web": "./src/web.ts",} (invalid)

Only the scenario where all three exports are rendered produces valid JSON.

🔎 Fix by conditionally adding commas between entries

The solution is to add commas only between entries, not after the last one. Here's one approach:

 	"exports": {
-{{#if (and (ne backend "convex") (ne backend "none") (ne runtime "workers"))}}
-		"./server": "./src/server.ts",
-{{/if}}
-{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
-		"./web": "./src/web.ts",
-{{/if}}
-{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
-		"./native": "./src/native.ts"
-{{/if}}
+{{~#if (and (ne backend "convex") (ne backend "none") (ne runtime "workers"))}}
+		"./server": "./src/server.ts"{{#if (or (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid")) (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles")))}},{{/if}}
+{{~/if}}
+{{~#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
+		"./web": "./src/web.ts"{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}},{{/if}}
+{{~/if}}
+{{~#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
+		"./native": "./src/native.ts"
+{{~/if}}
 	}

This adds a comma after each export only if a subsequent export will be rendered.

🧹 Nitpick comments (2)
apps/cli/test/test-utils.ts (1)

81-93: Consider using type aliases instead of interfaces.

Per coding guidelines, TypeScript type aliases should be preferred over interface declarations.

🔎 Proposed fix
-export interface TestResult {
-  success: boolean;
-  result?: InitResult;
-  error?: string;
-  projectDir?: string;
-  config: TestConfig;
-}
+export type TestResult = {
+  success: boolean;
+  result?: InitResult;
+  error?: string;
+  projectDir?: string;
+  config: TestConfig;
+};

-export interface TestConfig extends CreateInput {
-  projectName?: string;
-  expectError?: boolean;
-  expectedErrorMessage?: string;
-}
+export type TestConfig = CreateInput & {
+  projectName?: string;
+  expectError?: boolean;
+  expectedErrorMessage?: string;
+};
apps/cli/src/index.ts (1)

214-225: Consider providing a more complete error fallback object.

The projectConfig: {} as ProjectConfig type assertion creates an object that doesn't match the ProjectConfig shape at runtime. While consumers should check success before using projectConfig, this could lead to runtime errors if misused.

🔎 Proposed fix

Provide a default error config similar to createProjectHandler's error return:

   } catch (error) {
     return {
       success: false,
       error: error instanceof Error ? error.message : String(error),
-      projectConfig: {} as ProjectConfig,
+      projectConfig: {
+        projectName: "",
+        projectDir: "",
+        relativePath: "",
+        database: "none",
+        orm: "none",
+        backend: "none",
+        runtime: "none",
+        frontend: [],
+        addons: [],
+        examples: [],
+        auth: "none",
+        payments: "none",
+        git: false,
+        packageManager: "npm",
+        install: false,
+        dbSetup: "none",
+        api: "none",
+        webDeploy: "none",
+        serverDeploy: "none",
+      } satisfies ProjectConfig,
       reproducibleCommand: "",
       timeScaffolded: new Date().toISOString(),
       elapsedTimeMs: 0,
       projectDirectory: "",
       relativePath: "",
     };
   }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0d12f7 and edea419.

📒 Files selected for processing (8)
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/index.ts
  • apps/cli/src/types.ts
  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/test/test-utils.ts
  • apps/web/src/lib/types.ts
  • packages/types/src/index.ts
  • packages/types/src/types.ts
💤 Files with no reviewable changes (1)
  • packages/types/src/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/cli/src/helpers/core/workspace-setup.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions

Files:

  • apps/web/src/lib/types.ts
  • packages/types/src/index.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/index.ts
  • apps/cli/src/types.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations
Do not use explicit return types

Files:

  • apps/web/src/lib/types.ts
  • packages/types/src/index.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/index.ts
  • apps/cli/src/types.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{ts,tsx,js,jsx}: Use bun <file> instead of node <file> or ts-node <file> for running TypeScript/JavaScript files
Bun automatically loads .env files, so don't use the dotenv package
Use Bun.serve() which supports WebSockets, HTTPS, and routes instead of express
Use bun:sqlite module for SQLite instead of better-sqlite3
Use Bun.redis for Redis instead of ioredis
Use Bun.sql for Postgres instead of pg or postgres.js
Use built-in WebSocket instead of the ws package
Prefer Bun.file over node:fs readFile/writeFile methods
Use Bun.$ template literal syntax instead of execa for shell command execution
Import .css files directly in TypeScript/JavaScript files; Bun's CSS bundler will handle bundling
Run server with bun --hot <file> to enable hot reloading during development

Files:

  • apps/web/src/lib/types.ts
  • packages/types/src/index.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/index.ts
  • apps/cli/src/types.ts
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file> instead of webpack or esbuild for bundling TypeScript, JavaScript, and CSS files

Files:

  • apps/web/src/lib/types.ts
  • packages/types/src/index.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/index.ts
  • apps/cli/src/types.ts
**/*.{html,tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use HTML imports with Bun.serve() for frontend instead of Vite

Files:

  • apps/web/src/lib/types.ts
  • packages/types/src/index.ts
  • apps/cli/test/test-utils.ts
  • apps/cli/src/index.ts
  • apps/cli/src/types.ts
**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.hbs: In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle
Escape the '{{' in Handlebars templates like '{{'

Files:

  • apps/cli/templates/packages/env/package.json.hbs
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript type aliases instead of interface declarations

Applied to files:

  • apps/web/src/lib/types.ts
  • packages/types/src/index.ts
  • apps/cli/src/types.ts
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.{ts,tsx} : Do not use explicit return types

Applied to files:

  • packages/types/src/index.ts
  • apps/cli/src/index.ts
  • apps/cli/src/types.ts
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/schema.ts : Always define your schema in convex/schema.ts and import schema definition functions from convex/server

Applied to files:

  • packages/types/src/index.ts
  • apps/cli/test/test-utils.ts
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/**/*.ts : Always add 'use node'; to the top of files containing actions that use Node.js built-in modules

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Run server with `bun --hot <file>` to enable hot reloading during development

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx,css} : Use `bun build <file>` instead of `webpack` or `esbuild` for bundling TypeScript, JavaScript, and CSS files

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{html,tsx,ts,jsx,js} : Use HTML imports with `Bun.serve()` for frontend instead of Vite

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun <file>` instead of `node <file>` or `ts-node <file>` for running TypeScript/JavaScript files

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun:sqlite` module for SQLite instead of `better-sqlite3`

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
🧬 Code graph analysis (1)
apps/cli/src/index.ts (2)
packages/types/src/types.ts (3)
  • CreateInput (47-47)
  • InitResult (52-52)
  • ProjectConfig (50-50)
apps/cli/src/helpers/core/command-handlers.ts (1)
  • createProjectHandler (38-222)
🔇 Additional comments (7)
packages/types/src/index.ts (1)

1-3: LGTM!

Consolidating to wildcard re-exports simplifies maintenance and keeps the public API surface in sync with the underlying modules automatically.

apps/web/src/lib/types.ts (1)

1-19: LGTM!

Defining TechCategory locally provides independence from the shared types package, allowing the web UI to evolve its categorization separately. The type alias approach aligns with coding guidelines.

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

1-1: LGTM!

Wildcard re-export keeps the CLI's type surface in sync with the shared types package automatically.

apps/cli/test/test-utils.ts (1)

179-179: LGTM!

Correctly updated to use the new create API instead of the previous init.

apps/cli/src/index.ts (2)

52-113: LGTM!

The router endpoint correctly renamed from init to create, and the handler properly delegates to createProjectHandler.


240-259: LGTM!

The expanded type exports provide a comprehensive public API surface for programmatic usage.

apps/cli/templates/packages/env/package.json.hbs (1)

1-17: AI summary mentions non-existent dependencies.

The AI summary states "placeholder dependencies and devDependencies" exist in this template, but the actual code contains no such fields—only name, version, private, type, and exports.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
apps/web/content/docs/cli/options.mdx (1)

368-368: Inconsistent deployment option in example.

The example uses --web-deploy wrangler, but according to the Deployment section (lines 326-331), only none and alchemy are valid options for --web-deploy. The wrangler option was removed in this PR.

🔎 Proposed fix
-  --web-deploy wrangler \
+  --web-deploy alchemy \
apps/web/content/docs/cli/programmatic-api.mdx (4)

182-196: Documentation refers to init() but should say create().

Line 184 states "Result object returned by init()" but the API was renamed to create().

🔎 Proposed fix
-Result object returned by `init()`:
+Result object returned by `create()`:

248-256: Code example still uses init() instead of create().

The Directory Conflicts error handling example uses init() but should use create() to match the API rename.

🔎 Proposed fix
-const result = await init("existing-dir", {
+const result = await create("existing-dir", {
   directoryConflict: "error"
 });

263-272: Code example still uses init() instead of create().

The Validation Errors example uses init() but should use create() to match the API rename.

🔎 Proposed fix
 try {
-  await init("test", {
+  await create("test", {
     database: "mongodb",
     orm: "drizzle" // Invalid combination
   });

307-321: Code example still uses init() instead of create().

The "Handling Prompts" example uses init() but should use create() to match the API rename.

🔎 Proposed fix
 // Instead of interactive prompts, specify all options
-const result = await init("my-app", {
+const result = await create("my-app", {
   yes: true, // Skip all prompts
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between edea419 and 6781043.

📒 Files selected for processing (5)
  • apps/web/content/docs/cli/compatibility.mdx
  • apps/web/content/docs/cli/index.mdx
  • apps/web/content/docs/cli/options.mdx
  • apps/web/content/docs/cli/programmatic-api.mdx
  • apps/web/content/docs/index.mdx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.serve()` which supports WebSockets, HTTPS, and routes instead of `express`

Applied to files:

  • apps/web/content/docs/cli/options.mdx
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun:sqlite` module for SQLite instead of `better-sqlite3`

Applied to files:

  • apps/web/content/docs/index.mdx
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun <file>` instead of `node <file>` or `ts-node <file>` for running TypeScript/JavaScript files

Applied to files:

  • apps/web/content/docs/index.mdx
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx,css} : Use `bun build <file>` instead of `webpack` or `esbuild` for bundling TypeScript, JavaScript, and CSS files

Applied to files:

  • apps/web/content/docs/index.mdx
🔇 Additional comments (12)
apps/web/content/docs/cli/compatibility.mdx (2)

136-136: LGTM!

PlanetScale addition with MySQL/PostgreSQL support is consistent with the expanded db-setup options documented elsewhere in this PR.


169-169: LGTM!

The update from wrangler to alchemy aligns with the deployment option changes across the CLI documentation.

apps/web/content/docs/index.mdx (2)

236-256: LGTM!

The native-nativewindnative-uniwind rename is applied consistently across all three package manager examples (npm, pnpm, bun).


306-314: LGTM!

The flags cheat sheet now accurately reflects the expanded option surface: new native-bare frontend, self backend, payments flag, and additional addons (opentui, wxt).

apps/web/content/docs/cli/index.mdx (3)

31-46: LGTM!

The init command options are properly updated with the new self backend, payments flag, planetscale db-setup, alchemy deployment, template, and manual-db options.


74-90: LGTM!

The add command options and example correctly reflect the deployment option changes (alchemy only).


167-178: LGTM!

The programmatic usage example correctly demonstrates the renamed create() API with proper import, invocation, and result handling.

apps/web/content/docs/cli/options.mdx (3)

16-36: LGTM!

The new --template and --manual-db options are well-documented with clear descriptions and examples.


267-280: LGTM!

The new Payments section is properly documented with the polar option and the Better-Auth requirement note.


299-300: LGTM!

The new opentui and wxt addons are properly added to the list.

apps/web/content/docs/cli/programmatic-api.mdx (2)

48-72: LGTM!

The Quick Start example correctly demonstrates the new create() API with proper import, options, and result handling.


148-179: LGTM!

The CreateInput type definition is properly updated with the new fields: template, typed auth (string union instead of boolean), payments, and manualDb.

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/cli/templates/frontend/react/next/next.config.ts.hbs (1)

20-22: Move initOpenNextCloudflareForDev() to execute before the config export.

The function must be called immediately after its import and before export default nextConfig per OpenNext Cloudflare documentation. Currently at lines 20-22 (after export), it should be at line 18 (before export):

{{#if (eq webDeploy "alchemy")}}
initOpenNextCloudflareForDev();
{{/if}}

export default nextConfig;
🧹 Nitpick comments (1)
apps/cli/src/helpers/core/workspace-setup.ts (1)

55-55: Consider computing runtime dev dependencies once.

getRuntimeDevDeps(runtime, backend) is called twice (lines 55 and 197) for the env package and root project respectively. While both calls are intentional and correct, you could optimize by computing once at the function's beginning and reusing the result.

🔎 Optional refactor to reduce duplication
 export async function setupWorkspaceDependencies(projectDir: string, options: ProjectConfig) {
   const { projectName, packageManager, database, auth, api, runtime, backend } = options;
   const workspaceVersion = packageManager === "npm" ? "*" : "workspace:*";
+  const runtimeDevDeps = getRuntimeDevDeps(runtime, backend);

   const commonDeps: AvailableDependencies[] = ["dotenv", "zod"];
   const commonDevDeps: AvailableDependencies[] = ["typescript"];

Then remove the duplicate declaration at line 55 and line 197.

Also applies to: 197-197

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6781043 and 6141419.

📒 Files selected for processing (14)
  • apps/cli/src/constants.ts
  • apps/cli/src/helpers/core/env-setup.ts
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs
  • apps/cli/templates/auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs
  • apps/cli/templates/examples/ai/web/nuxt/app/pages/ai.vue.hbs
  • apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs
  • apps/cli/templates/frontend/react/next/next.config.ts.hbs
  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/templates/packages/env/src/native.ts.hbs
  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
💤 Files with no reviewable changes (1)
  • apps/cli/src/helpers/core/env-setup.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/packages/env/src/native.ts.hbs
🧰 Additional context used
📓 Path-based instructions (6)
**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.hbs: In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle
Escape the '{{' in Handlebars templates like '{{'

Files:

  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/templates/auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs
  • apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs
  • apps/cli/templates/examples/ai/web/nuxt/app/pages/ai.vue.hbs
  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs
  • apps/cli/templates/frontend/react/next/next.config.ts.hbs
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions

Files:

  • apps/cli/src/constants.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/core/template-manager.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations
Do not use explicit return types

Files:

  • apps/cli/src/constants.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/core/template-manager.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{ts,tsx,js,jsx}: Use bun <file> instead of node <file> or ts-node <file> for running TypeScript/JavaScript files
Bun automatically loads .env files, so don't use the dotenv package
Use Bun.serve() which supports WebSockets, HTTPS, and routes instead of express
Use bun:sqlite module for SQLite instead of better-sqlite3
Use Bun.redis for Redis instead of ioredis
Use Bun.sql for Postgres instead of pg or postgres.js
Use built-in WebSocket instead of the ws package
Prefer Bun.file over node:fs readFile/writeFile methods
Use Bun.$ template literal syntax instead of execa for shell command execution
Import .css files directly in TypeScript/JavaScript files; Bun's CSS bundler will handle bundling
Run server with bun --hot <file> to enable hot reloading during development

Files:

  • apps/cli/src/constants.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/core/template-manager.ts
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file> instead of webpack or esbuild for bundling TypeScript, JavaScript, and CSS files

Files:

  • apps/cli/src/constants.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/core/template-manager.ts
**/*.{html,tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use HTML imports with Bun.serve() for frontend instead of Vite

Files:

  • apps/cli/src/constants.ts
  • apps/cli/src/utils/setup-catalogs.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/src/helpers/core/template-manager.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/templates/packages/env/src/server.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

Applied to files:

  • apps/cli/templates/packages/env/package.json.hbs
  • apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs
  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/templates/frontend/react/next/next.config.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{html,tsx,ts,jsx,js} : Use HTML imports with `Bun.serve()` for frontend instead of Vite

Applied to files:

  • apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs
  • apps/cli/templates/frontend/react/next/next.config.ts.hbs
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : Escape the '{{' in Handlebars templates like '\{{'

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
📚 Learning: 2025-06-08T17:57:33.083Z
Learnt from: Vijayabaskar56
Repo: AmanVarshney01/create-better-t-stack PR: 310
File: apps/cli/templates/frontend/angular/src/app.component.html:1-7
Timestamp: 2025-06-08T17:57:33.083Z
Learning: The Angular frontend template uses Tailwind CSS v4, which doesn't require a traditional tailwind.config.js configuration file.

Applied to files:

  • apps/cli/templates/frontend/react/next/next.config.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Import .css files directly in TypeScript/JavaScript files; Bun's CSS bundler will handle bundling

Applied to files:

  • apps/cli/templates/frontend/react/next/next.config.ts.hbs
🧬 Code graph analysis (2)
apps/cli/src/helpers/core/workspace-setup.ts (2)
apps/cli/src/constants.ts (1)
  • AvailableDependencies (181-181)
apps/cli/src/utils/add-package-deps.ts (1)
  • addPackageDependency (6-57)
apps/cli/src/helpers/core/template-manager.ts (2)
packages/types/src/types.ts (1)
  • ProjectConfig (50-50)
apps/cli/src/constants.ts (1)
  • PKG_ROOT (7-7)
🔇 Additional comments (19)
apps/cli/templates/frontend/react/next/next.config.ts.hbs (2)

9-15: LGTM! Formatting changes improve readability.

The conditional blocks use explicit conditions as required by the Handlebars coding guidelines, and the repositioning maintains clear separation between different configuration concerns.


1-1: LGTM! Environment validation import aligns with PR objectives.

The unconditional import of the env/web module ensures environment variables are validated on every Next.js configuration load, which helps catch configuration issues early. The env/web package exists in the templates, and all conditional blocks throughout the file use explicit conditions as required.

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

1-1: No changes needed. The useRuntimeConfig composable is auto-imported in Nuxt 3 by default and is correctly called inside the defineNuxtPlugin callback function. This pattern is standard across all Nuxt plugin templates in the repository.

Likely an incorrect or invalid review comment.

apps/cli/templates/examples/ai/web/nuxt/app/pages/ai.vue.hbs (1)

15-15: LGTM! Correct use of runtime config for server URL.

The change to use config.public.NUXT_PUBLIC_SERVER_URL aligns with the env-based URL sourcing pattern introduced in this PR.

apps/cli/templates/auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs (1)

6-10: LGTM! Clean refactor aligning with env-based config.

The removal of the unused nuxtApp parameter and the switch to config.public.NUXT_PUBLIC_SERVER_URL for the baseURL are both correct improvements that align with the env package migration.

apps/cli/src/utils/setup-catalogs.ts (1)

34-34: LGTM! Correct integration of the new env package.

Adding "packages/env" to the packagePaths ensures the new environment package is properly included in the catalog dependency analysis and integration workflow.

apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs (2)

1-2: LGTM! Proper env validation integration.

The import of @{{projectName}}/env/web ensures environment variable validation occurs at application startup, providing early detection of configuration issues.


22-28: LGTM! Correct runtime config structure.

The else branch properly handles non-Convex backends by exposing the server URL through Nuxt's runtime config, making it available to the client-side code via useRuntimeConfig().

apps/cli/templates/packages/env/package.json.hbs (1)

1-7: LGTM! Correct template structure with programmatic export population.

The minimal package.json template with an empty exports object is correct. The exports are populated programmatically in template-manager.ts (lines 323-339), which addresses the previous concern about trailing commas in conditionally generated exports.

apps/cli/src/helpers/core/template-manager.ts (2)

266-341: LGTM! Well-structured env package setup logic.

The setupEnvPackage function correctly:

  • Detects when an env package is needed based on frontend and backend configuration
  • Conditionally copies template files (server/web/native) as required
  • Programmatically populates the package.json exports to avoid invalid JSON with trailing commas
  • Properly excludes env setup for Convex backend and Workers runtime

The implementation is clean and handles all the necessary edge cases.


345-345: LGTM! Correct placement in setup sequence.

Calling setupEnvPackage after setupConfigPackage and before backend-specific setup ensures the environment validation package is available when needed by subsequent setup steps.

apps/cli/templates/packages/env/src/server.ts.hbs (2)

1-5: LGTM! Correct setup for environment validation.

The imports and createEnv initialization properly use @t3-oss/env-core with Zod for type-safe environment variable validation. The project uses Zod v4.1.13, which supports the features used in this template.


6-31: The server schema is well-structured with appropriate validation:

  • Security: BETTER_AUTH_SECRET requires minimum 32 characters
  • Type safety: URLs validated with Zod's z.url()
  • Good practices: emptyStringAsUndefined: true and explicit conditionals
  • CORS_ORIGIN: z.url() correctly validates a single URL origin, which is what all backend frameworks (Express, Fastify, Elysia, Hono, and better-auth) expect
apps/cli/src/constants.ts (1)

167-174: Dependencies are current and secure.

Verification confirms alchemy 0.82.1 is the latest stable version, and @t3-oss/env-* packages using ^0.13.1 will resolve to their latest patches (0.13.10) on installation. No known direct security vulnerabilities were found for these packages. The caret constraint appropriately allows patch-level updates while maintaining stability.

apps/cli/src/helpers/core/workspace-setup.ts (5)

15-15: LGTM! Consistent package existence pattern.

The env package path and existence check follow the same pattern as other packages in the workspace.

Also applies to: 26-26, 36-36


50-52: LGTM! Consistent dependency map pattern.

The envDep creation follows the same pattern as configDep, ensuring consistent workspace dependency handling.


89-89: LGTM! Correct env package propagation.

The envDep is correctly propagated to all relevant packages (db, auth, api, server, web, native), ensuring they can import from the new env package. The implementation is consistent across all packages.

Also applies to: 96-96, 111-111, 138-138, 159-159, 180-180


206-223: LGTM! Clean runtime dependency resolution.

The getRuntimeDevDeps function correctly maps runtime and backend configurations to appropriate TypeScript type packages.


54-83: The logic for selecting T3 Env packages conflicts with recommended monorepo architecture.

According to T3 Env's official guidance for monorepos, each package should declare only the env package it needs in its own dependency set:

  • Frontend packages (Next.js apps) should use only @t3-oss/env-nextjs
  • Backend services should use only @t3-oss/env-core
  • Shared validators should be in a separate shared package

The current code (lines 62-75) adds both @t3-oss/env-nextjs and @t3-oss/env-core to the same t3EnvDeps array, which creates an incorrect dependency structure. The logic should instead determine whether envDir is a frontend or backend package and install only the appropriate package, not both.

⛔ Skipped due to learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

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: 3

🧹 Nitpick comments (4)
apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs (1)

7-11: Inconsistent fallback handling between runtime branches.

The non-workers path (line 8) uses env.DATABASE_URL directly, while the workers path (line 31) uses env.DATABASE_URL || "". Since the env package validates DATABASE_URL with z.string().min(1), the fallback should be unnecessary in both cases.

Consider removing the fallback for consistency:

🔎 Proposed fix
 const client = createClient({
-	url: env.DATABASE_URL || "",
+	url: env.DATABASE_URL,
 {{#if (eq dbSetup "turso")}}
 	authToken: env.DATABASE_AUTH_TOKEN,
 {{/if}}
 });

Also applies to: 30-34

apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs (2)

36-42: Inconsistent fallback handling in workers paths.

Similar to the SQLite template, the workers paths use || "" fallbacks (lines 36, 42) while the non-workers paths (lines 15, 20) don't. Since the env validation ensures DATABASE_URL is always a non-empty string, consider removing the fallbacks for consistency.

🔎 Proposed fix
-const sql = neon(env.DATABASE_URL || "");
+const sql = neon(env.DATABASE_URL);
 export const db = drizzle(sql, { schema });
 {{else}}
 import { drizzle } from "drizzle-orm/node-postgres";
 import { env } from "@{{projectName}}/env/server";

-export const db = drizzle(env.DATABASE_URL || "", { schema });
+export const db = drizzle(env.DATABASE_URL, { schema });

44-44: Missing newline at end of file.

Add a trailing newline after the final {{/if}} for POSIX compliance.

apps/cli/templates/db/prisma/mysql/src/index.ts.hbs (1)

8-13: Inconsistent fallback handling between workers and non-workers paths.

Similar pattern to the Drizzle templates: workers paths (lines 8, 13) use || "" fallbacks while non-workers paths (lines 35, 40) access env.DATABASE_URL directly. Since env validation ensures the URL is present, consider unifying the approach.

🔎 Proposed fix for workers path
-const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL || "" });
+const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL });
-const databaseUrl: string = env.DATABASE_URL || "";
+const databaseUrl: string = env.DATABASE_URL;

Also applies to: 35-40

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6141419 and 9448b12.

📒 Files selected for processing (15)
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/base/tsconfig.json.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/prisma/mysql/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs
  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/packages/env/tsconfig.json.hbs
✅ Files skipped from review due to trivial changes (2)
  • apps/cli/templates/packages/env/tsconfig.json.hbs
  • apps/cli/templates/base/tsconfig.json.hbs
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
🧰 Additional context used
📓 Path-based instructions (6)
**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.hbs: In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle
Escape the '{{' in Handlebars templates like '{{'

Files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/prisma/mysql/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations
Do not use explicit return types

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{ts,tsx,js,jsx}: Use bun <file> instead of node <file> or ts-node <file> for running TypeScript/JavaScript files
Bun automatically loads .env files, so don't use the dotenv package
Use Bun.serve() which supports WebSockets, HTTPS, and routes instead of express
Use bun:sqlite module for SQLite instead of better-sqlite3
Use Bun.redis for Redis instead of ioredis
Use Bun.sql for Postgres instead of pg or postgres.js
Use built-in WebSocket instead of the ws package
Prefer Bun.file over node:fs readFile/writeFile methods
Use Bun.$ template literal syntax instead of execa for shell command execution
Import .css files directly in TypeScript/JavaScript files; Bun's CSS bundler will handle bundling
Run server with bun --hot <file> to enable hot reloading during development

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file> instead of webpack or esbuild for bundling TypeScript, JavaScript, and CSS files

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{html,tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use HTML imports with Bun.serve() for frontend instead of Vite

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : Escape the '{{' in Handlebars templates like '\{{'

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs
  • apps/cli/src/helpers/core/workspace-setup.ts
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun:sqlite` module for SQLite instead of `better-sqlite3`

Applied to files:

  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.sql` for Postgres instead of `pg` or `postgres.js`

Applied to files:

  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:14.714Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-12-03T07:48:14.714Z
Learning: Applies to convex/schema.ts : Always define your schema in convex/schema.ts and import schema definition functions from convex/server

Applied to files:

  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use built-in `WebSocket` instead of the `ws` package

Applied to files:

  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{html,tsx,ts,jsx,js} : Use HTML imports with `Bun.serve()` for frontend instead of Vite

Applied to files:

  • apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs
🧬 Code graph analysis (2)
apps/cli/src/helpers/core/template-manager.ts (2)
packages/types/src/types.ts (1)
  • ProjectConfig (50-50)
apps/cli/src/constants.ts (1)
  • PKG_ROOT (7-7)
apps/cli/src/helpers/core/workspace-setup.ts (2)
apps/cli/src/constants.ts (1)
  • AvailableDependencies (181-181)
apps/cli/src/utils/add-package-deps.ts (1)
  • addPackageDependency (6-57)
🔇 Additional comments (18)
apps/cli/templates/db/prisma/postgres/src/index.ts.hbs (2)

3-3: LGTM! Import path correctly updated.

The migration from cloudflare:workers to the new @{{projectName}}/env/server package is consistent across both runtime branches and aligns with the PR's objective to standardize environment variable handling.

Also applies to: 36-36


46-46: Implementation is correct. The env.DATABASE_URL usage without fallback at lines 46, 55, and 63 is appropriate because the env package validates DATABASE_URL as a required field (using z.string().min(1) in the server env schema).

apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs (2)

3-8: LGTM: Excellent environment variable handling pattern!

The migration from alchemy.env.* to dedicated env packages shows strong architectural improvements:

  • Clear separation: webEnv for public client-side variables vs env for server-side variables
  • Security: Consistent use of alchemy.secret() wrapper for sensitive values (DATABASE_URL, auth secrets, API keys, passwords)
  • Type safety: The validated env packages provide compile-time type checking
  • Maintainability: Centralized environment validation in the new env package

The pattern is consistently applied across all framework variants (Next.js, Nuxt, SvelteKit, TanStack Start/Router, React Router, Solid), which ensures uniformity in the generated projects.

Also applies to: 59-255


2-2: Remove review comment - dotenv is necessary in this context.

The dotenv package is required here. While the learning notes that Bun automatically loads .env files in standard applications, this is a deployment configuration that must explicitly load multiple .env files for the monorepo structure (./.env, ./apps/web/.env, ./apps/server/.env). The custom env modules (env/server, env/web) imported in this file depend on dotenv being called before they are imported, so their validation logic can access the loaded environment variables. Bun's automatic loading applies only to the root .env file in direct execution contexts and does not handle the explicit multi-path loading required by this monorepo deployment setup.

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

54-83: LGTM!

The env package dependency setup correctly:

  • Determines the appropriate T3 Env package based on frontend choice (Next.js → @t3-oss/env-nextjs, Nuxt → @t3-oss/env-nuxt, others → @t3-oss/env-core)
  • Adds @t3-oss/env-core for server-side validation when needed (non-Convex backend, non-workers runtime)
  • Properly wires up dev dependencies including runtime-specific types

85-195: LGTM!

The envDep is correctly propagated to all dependent packages (db, auth, api, server, web, native) using object spread, ensuring the centralized env package is available wherever environment variables are accessed.

apps/cli/templates/packages/env/src/server.ts.hbs (1)

1-37: LGTM!

The server env template correctly:

  • Re-exports env from cloudflare:workers for Workers runtime (where bindings come from platform)
  • Uses @t3-oss/env-core with proper Zod v4 validators (z.url(), z.string().min()) for other runtimes
  • Conditionally includes database, auth, and payment environment variables based on project configuration
  • Sets sensible defaults (NODE_ENV defaults to "development")

Note: The Handlebars conditionals ({{#if}}, {{/if}}) are correctly unescaped as they need to be processed by the template engine. Only literal {{ in the output would need escaping.

apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs (1)

1-25: LGTM!

The Prisma SQLite template correctly migrates to the centralized env module for both D1 and LibSQL adapters. The || "" fallback on authToken (line 18) is acceptable as defensive coding since the auth token is only required for Turso setups.

apps/cli/templates/packages/env/src/web.ts.hbs (2)

62-87: Verify handling when backend is "self".

The condition {{else if (ne backend "self")}} (line 62) means the NEXT_PUBLIC_SERVER_URL / VITE_SERVER_URL configuration is skipped when backend === "self". This seems intentional since "self" implies a fullstack app where the server is co-located, but verify this doesn't break any use cases where the frontend still needs to know the server URL.


1-89: LGTM!

The web env template provides comprehensive client-side environment validation with:

  • Correct framework-specific imports (@t3-oss/env-nextjs, env-nuxt, env-core)
  • Appropriate client prefixes for each framework (NEXT_PUBLIC_, NUXT_PUBLIC_, PUBLIC_, VITE_)
  • Proper runtimeEnv sources (process.env for Next.js, import.meta.env for Vite-based frameworks)
  • Zod v4 validators (z.url(), z.string().min())
apps/cli/src/helpers/core/template-manager.ts (3)

266-340: LGTM!

The setupEnvPackage function is well-structured:

  • Correctly identifies when to create the env package (has web frontend, native app, or non-"none" backend)
  • Excludes Convex backend from server env (line 296) since Convex manages its own environment
  • Dynamically builds package.json exports based on which env files were generated
  • Creates only the necessary env modules (server/web/native) based on project configuration

342-344: LGTM!

Good placement of setupEnvPackage early in setupBackendFramework to ensure the env package is scaffolded before other packages that depend on it.


972-982: LGTM!

The simplified addEnvDtsToPackages now targets only packages/env, which aligns with the centralized env architecture. This is cleaner than the previous approach of adding env.d.ts to multiple packages.

apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs (5)

4-4: LGTM: Centralized environment variable management.

The migration from direct process.env access to a centralized env module is a good practice that improves type safety, validation, and maintainability across the codebase.

Also applies to: 65-65, 126-126, 201-201, 255-255


18-23: LGTM: Consistent env-based configuration across all branches.

The trustedOrigins and Polar plugin configurations consistently use env-based values (env.CORS_ORIGIN, env.POLAR_SUCCESS_URL) across all ORM and runtime branches. The conditional inclusion of native frontend origins is properly handled.

Also applies to: 80-85, 141-146, 210-215, 263-268, 50-50, 112-112, 186-186, 242-242, 295-295


1-304: LGTM: Handlebars template follows coding guidelines.

All conditional blocks use explicit comparisons (e.g., eq, ne, includes) as required by the coding guidelines. The template structure is clear and maintainable.

As per coding guidelines.


262-262: LGTM: Intentional invalid placeholder for "none" ORM.

The empty database string with the "Invalid configuration" comment appropriately signals that a proper database configuration is required. This is a clear placeholder for the "none" ORM scenario.


74-79: Provider strings and MongoDB support are correctly implemented.

The Drizzle adapter configuration is correct:

  • Provider strings "pg", "sqlite", and "mysql" match Better Auth's Drizzle adapter specification.
  • MongoDB absence is intentional; the Drizzle adapter does not support MongoDB. When MongoDB is selected as the database, the template uses mongodbAdapter (via Mongoose) instead, which is the appropriate adapter for MongoDB.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/cli/templates/db/prisma/mysql/src/index.ts.hbs (1)

1-27: Remove unnecessary || "" fallbacks in workers branch.

The workers branch (lines 8, 13) uses env.DATABASE_URL || "" while the non-workers branch (lines 35, 40) correctly uses env.DATABASE_URL without fallback. Since the env package validates DATABASE_URL as required, these fallbacks are unnecessary and create inconsistency.

🔎 Proposed fix
-const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL || "" });
+const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL });
-const databaseUrl: string = env.DATABASE_URL || "";
+const databaseUrl: string = env.DATABASE_URL;
♻️ Duplicate comments (3)
apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs (2)

12-17: Refactor: Use if/else-if chain for provider assignment.

Per coding guidelines, use explicit if/else-if conditions instead of separate {{#if}} blocks since only one database value can be true at a time.

🔎 Suggested refactor
{{#if (eq database "postgres")}}
		provider: "postgresql",
{{else if (eq database "sqlite")}}
		provider: "sqlite",
{{else if (eq database "mysql")}}
		provider: "mysql",
{{else if (eq database "mongodb")}}
		provider: "mongodb",
{{/if}}

Apply same pattern to lines 75-78 and 136-139.


11-58: Missing secret and baseURL configuration for Prisma block.

The workers block (lines 157-158) correctly includes secret and baseURL, but this Prisma non-workers block is missing them. Better Auth documentation requires these fields for production deployments across all runtimes for proper signing/encryption and redirect handling.

🔎 Proposed fix

Add after line 26 (before the {{#if (eq payments "polar")}} block):

	secret: env.BETTER_AUTH_SECRET,
	baseURL: env.BETTER_AUTH_URL,

Apply the same fix to:

  • Drizzle non-workers block (after line 97)
  • Mongoose block (after line 227)
  • None/ORM block (after line 280)
apps/cli/templates/db/prisma/postgres/src/index.ts.hbs (1)

10-14: Remove dangerous || "" fallbacks in workers branches.

This issue was previously identified. The workers branches (lines 12, 20, 28) use env.DATABASE_URL || "" while non-workers branches correctly omit the fallback. Since the env package validates DATABASE_URL as required with z.string().min(1), these fallbacks are unnecessary and could mask configuration errors by providing an empty connection string that will fail at runtime.

🧹 Nitpick comments (3)
apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs (1)

18-18: Consider removing the || "" fallback.

Since the env package validates DATABASE_AUTH_TOKEN with z.string().min(1) when dbSetup is "turso", the fallback is unnecessary—validation will fail before this code runs if the token is missing. Removing it would be consistent with the non-workers branches in other templates.

🔎 Suggested change
-	authToken: env.DATABASE_AUTH_TOKEN || "",
+	authToken: env.DATABASE_AUTH_TOKEN,
apps/cli/src/helpers/core/template-manager.ts (2)

301-301: Consolidate redundant directory creation calls.

The src directory within envPackageDir is created three times (lines 301, 309, 317). Move this call before the conditional blocks to avoid redundancy.

🔎 Proposed refactor
  const needsServerEnv = context.backend !== "none" && context.backend !== "convex";

+ await fs.ensureDir(path.join(envPackageDir, "src"));
+
  if (needsServerEnv) {
    const serverSrc = path.join(envBaseDir, "src/server.ts.hbs");
    if (await fs.pathExists(serverSrc)) {
-     await fs.ensureDir(path.join(envPackageDir, "src"));
      await processAndCopyFiles("src/server.ts.hbs", envBaseDir, envPackageDir, context);
    }
  }

  if (hasWebFrontend) {
    const webSrc = path.join(envBaseDir, "src/web.ts.hbs");
    if (await fs.pathExists(webSrc)) {
-     await fs.ensureDir(path.join(envPackageDir, "src"));
      await processAndCopyFiles("src/web.ts.hbs", envBaseDir, envPackageDir, context);
    }
  }

  if (hasNative) {
    const nativeSrc = path.join(envBaseDir, "src/native.ts.hbs");
    if (await fs.pathExists(nativeSrc)) {
-     await fs.ensureDir(path.join(envPackageDir, "src"));
      await processAndCopyFiles("src/native.ts.hbs", envBaseDir, envPackageDir, context);
    }
  }

Also applies to: 309-309, 317-317


298-320: Consider extracting repeated template copying logic.

The pattern for checking template existence and copying files is repeated for server, web, and native templates. Consider extracting this into a helper function to reduce duplication.

Example refactor approach
async function copyEnvTemplate(
  envBaseDir: string,
  envPackageDir: string,
  templateName: string,
  context: ProjectConfig
) {
  const templateSrc = path.join(envBaseDir, `src/${templateName}.ts.hbs`);
  if (await fs.pathExists(templateSrc)) {
    await processAndCopyFiles(`src/${templateName}.ts.hbs`, envBaseDir, envPackageDir, context);
  }
}

// Then use it as:
if (needsServerEnv) {
  await copyEnvTemplate(envBaseDir, envPackageDir, "server", context);
}
if (hasWebFrontend) {
  await copyEnvTemplate(envBaseDir, envPackageDir, "web", context);
}
if (hasNative) {
  await copyEnvTemplate(envBaseDir, envPackageDir, "native", context);
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9448b12 and 9e42506.

📒 Files selected for processing (14)
  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/base/tsconfig.json.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/prisma/mysql/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
  • apps/cli/templates/packages/env/tsconfig.json.hbs
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/cli/templates/packages/env/tsconfig.json.hbs
  • apps/cli/templates/backend/server/hono/src/index.ts.hbs
  • apps/cli/templates/base/tsconfig.json.hbs
  • apps/cli/templates/db/drizzle/mysql/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/drizzle/postgres/src/index.ts.hbs
  • apps/cli/templates/packages/env/src/web.ts.hbs
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

Define functions using the standard function declaration syntax, not arrow functions

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations
Do not use explicit return types

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{ts,tsx,js,jsx}: Use bun <file> instead of node <file> or ts-node <file> for running TypeScript/JavaScript files
Bun automatically loads .env files, so don't use the dotenv package
Use Bun.serve() which supports WebSockets, HTTPS, and routes instead of express
Use bun:sqlite module for SQLite instead of better-sqlite3
Use Bun.redis for Redis instead of ioredis
Use Bun.sql for Postgres instead of pg or postgres.js
Use built-in WebSocket instead of the ws package
Prefer Bun.file over node:fs readFile/writeFile methods
Use Bun.$ template literal syntax instead of execa for shell command execution
Import .css files directly in TypeScript/JavaScript files; Bun's CSS bundler will handle bundling
Run server with bun --hot <file> to enable hot reloading during development

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{ts,tsx,js,jsx,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file> instead of webpack or esbuild for bundling TypeScript, JavaScript, and CSS files

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.{html,tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use HTML imports with Bun.serve() for frontend instead of Vite

Files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.hbs: In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle
Escape the '{{' in Handlebars templates like '{{'

Files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
  • apps/cli/templates/db/prisma/mysql/src/index.ts.hbs
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

Applied to files:

  • apps/cli/src/helpers/core/template-manager.ts
  • apps/cli/src/helpers/core/workspace-setup.ts
  • apps/cli/templates/packages/env/src/server.ts.hbs
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : Escape the '{{' in Handlebars templates like '\{{'

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.sql` for Postgres instead of `pg` or `postgres.js`

Applied to files:

  • apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs
  • apps/cli/templates/db/prisma/postgres/src/index.ts.hbs
  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `bun:sqlite` module for SQLite instead of `better-sqlite3`

Applied to files:

  • apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs
🧬 Code graph analysis (2)
apps/cli/src/helpers/core/template-manager.ts (2)
packages/types/src/types.ts (1)
  • ProjectConfig (50-50)
apps/cli/src/constants.ts (1)
  • PKG_ROOT (7-7)
apps/cli/src/helpers/core/workspace-setup.ts (2)
apps/cli/src/constants.ts (1)
  • AvailableDependencies (181-181)
apps/cli/src/utils/add-package-deps.ts (1)
  • addPackageDependency (6-57)
🔇 Additional comments (13)
apps/cli/templates/packages/env/src/server.ts.hbs (1)

1-37: Well-structured environment validation template.

The template correctly implements conditional environment schema generation based on runtime, database setup, auth, and payments configuration. The Zod schemas are appropriate, and z.url() is valid for Zod 4.2.1 being used.

Note: The past review comment about escaping {{ is incorrect for this context—these are intentional Handlebars directives that should not be escaped. Escaping them would break the template.

Consider adding a trailing newline at the end of the file for POSIX compliance.

apps/cli/src/helpers/core/workspace-setup.ts (4)

54-83: LGTM! Env package dependency setup is well-structured.

The logic correctly:

  • Determines T3 Env package based on frontend (Next.js → @t3-oss/env-nextjs, Nuxt → @t3-oss/env-nuxt, otherwise → @t3-oss/env-core)
  • Adds @t3-oss/env-core for server-side env when backend requires it (not convex/none and not workers)
  • Includes appropriate runtime dev dependencies

The intentional omission of envDep from backendExists block (lines 128-135) is correct since Convex handles environment configuration differently.


85-93: LGTM! Env dependency propagation to db package.

Correctly adds envDep as a custom dependency when env package exists.


95-108: LGTM! Auth dependencies correctly include env.

The spread of envDep into authDeps ensures auth package can access validated environment variables.


199-205: LGTM! Root package includes env dependency.

Correctly propagates envDep to the root workspace package.json.

apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs (1)

261-262: Intentionally invalid database placeholder in orm: "none" case.

The database: "" configuration is explicitly marked as invalid. Consider adding a more descriptive comment or throwing an error at build time to prevent accidental deployment without a database adapter.

apps/cli/templates/db/prisma/sqlite/src/index.ts.hbs (1)

1-25: LGTM! SQLite/Turso env integration is correct.

The template correctly imports from the centralized env package and uses validated environment variables for both D1 and LibSQL/Turso adapters.

apps/cli/templates/db/prisma/mysql/src/index.ts.hbs (1)

28-55: LGTM! Non-workers branch correctly uses validated env.

The non-workers path properly uses env.DATABASE_URL without fallbacks, trusting the env package validation.

apps/cli/templates/db/prisma/postgres/src/index.ts.hbs (1)

34-68: LGTM! Non-workers branch correctly uses validated env.

The non-workers paths properly trust the env package validation and use env.DATABASE_URL directly without fallbacks across all dbSetup configurations (neon, prisma-postgres, default).

apps/cli/src/helpers/core/template-manager.ts (4)

344-344: LGTM! Env package setup properly integrated.

The setupEnvPackage call is correctly positioned after config package setup and before backend-specific setup. The function has appropriate guard logic to handle cases where the env package isn't needed.


977-982: LGTM! Simplified to target centralized env package.

The refactoring to focus solely on packages/env aligns with the PR's objective of introducing a centralized environment package. The logic correctly checks for the package's existence before processing the env.d.ts template.


266-340: AI summary inconsistency: No duplicate declaration found.

The AI summary claims there's a duplicate declaration of setupEnvPackage within this file, but only one declaration is visible at line 266. This discrepancy should be noted.


322-339: Add safety check before reading package.json.

If the template at line 292 doesn't exist, package.json won't be created, causing fs.readJson to fail at line 324. Add a guard to ensure the file exists before reading it.

🔎 Proposed fix
  const packageJsonPath = path.join(envPackageDir, "package.json");
  if (await fs.pathExists(packageJsonPath)) {
    const packageJson = await fs.readJson(packageJsonPath);
    const exports: Record<string, string> = {};

    if (needsServerEnv) {
      exports["./server"] = "./src/server.ts";
    }
    if (hasWebFrontend) {
      exports["./web"] = "./src/web.ts";
    }
    if (hasNative) {
      exports["./native"] = "./src/native.ts";
    }

    packageJson.exports = exports;
    await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
+ } else {
+   console.warn("package.json template not found for env package");
  }
⛔ Skipped due to learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

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: 0

🧹 Nitpick comments (3)
apps/cli/templates/packages/env/src/server.ts.hbs (3)

1-6: Use explicit conditions instead of generic {{else}} block.

Per coding guidelines, Handlebars templates should avoid generic if/else blocks and use explicit conditions for clarity.

🔎 Suggested change
 {{#if (eq serverDeploy "alchemy")}}
 /// <reference path="../env.d.ts" />
 // For Cloudflare Workers, env is accessed via cloudflare:workers module
 // Types are defined in env.d.ts based on your alchemy.run.ts bindings
 export { env } from "cloudflare:workers";
-{{else}}
+{{else if (ne serverDeploy "alchemy")}}

12-22: Use explicit condition instead of generic {{else}}.

Line 17 uses a generic {{else}} block. Per coding guidelines, use explicit conditions for better readability.

🔎 Suggested change
 {{#if (ne database "none")}}
 {{#if (eq dbSetup "planetscale")}}
 		DATABASE_HOST: z.string().min(1),
 		DATABASE_USERNAME: z.string().min(1),
 		DATABASE_PASSWORD: z.string().min(1),
-{{else}}
+{{else if (ne dbSetup "planetscale")}}
 		DATABASE_URL: z.string().min(1),
 {{#if (eq dbSetup "turso")}}
 		DATABASE_AUTH_TOKEN: z.string().min(1),
 {{/if}}
 {{/if}}
 {{/if}}

37-38: Add trailing newline.

The file ends without a trailing newline. Most code style conventions expect files to end with a newline character.

🔎 Suggested change
 });
 {{/if}}
+
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e42506 and e45d203.

📒 Files selected for processing (1)
  • apps/cli/templates/packages/env/src/server.ts.hbs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)

**/*.hbs: In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle
Escape the '{{' in Handlebars templates like '{{'

Files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use `Bun.$` template literal syntax instead of `execa` for shell command execution
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to package.json : Use `bun run <script>` instead of `npm run <script>`, `yarn run <script>`, or `pnpm run <script>`
📚 Learning: 2025-12-03T07:48:26.419Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-12-03T07:48:26.419Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Bun automatically loads .env files, so don't use the dotenv package

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : Escape the '{{' in Handlebars templates like '\{{'

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
📚 Learning: 2025-12-03T07:47:42.038Z
Learnt from: CR
Repo: AmanVarshney01/create-better-t-stack PR: 0
File: .cursor/rules/better-t-stack-repo.mdc:0-0
Timestamp: 2025-12-03T07:47:42.038Z
Learning: Applies to **/*.hbs : In Handlebars templates, avoid generic if/else blocks. Write explicit conditions, such as: use if (eq orm "prisma") for Prisma, and else if (eq orm "drizzle") for Drizzle

Applied to files:

  • apps/cli/templates/packages/env/src/server.ts.hbs
🔇 Additional comments (2)
apps/cli/templates/packages/env/src/server.ts.hbs (2)

35-38: LGTM!

The runtimeEnv: process.env and emptyStringAsUndefined: true configuration is correct for @t3-oss/env-core. The emptyStringAsUndefined option properly handles empty env vars as undefined, which pairs well with the .min(1) validators.


26-32: No action required. The Zod version constraint is already correctly specified in apps/cli/src/constants.ts as zod: "^4.1.13", which ensures all generated projects support z.url() and other v4 helpers used in the template.

@AmanVarshney01 AmanVarshney01 merged commit d04f045 into main Dec 25, 2025
4 checks passed
@AmanVarshney01 AmanVarshney01 deleted the env-package branch December 25, 2025 22:04
@dosubot dosubot bot mentioned this pull request Dec 26, 2025
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.

2 participants