-
-
Notifications
You must be signed in to change notification settings - Fork 222
feat(cli): add fullstack tanstack start #613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds TanStack Start as a supported fullstack frontend for self backends across CLI prompts, templates, env handling, and workspace gating; inserts Better Auth plugin auto-configuration during project creation; updates ORPC/TRPC route templates and API-reference prefixes; expands web presets and stack command mapping. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant CLI as CLI:createProject
participant Auth as BetterAuthSetup
participant FS as Filesystem
User->>CLI: create-project
CLI->>CLI: scaffold templates
CLI->>Auth: setupBetterAuthPlugins(projectDir, options)
alt backend != "self" or auth != "better-auth"
Auth-->>CLI: no-op
else
Auth->>FS: open packages/auth/src/index.ts
Auth->>FS: add imports & plugin entries
FS-->>Auth: save file
Auth-->>CLI: done
end
CLI-->>User: completed
sequenceDiagram
autonumber
participant Client
participant Server
participant RPC as RPCHandler
participant OAPI as OpenAPIHandler
Client->>Server: HTTP /api/rpc/...
Server->>RPC: handle(prefix="/api/rpc")
alt RPC matched
RPC-->>Server: response
Server-->>Client: RPC response
else
Server->>OAPI: handle(prefix="/api/rpc/api-reference")
alt OAPI matched
OAPI-->>Server: response
Server-->>Client: API-reference response
else
Server-->>Client: 404
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
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/backend/server/elysia/src/index.ts.hbs (1)
83-89: Update Elysia route pattern to match handler prefix- .all('/api*', async (context) => { + .all('/api-reference*', async (context) => { const { response } = await apiHandler.handle(context.request, { prefix: '/api-reference',
🧹 Nitpick comments (3)
apps/cli/src/helpers/core/post-installation.ts (1)
66-66: Remove unused parameter from function signature.The
_frontendparameter is passed togetNativeInstructionsbut never used in the function body (lines 217-244). While the underscore prefix signals intentional non-use, this adds unnecessary complexity.Apply this diff to remove the unused parameter:
- ? getNativeInstructions(isConvex, isBackendSelf, frontend || []) + ? getNativeInstructions(isConvex, isBackendSelf)function getNativeInstructions( isConvex: boolean, isBackendSelf: boolean, - _frontend: string[], ) {Also applies to: 217-221
apps/web/src/lib/stack-utils.ts (1)
82-88: LGTM! Backend mapping added for new variants.The
mapBackendToClifunction correctly normalizes "self-next" and "self-tanstack-start" to the CLI's "self" backend flag, supporting the new TanStack Start fullstack option.Consider extracting the backend mapping to a constant for easier maintenance:
+const BACKEND_TO_CLI_MAP: Record<string, string> = { + "self-next": "self", + "self-tanstack-start": "self", +}; + // Map web interface backend IDs to CLI backend flags const mapBackendToCli = (backend: string) => { - if (backend === "self-next" || backend === "self-tanstack-start") { - return "self"; - } - return backend; + return BACKEND_TO_CLI_MAP[backend] ?? backend; };apps/web/src/app/(home)/new/_components/utils.ts (1)
203-231: Align the fallback frontend with the selected self backendWhen
self-tanstack-startis selected without a supported frontend, we first force"next"and then immediately switch to"tanstack-start". That produces two change entries and conflicting messaging for the user. Pick the fallback based on the chosen self backend so the compatibility report only shows the final, correct adjustment.- nextStack.webFrontend = ["next"]; + const fallbackFrontendId = isBackendSelfTanstackStart + ? "tanstack-start" + : "next"; + const fallbackFrontendName = + fallbackFrontendId === "tanstack-start" + ? "TanStack Start" + : "Next.js"; + nextStack.webFrontend = [fallbackFrontendId]; ... - "Frontend set to 'Next.js' (Self backend currently only supports Next.js and TanStack Start)", + `Frontend set to '${fallbackFrontendName}' (Self backend currently only supports Next.js and TanStack Start)`,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
apps/cli/src/helpers/core/api-setup.ts(4 hunks)apps/cli/src/helpers/core/create-project.ts(2 hunks)apps/cli/src/helpers/core/env-setup.ts(4 hunks)apps/cli/src/helpers/core/post-installation.ts(3 hunks)apps/cli/src/helpers/core/template-manager.ts(3 hunks)apps/cli/src/helpers/core/workspace-setup.ts(3 hunks)apps/cli/src/prompts/backend.ts(1 hunks)apps/cli/src/utils/better-auth-plugin-setup.ts(1 hunks)apps/cli/src/utils/compatibility-rules.ts(3 hunks)apps/cli/templates/api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs(1 hunks)apps/cli/templates/api/orpc/fullstack/tanstack-start/src/routes/api/rpc/$.ts.hbs(1 hunks)apps/cli/templates/api/orpc/server/src/context.ts.hbs(1 hunks)apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs(3 hunks)apps/cli/templates/api/trpc/fullstack/tanstack-start/src/routes/api/trpc/$.ts.hbs(1 hunks)apps/cli/templates/api/trpc/server/src/context.ts.hbs(1 hunks)apps/cli/templates/auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs(1 hunks)apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs(5 hunks)apps/cli/templates/backend/server/elysia/src/index.ts.hbs(1 hunks)apps/cli/templates/backend/server/express/src/index.ts.hbs(1 hunks)apps/cli/templates/backend/server/fastify/src/index.ts.hbs(1 hunks)apps/cli/templates/backend/server/hono/src/index.ts.hbs(1 hunks)apps/cli/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs(1 hunks)apps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs(1 hunks)apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs(1 hunks)apps/web/src/app/(home)/new/_components/utils.ts(11 hunks)apps/web/src/lib/constant.ts(2 hunks)apps/web/src/lib/stack-utils.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{hbs,handlebars}
📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)
In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).
Files:
apps/cli/templates/backend/server/elysia/src/index.ts.hbsapps/cli/templates/api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbsapps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbsapps/cli/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbsapps/cli/templates/api/trpc/fullstack/tanstack-start/src/routes/api/trpc/$.ts.hbsapps/cli/templates/api/orpc/server/src/context.ts.hbsapps/cli/templates/auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbsapps/cli/templates/auth/better-auth/server/base/src/index.ts.hbsapps/cli/templates/backend/server/express/src/index.ts.hbsapps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbsapps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbsapps/cli/templates/backend/server/hono/src/index.ts.hbsapps/cli/templates/backend/server/fastify/src/index.ts.hbsapps/cli/templates/api/trpc/server/src/context.ts.hbsapps/cli/templates/api/orpc/fullstack/tanstack-start/src/routes/api/rpc/$.ts.hbs
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)
**/*.{ts,tsx}: Use Id from './_generated/dataModel' to type document ids (e.g., Id<'users'>)
Ensure Record key/value types align with validators (e.g., v.record(v.id('users'), v.string()) => Record<Id<'users'>, string>)
Be strict with types for document ids; prefer Id<'table'> over string
Use 'as const' for string literals in discriminated unions
When using Array and Record types, declare with explicit generic types (e.g., const arr: Array = ...)
**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations.
Do not use explicit return types in TypeScript.
Files:
apps/cli/src/helpers/core/template-manager.tsapps/web/src/lib/stack-utils.tsapps/cli/src/helpers/core/env-setup.tsapps/cli/src/prompts/backend.tsapps/web/src/lib/constant.tsapps/cli/src/helpers/core/api-setup.tsapps/cli/src/helpers/core/workspace-setup.tsapps/cli/src/utils/better-auth-plugin-setup.tsapps/cli/src/utils/compatibility-rules.tsapps/web/src/app/(home)/new/_components/utils.tsapps/cli/src/helpers/core/post-installation.tsapps/cli/src/helpers/core/create-project.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
**/*.{js,jsx,ts,tsx,mjs,cjs}: Do not use dotenv; Bun auto-loads .env
UseBun.serve()for HTTP/WebSockets; do not useexpress
Usebun:sqlitefor SQLite; do not usebetter-sqlite3
UseBun.redisfor Redis; do not useioredis
UseBun.sqlfor Postgres; do not usepgorpostgres.js
Use built-inWebSocket; do not usews
PreferBun.fileovernode:fsreadFile/writeFile
UseBun.$instead ofexecafor shelling out
Files:
apps/cli/src/helpers/core/template-manager.tsapps/web/src/lib/stack-utils.tsapps/cli/src/helpers/core/env-setup.tsapps/cli/src/prompts/backend.tsapps/web/src/lib/constant.tsapps/cli/src/helpers/core/api-setup.tsapps/cli/src/helpers/core/workspace-setup.tsapps/cli/src/utils/better-auth-plugin-setup.tsapps/cli/src/utils/compatibility-rules.tsapps/web/src/app/(home)/new/_components/utils.tsapps/cli/src/helpers/core/post-installation.tsapps/cli/src/helpers/core/create-project.ts
**/*.{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.tsapps/web/src/lib/stack-utils.tsapps/cli/src/helpers/core/env-setup.tsapps/cli/src/prompts/backend.tsapps/web/src/lib/constant.tsapps/cli/src/helpers/core/api-setup.tsapps/cli/src/helpers/core/workspace-setup.tsapps/cli/src/utils/better-auth-plugin-setup.tsapps/cli/src/utils/compatibility-rules.tsapps/web/src/app/(home)/new/_components/utils.tsapps/cli/src/helpers/core/post-installation.tsapps/cli/src/helpers/core/create-project.ts
🧬 Code graph analysis (6)
apps/cli/src/helpers/core/template-manager.ts (1)
apps/cli/src/constants.ts (1)
PKG_ROOT(7-7)
apps/cli/src/prompts/backend.ts (1)
apps/cli/src/types.ts (1)
Frontend(37-37)
apps/cli/src/helpers/core/workspace-setup.ts (1)
apps/cli/src/utils/add-package-deps.ts (1)
addPackageDependency(6-59)
apps/cli/src/utils/better-auth-plugin-setup.ts (1)
apps/cli/src/utils/ts-morph.ts (2)
tsProject(10-17)ensureArrayProperty(19-31)
apps/cli/src/utils/compatibility-rules.ts (2)
apps/cli/src/types.ts (1)
Frontend(37-37)apps/cli/test/test-utils.ts (1)
Frontend(203-203)
apps/cli/src/helpers/core/create-project.ts (1)
apps/cli/src/utils/better-auth-plugin-setup.ts (1)
setupBetterAuthPluginsForSelfBackend(83-92)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (21)
apps/cli/src/helpers/core/post-installation.ts (1)
174-174: LGTM: API reference endpoint updates.The URL path updates correctly reflect the new endpoint structure:
- Standalone backend:
/api-referencefor direct API access- Self backend:
/api/rpc/api-referencefor scoped RPC API accessThese changes align with the broader endpoint routing adjustments mentioned in the AI summary.
Also applies to: 179-179
apps/cli/templates/auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs (2)
7-12: Consider adding error handling if required.Both handlers delegate directly to
auth.handler(request)without explicit error handling. While Better Auth likely handles errors internally, verify whether the route should catch and transform errors for consistency with your application's error handling patterns.
4-15: Better Auth routes require only GET and POST.
Official docs confirm GET and POST are the only methods required by Better Auth; no additional HTTP methods needed.apps/cli/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs (1)
13-13: Gemini model identifier is valid
“gemini-2.5-flash” is a supported model name in the @ai-sdk/google as of October 2025. No changes needed.apps/cli/templates/backend/server/hono/src/index.ts.hbs (1)
95-95: LGTM! Consistent API reference routing.The prefix change from "/api" to "/api-reference" aligns with similar updates across other backend templates (express, elysia, fastify) and maintains consistency in API reference endpoint routing.
apps/cli/templates/api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs (1)
38-38: LGTM! Prefix correctly scoped to route location.The prefix "/api/rpc/api-reference" correctly includes the full path from the route file location (/api/rpc/[[...rest]]/route.ts), ensuring API reference requests are properly matched.
apps/cli/templates/backend/server/express/src/index.ts.hbs (1)
89-89: LGTM! Middleware prefix updated correctly.The prefix change is properly applied in the Express middleware flow. The handler will correctly match and strip the "/api-reference" prefix from incoming requests.
apps/cli/templates/backend/server/fastify/src/index.ts.hbs (1)
90-90: LGTM! Server factory prefix updated correctly.The prefix change in the serverFactory pattern is correct. Requests will be processed by the apiHandler with the new "/api-reference" prefix before falling through to Fastify.
apps/web/src/lib/stack-utils.ts (1)
96-96: LGTM! Backend flag generation updated.The backend flag now correctly uses the mapped CLI value, ensuring generated commands work with the CLI's expected backend options.
apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs (1)
88-88: Approve conditional URL; environment configuration for VITE_SERVER_URL is in place.Env-setup maps
hasTanstackStarttoVITE_SERVER_URLwith a default ofhttp://localhost:3000.apps/cli/src/helpers/core/api-setup.ts (1)
71-73: Keep @orpc/server in web dependencies. The web templates importcreateRouterClientandRouterClientfrom@orpc/server.apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs (1)
6-56: LGTM! Well-structured isomorphic client setup.The tanstack-start client implementation correctly uses
createIsomorphicFnto separate server-side and client-side logic. The server path directly creates aRouterClientwith the app router and context, while the client path usesRPCLinkfor HTTP communication. URL construction appropriately uses relative paths for self backends and environment variables for remote backends.apps/web/src/lib/constant.ts (2)
697-723: LGTM! New preset is well-configured.The
tanstack-start-fullstackpreset mirrors thenextjs-fullstackpreset structure with appropriate frontend and backend selections. Configuration is consistent and complete.
205-217: No additional mapping requiredThe
mapBackendToClifunction inapps/web/src/lib/stack-utils.tsalready mapsself-nextandself-tanstack-startto the CLI’sselfbackend flag.apps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs (1)
18-18: LGTM! Correct API endpoint construction.The conditional API path correctly uses
/api/aifor self backends and falls back to the environment variable for remote backends, consistent with the URL patterns used throughout the PR.apps/cli/src/prompts/backend.ts (1)
6-12: LGTM! Expanded fullstack frontend support.The addition of
tanstack-starttoFULLSTACK_FRONTENDScorrectly extends self backend support beyond Next.js, aligning with the PR objectives and related compatibility rule updates.apps/cli/templates/api/trpc/fullstack/tanstack-start/src/routes/api/trpc/$.ts.hbs (1)
1-22: LGTM! Proper TRPC route handler implementation.The route handler correctly sets up TRPC for tanstack-start using
fetchRequestHandlerwith the app router and context. Supporting both GET and POST methods via the same handler is appropriate for TRPC endpoints, and the/api/trpcpath aligns with the URL patterns used in client configurations.apps/cli/src/helpers/core/create-project.ts (1)
90-91: LGTM! Appropriate placement of Better Auth plugin setup.The invocation of
setupBetterAuthPluginsForSelfBackendis correctly positioned after authentication setup and is internally guarded to only execute for self backends with better-auth, preventing unnecessary processing for other configurations.apps/cli/templates/api/orpc/server/src/context.ts.hbs (1)
20-36: LGTM! Context creation aligns with tanstack-start patterns.The new
createContextbranch for tanstack-start correctly accepts aRequestobject and retrieves the session via request headers when better-auth is enabled. The implementation mirrors the Next.js path above and maintains consistency across backend contexts.apps/cli/src/utils/compatibility-rules.ts (2)
46-52: LGTM! Compatibility rules updated correctly.The expansion of
FULLSTACK_FRONTENDSto includetanstack-startis consistent with the changes inprompts/backend.tsand properly extends self backend support.
68-70: LGTM! Clear error messaging for users.The updated error message correctly references both Next.js and TanStack Start with actionable guidance using
--frontendflags, improving the user experience when encountering compatibility issues.
apps/cli/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs
Show resolved
Hide resolved
apps/cli/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs
Show resolved
Hide resolved
134237c to
b3ae935
Compare
| category: "backend", | ||
| message: | ||
| "Frontend set to 'Next.js' (Self backend currently only supports Next.js)", | ||
| "Frontend set to 'Next.js' (Self backend currently only supports Next.js and TanStack Start)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Frontend Selection Mismatch with Fullstack Backend
The general isBackendSelf compatibility logic incorrectly defaults the web frontend to 'next' when a fullstack backend is selected without a supported frontend. This conflicts with the self-tanstack-start backend, which expects 'tanstack-start', leading to inconsistent frontend selection and redundant processing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/web/src/app/(home)/new/_components/utils.ts (1)
203-230: Redundant frontend enforcement creates confusing change messages.This generic self-backend block enforces Next.js as the default when no supported frontend is present, but then the specific variant blocks (lines 249-275 for
self-next, 277-304 forself-tanstack-start) re-enforce the correct frontend for each variant. This results in two change messages being generated for users, which is confusing.Example scenario:
- User selects
self-tanstack-startbackend withnuxtfrontend- This block (line 209) changes frontend to
["next"]and adds a change message- Then the specific block (line 282) changes frontend to
["tanstack-start"]and adds another change message- User sees both: "Frontend set to 'Next.js'..." followed by "Frontend set to 'TanStack Start'..."
Recommended fix: Check the specific backend variant here and default to the appropriate frontend:
} else if (isBackendSelf) { const hasSupportedFrontend = nextStack.webFrontend.includes("next") || nextStack.webFrontend.includes("tanstack-start"); if (!hasSupportedFrontend) { const originalWebFrontendLength = nextStack.webFrontend.length; - nextStack.webFrontend = ["next"]; + // Default to the appropriate frontend for the specific backend variant + const defaultFrontend = isBackendSelfTanstackStart ? "tanstack-start" : "next"; + nextStack.webFrontend = [defaultFrontend]; if ( originalWebFrontendLength !== 1 || - !nextStack.webFrontend.includes("next") + !nextStack.webFrontend.includes(defaultFrontend) ) { changed = true; notes.webFrontend.notes.push( "Self backend (fullstack) currently only supports Next.js and TanStack Start frontends. Other frontends have been removed.", ); notes.backend.notes.push( "Self backend (fullstack) requires Next.js or TanStack Start frontend.", ); notes.webFrontend.hasIssue = true; notes.backend.hasIssue = true; changes.push({ category: "backend", message: - "Frontend set to 'Next.js' (Self backend currently only supports Next.js and TanStack Start)", + `Frontend set to '${defaultFrontend === "tanstack-start" ? "TanStack Start" : "Next.js"}' (Self backend requires matching frontend)`, }); } }apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs (1)
57-87: Use explicit condition instead of bareelseblock.Similar to the earlier issue, line 57 uses a bare
{{else}}block. Replace it with an explicit condition for consistency with the coding guidelines.As per coding guidelines.
Apply this diff:
export const client: RouterClient<typeof appRouter> = getORPCClient(); -{{else}} +{{else if (not (includes frontend "tanstack-start"))}} export const link = new RPCLink({
♻️ Duplicate comments (2)
apps/cli/src/utils/better-auth-plugin-setup.ts (2)
10-15: Handle absent Better Auth index without crashing.
addSourceFileAtPaththrows when the file is missing, so this guard is never reached and the CLI aborts on templates withoutpackages/auth/src/index.ts. Switch to the safe helper so we can warn and exit gracefully.- const authIndexFile = tsProject.addSourceFileAtPath(authIndexPath); + const authIndexFile = + tsProject.addSourceFileAtPathIfExists(authIndexPath);
80-81: Persist ts-morph edits before exiting.
save()is async; without awaiting it the process can exit and drop the edits. Await the promise.- authIndexFile.save(); + await authIndexFile.save();
🧹 Nitpick comments (3)
apps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs (1)
18-18: Use explicit conditions instead of generic else block.The Handlebars conditional uses a generic
{{else}}block, which violates the coding guideline requiring explicit conditions for all branches. Instead of the generic else, explicitly enumerate the other backend types.As per coding guidelines, for Handlebars templates: "avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle"))."
For example:
api: {{#if (eq backend "self")}}"/api/ai"{{else if (eq backend "convex")}}`${import.meta.env.VITE_SERVER_URL}/ai`{{!-- add other backends here --}}{{/if}},Based on coding guidelines.
apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs (1)
88-88: Use explicit conditions instead of generic else block.Same issue as in the AI route template: the Handlebars conditional uses a generic
{{else}}block instead of explicitly enumerating backend types. Please use explicit conditions for each backend option as per the coding guidelines.For example:
url: {{#if (eq backend "self")}}"/api/trpc"{{else if (eq backend "convex")}}`${import.meta.env.VITE_SERVER_URL}/trpc`{{!-- add other backends --}}{{/if}},Based on coding guidelines.
apps/web/src/app/(home)/new/_components/utils.ts (1)
249-304: Variant-specific enforcement blocks are correct but could be simplified.The specific enforcement blocks for
self-next(lines 249-275) andself-tanstack-start(lines 277-304) are symmetric and correctly enforce the required frontend for each backend variant. However, if the previous issue (lines 203-230) is fixed, these blocks would only run in edge cases and could potentially be simplified or removed.For now, they serve as a safety net and provide explicit enforcement.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
apps/cli/src/helpers/core/api-setup.ts(4 hunks)apps/cli/src/helpers/core/create-project.ts(2 hunks)apps/cli/src/helpers/core/env-setup.ts(4 hunks)apps/cli/src/helpers/core/post-installation.ts(3 hunks)apps/cli/src/helpers/core/template-manager.ts(3 hunks)apps/cli/src/helpers/core/workspace-setup.ts(3 hunks)apps/cli/src/prompts/backend.ts(1 hunks)apps/cli/src/utils/better-auth-plugin-setup.ts(1 hunks)apps/cli/src/utils/compatibility-rules.ts(3 hunks)apps/cli/templates/api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs(1 hunks)apps/cli/templates/api/orpc/fullstack/tanstack-start/src/routes/api/rpc/$.ts.hbs(1 hunks)apps/cli/templates/api/orpc/server/src/context.ts.hbs(1 hunks)apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs(3 hunks)apps/cli/templates/api/trpc/fullstack/tanstack-start/src/routes/api/trpc/$.ts.hbs(1 hunks)apps/cli/templates/api/trpc/server/src/context.ts.hbs(1 hunks)apps/cli/templates/auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs(1 hunks)apps/cli/templates/auth/better-auth/server/base/src/index.ts.hbs(5 hunks)apps/cli/templates/backend/server/elysia/src/index.ts.hbs(1 hunks)apps/cli/templates/backend/server/express/src/index.ts.hbs(1 hunks)apps/cli/templates/backend/server/fastify/src/index.ts.hbs(1 hunks)apps/cli/templates/backend/server/hono/src/index.ts.hbs(1 hunks)apps/cli/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs(1 hunks)apps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs(1 hunks)apps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbs(1 hunks)apps/web/src/app/(home)/new/_components/utils.ts(11 hunks)apps/web/src/lib/constant.ts(2 hunks)apps/web/src/lib/stack-utils.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
- apps/cli/templates/backend/server/hono/src/index.ts.hbs
- apps/web/src/lib/stack-utils.ts
- apps/cli/src/helpers/core/api-setup.ts
- apps/cli/templates/auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs
- apps/cli/templates/backend/server/elysia/src/index.ts.hbs
- apps/cli/templates/api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs
- apps/cli/templates/examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs
- apps/cli/src/utils/compatibility-rules.ts
- apps/cli/src/helpers/core/create-project.ts
- apps/cli/src/helpers/core/post-installation.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{hbs,handlebars}
📄 CodeRabbit inference engine (.cursor/rules/better-t-stack-repo.mdc)
In Handlebars templates, avoid generic if/else blocks; write explicit conditions (e.g., if (eq orm "prisma") and else if (eq orm "drizzle")).
Files:
apps/cli/templates/api/trpc/fullstack/tanstack-start/src/routes/api/trpc/$.ts.hbsapps/cli/templates/backend/server/fastify/src/index.ts.hbsapps/cli/templates/frontend/react/tanstack-start/src/router.tsx.hbsapps/cli/templates/api/orpc/fullstack/tanstack-start/src/routes/api/rpc/$.ts.hbsapps/cli/templates/auth/better-auth/server/base/src/index.ts.hbsapps/cli/templates/api/orpc/server/src/context.ts.hbsapps/cli/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbsapps/cli/templates/api/trpc/server/src/context.ts.hbsapps/cli/templates/backend/server/express/src/index.ts.hbsapps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/convex_rules.mdc)
**/*.{ts,tsx}: Use Id from './_generated/dataModel' to type document ids (e.g., Id<'users'>)
Ensure Record key/value types align with validators (e.g., v.record(v.id('users'), v.string()) => Record<Id<'users'>, string>)
Be strict with types for document ids; prefer Id<'table'> over string
Use 'as const' for string literals in discriminated unions
When using Array and Record types, declare with explicit generic types (e.g., const arr: Array = ...)
**/*.{ts,tsx}: Use TypeScript type aliases instead of interface declarations.
Do not use explicit return types in TypeScript.
Files:
apps/web/src/app/(home)/new/_components/utils.tsapps/cli/src/prompts/backend.tsapps/cli/src/utils/better-auth-plugin-setup.tsapps/cli/src/helpers/core/template-manager.tsapps/cli/src/helpers/core/workspace-setup.tsapps/cli/src/helpers/core/env-setup.tsapps/web/src/lib/constant.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
**/*.{js,jsx,ts,tsx,mjs,cjs}: Do not use dotenv; Bun auto-loads .env
UseBun.serve()for HTTP/WebSockets; do not useexpress
Usebun:sqlitefor SQLite; do not usebetter-sqlite3
UseBun.redisfor Redis; do not useioredis
UseBun.sqlfor Postgres; do not usepgorpostgres.js
Use built-inWebSocket; do not usews
PreferBun.fileovernode:fsreadFile/writeFile
UseBun.$instead ofexecafor shelling out
Files:
apps/web/src/app/(home)/new/_components/utils.tsapps/cli/src/prompts/backend.tsapps/cli/src/utils/better-auth-plugin-setup.tsapps/cli/src/helpers/core/template-manager.tsapps/cli/src/helpers/core/workspace-setup.tsapps/cli/src/helpers/core/env-setup.tsapps/web/src/lib/constant.ts
**/*.{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/app/(home)/new/_components/utils.tsapps/cli/src/prompts/backend.tsapps/cli/src/utils/better-auth-plugin-setup.tsapps/cli/src/helpers/core/template-manager.tsapps/cli/src/helpers/core/workspace-setup.tsapps/cli/src/helpers/core/env-setup.tsapps/web/src/lib/constant.ts
🧬 Code graph analysis (4)
apps/cli/src/prompts/backend.ts (1)
apps/cli/src/types.ts (1)
Frontend(37-37)
apps/cli/src/utils/better-auth-plugin-setup.ts (1)
apps/cli/src/utils/ts-morph.ts (2)
tsProject(10-17)ensureArrayProperty(19-31)
apps/cli/src/helpers/core/template-manager.ts (1)
apps/cli/src/constants.ts (1)
PKG_ROOT(7-7)
apps/cli/src/helpers/core/workspace-setup.ts (1)
apps/cli/src/utils/add-package-deps.ts (1)
addPackageDependency(6-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (15)
apps/web/src/app/(home)/new/_components/utils.ts (11)
84-89: LGTM! Clean backend variant flags.The addition of specific flags (
isBackendSelfNext,isBackendSelfTanstackStart) alongside the genericisBackendSelfflag provides a clean separation of concerns, allowing both shared and variant-specific logic paths.
203-230: Logic error: Forces Next.js even when TanStack Start is present.This block checks if either Next.js or TanStack Start frontend is present (line 203-205), but then unconditionally forces Next.js (line 209) when neither is present. However, the condition on line 207 negates
hasSupportedFrontend, meaning this block executes when neither frontend is present, which is correct.Wait, re-reading: Line 207 is
if (!hasSupportedFrontend), so this block runs when neither Next.js nor TanStack Start is present. Then line 209 sets["next"]as the default. This is fine as a fallback behavior.However, there's a subtle issue: the messages on lines 217, 220, and 227 now mention "Next.js and TanStack Start" but the code still defaults to Next.js only. The messages suggest that users could have TanStack Start, but the code doesn't respect that choice here.
Actually, looking at lines 249-304, there are specific blocks that enforce the correct frontend for each backend variant. So this block (203-230) seems to be a general fallback that runs for any self-backend when no supported frontend exists, and it defaults to Next.js.
The later blocks (249-275 for self-next, 277-304 for self-tanstack-start) are more specific and would enforce the correct frontend for each variant.
This means:
- Generic isBackendSelf block (203-230): Fallback to Next.js when no supported frontend
- Specific isBackendSelfNext block (249-275): Enforce Next.js for self-next
- Specific isBackendSelfTanstackStart block (277-304): Enforce TanStack Start for self-tanstack-start
The issue is that the generic block (203-230) still runs for both variants and defaults to Next.js. If the user selected
self-tanstack-startbackend but has a different frontend, this block would set it to Next.js, then the specific block (277-304) would change it to TanStack Start. That's redundant but not incorrect.Actually, re-reading more carefully: the blocks are NOT mutually exclusive. Line 202 checks
isBackendSelf, which is true for both variants. Lines 249 and 277 check the specific variants. So both the generic block AND the specific block will run.This means:
- User selects self-tanstack-start backend with, say, nuxt frontend
- Generic block (203-230) runs, changes frontend to ["next"]
- Specific block (277-304) runs, changes frontend to ["tanstack-start"]
- Result: Correct, but with unnecessary intermediate step
This is inefficient but functionally correct. However, it generates confusing change messages because both blocks add changes.
Let me check if this is the intended behavior or if the generic block should be skipped when a specific variant is detected.
Looking at the structure, it seems the generic block (202-248) should handle COMMON logic for all self-backend variants (like runtime enforcement), while the specific blocks (249-275, 277-304) handle variant-specific frontend enforcement.
But the generic block also tries to enforce frontend (lines 203-230), which conflicts with the specific blocks.
This is a design issue. The generic block should probably only handle the common runtime logic, and let the specific blocks handle frontend enforcement.
[analysis revised]
Actually, looking at line 207:if (!hasSupportedFrontend). This means the block only runs if NEITHER next NOR tanstack-start is present. So:
- If user has tanstack-start frontend, hasSupportedFrontend = true, this block is skipped
- If user has next frontend, hasSupportedFrontend = true, this block is skipped
- If user has neither, hasSupportedFrontend = false, this block runs and defaults to Next.js
Then the specific blocks:
- isBackendSelfNext (249-275): If backend is self-next and frontend is NOT next, enforce next
- isBackendSelfTanstackStart (277-304): If backend is self-tanstack-start and frontend is NOT tanstack-start, enforce tanstack-start
So the flow is:
- If no supported frontend exists, generic block defaults to Next.js
- Then specific block checks the actual backend variant and corrects if needed
For example:
- User selects self-tanstack-start backend with nuxt frontend
- Generic block: hasSupportedFrontend = false (nuxt is not next or tanstack-start), so sets frontend to ["next"]
- Specific block (277-304): hasNextFrontend = true (from previous step), hasTanstackStartFrontend = false, so sets frontend to ["tanstack-start"]
This is redundant and generates two changes:
- "Frontend set to 'Next.js' (Self backend currently only supports Next.js and TanStack Start)"
- "Frontend set to 'TanStack Start' (TanStack Start fullstack backend requires TanStack Start frontend)"
This is confusing for users. The fix would be to:
- Make the generic block smarter: check which specific backend is selected and default to the appropriate frontend
- OR remove frontend enforcement from the generic block and let specific blocks handle it
Actually, wait. Let me trace through the scenario more carefully:
Scenario: User selects self-tanstack-start backend with nuxt frontend
- isBackendSelf = true (line 84-86)
- hasSupportedFrontend = false (nuxt is not next or tanstack-start)
- Generic block (203-230) runs:
- Line 207: !hasSupportedFrontend = true, so enter the block
- Line 209: nextStack.webFrontend = ["next"]
- Lines 211-229: changed = true, add notes and changes
- isBackendSelfNext = false (line 87)
- Block 249-275 is skipped
- isBackendSelfTanstackStart = true (line 88-89)
- Specific block (277-304) runs:
- Line 278-279: hasTanstackStartFrontend = nextStack.webFrontend.includes("tanstack-start")
- At this point, nextStack.webFrontend = ["next"] from step 3
- So hasTanstackStartFrontend = false
- Line 280: enter the block
- Line 282: nextStack.webFrontend = ["tanstack-start"]
- Lines 284-302: changed = true (already), add more notes and changes
Result: Two change messages, which is confusing.
The fix: The generic block (203-230) should check the specific variant and default to the appropriate frontend, OR the generic block should skip frontend enforcement and let specific blocks handle it entirely.
[pending]
- Flag this as a logic/design issue
[actions]- Generate a major issue comment suggesting a fix
-->
1178-1207: LGTM! Correct server deployment disabling for fullstack backends.The logic correctly identifies self-next and self-tanstack-start backends and disables server deployment, which is appropriate since fullstack backends use the frontend's built-in API routes.
1423-1436: LGTM! Clear backend selection validation.The validation correctly enforces that
self-nextrequires Next.js frontend andself-tanstack-startrequires TanStack Start frontend, with clear error messages guiding users to select the appropriate frontend first.
1438-1452: LGTM! Prevents invalid frontend selections.The validation correctly prevents selecting incompatible frontends when a specific fullstack backend is already selected, with clear error messages.
1462-1470: LGTM! Comprehensive runtime 'none' validation.The validation correctly allows runtime 'none' for Convex, Next.js fullstack, and TanStack Start fullstack backends, with a clear error message listing all valid options.
1472-1479: LGTM! Enforces runtime 'none' for fullstack backends.The validation correctly prevents selecting a non-none runtime for fullstack backends, with a clear explanation of why fullstack backends don't need a separate runtime.
1481-1499: LGTM! Flexible ORM/database validation for fullstack backends.The validation correctly allows ORM without database (and vice versa) for fullstack backends, while enforcing the requirement for other backends. This makes sense as fullstack backends may handle database/ORM setup differently.
1502-1534: LGTM! Database-specific validations with fullstack flexibility.The database-specific validations correctly enforce ORM requirements for MongoDB and SQLite, while allowing fullstack backends to bypass these requirements.
1575-1595: LGTM! ORM-specific validations with fullstack flexibility.The ORM-specific validations correctly enforce database requirements for Drizzle and Prisma, while allowing fullstack backends to bypass these requirements.
1748-1763: LGTM! Prevents unnecessary server deployment for fullstack backends.The validation correctly prevents server deployment for fullstack backends (self-next and self-tanstack-start), with clear error messages explaining that these backends use the frontend's built-in API routes.
apps/cli/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs (2)
40-54: Client-side ORPC setup looks good.The client-side implementation correctly uses
createIsomorphicFn().client()which ensures the code only runs in the browser, making the direct use ofwindow.location.origin(line 42) safe without additional runtime checks. The credentials handling for Better Auth (lines 44-49) is properly configured.
31-56: Verify server-side header forwarding in createContextThe
createContextimplementation lives in your generated project (not this template). Ensure it extracts and forwards authentication headers (cookies or Authorization) from the incomingreqso Better Auth works on the server.apps/cli/src/prompts/backend.ts (1)
6-12: LGTM! TanStack Start fullstack support for the self backend is fully integrated.Template directories exist under apps/cli/templates/**/tanstack-start and the template‐manager, env‐setup, compatibility rules, and deployment logic correctly handle
tanstack-startwhenbackend="self".apps/cli/templates/backend/server/express/src/index.ts.hbs (1)
88-89: Confirm client and ORPC configurations for new/api-referenceprefix
- Backend templates (Express, Fastify, Hono, Elysia) now consistently use
/api-reference.- Verify that generated client code (fetch/axios calls) and TanStack Start (ORPC) templates reference
/api-referenceinstead of/api.- Ensure any existing consumer projects are updated to use
/api-reference.
Summary by CodeRabbit
New Features
Improvements
Documentation