-
Notifications
You must be signed in to change notification settings - Fork 140
V3 Update Tanstack Start to RC #617
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
WalkthroughMove many paths and configs from app/ to src/; replace several server-side API/OpenAPI/dev routes under app/routes/api with client file routes under src/routes/api and update the generated route tree and public route types; update Prisma generator output and switch imports to the generated client; adjust tooling, scripts, ESLint, and dependency versions. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client as Client
participant Router as Router
participant FileRoute as src/routes/api/auth.$.ts
participant Auth as server auth.handler
rect rgba(52,211,153,0.06)
Note over Client,FileRoute: New client-file route handles GET/POST at /api/auth/$
Client->>Router: HTTP GET/POST /api/auth/$
Router->>FileRoute: Dispatch to file route handler
FileRoute->>Auth: auth.handler(request)
Auth-->>FileRoute: Response
FileRoute-->>Router: Return response
Router-->>Client: HTTP response
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 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 |
3a9e27d
to
0eae9c7
Compare
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
🧹 Nitpick comments (14)
components.json (1)
8-8
: src/styles/app.css verified; no Tailwind config detected
- Found
src/styles/app.css
.- No
tailwind.config.(cjs|js|ts)
in repo root or one level down—if you need custom Tailwind settings, add a config file (e.g.tailwind.config.ts
) and set the"tailwind.config"
field in components.json accordingly.src/features/build-info/script-to-generate-json.ts (1)
37-46
: Make generation idempotent: ensure parent directory exists before writeIf the folder is missing (fresh clone/CI), writeFileSync will throw. Create the directory recursively first.
+import path from 'node:path'; @@ - try { - fs.writeFileSync(generatedPath, JSON.stringify(getContent(), null, 2)); + try { + fs.mkdirSync(path.dirname(generatedPath), { recursive: true }); + fs.writeFileSync(generatedPath, JSON.stringify(getContent(), null, 2)); console.log(`✅ Build info file generated (${generatedPath})`);eslint.config.ts (2)
79-83
: Broaden stories glob to cover .ts and .mdx (optional)Covers typical Storybook patterns; harmless if unused.
- files: ['**/*.stories.tsx', './src/locales/**/*'], + files: ['**/*.stories.{ts,tsx,mdx}', './src/locales/**/*'],
71-74
: Nit: reference '@/env' instead of '@/src/env' in message- 'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/src/env folder instead.', + 'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/env instead.',.storybook/preview.tsx (3)
7-7
: Avoid internal Storybook importsDon’t import types from storybook/internal/csf. Prefer the public types to avoid breakage across 8→9 and future updates.
Apply:
- import { StoryContext } from 'storybook/internal/csf'; + import type { StoryContext } from '@storybook/types';This follows Storybook’s public API and avoids relying on internal modules. (storybook.js.org)
5-5
: Type‑only import for ReactNodeUse a type‑only import to keep it erased at runtime.
- import { ReactNode } from 'react'; + import type { ReactNode } from 'react';
36-47
: Effect deps nit: stabilize dependencyExtract locale before the effect to keep deps simple and satisfy exhaustive‑deps linters.
- useEffect(() => { - i18n.changeLanguage(context.globals.locale); + const { locale } = context.globals; + useEffect(() => { + i18n.changeLanguage(locale); const languageConfig = AVAILABLE_LANGUAGES.find( - ({ key }) => key === context.globals.locale + ({ key }) => key === locale ); ... - }, [context.globals.locale, i18n]); + }, [locale, i18n]);src/routes/api/dev.email.$template.ts (2)
15-17
: Use URL API instead of string splitSafer and clearer query parsing.
- const query = request.url.split('?')[1]; - const props = Object.fromEntries(new URLSearchParams(query ?? '')); + const url = new URL(request.url); + const props = Object.fromEntries(url.searchParams.entries());
3-3
: Server‑only import: lazy‑load inside handlerMove previewEmailRoute import into the GET handler to ensure it never leaks into client bundles and to reduce cold‑start memory.
-import { previewEmailRoute } from '@/server/email'; ... - GET: ({ request, params }) => { + GET: async ({ request, params }) => { // Allows debug only in development if (import.meta.env.PROD) { return new Response(undefined, { status: 404, }); } - const query = request.url.split('?')[1]; - const props = Object.fromEntries(new URLSearchParams(query ?? '')); - return previewEmailRoute(params.template, props); + const url = new URL(request.url); + const props = Object.fromEntries(url.searchParams.entries()); + const { previewEmailRoute } = await import('@/server/email'); + return previewEmailRoute(params.template, props); },Server routes via createFileRoute are supported in Start RC; this change keeps server code server‑only. (tanstack.com)
Also applies to: 8-18
src/routes/__root.tsx (2)
37-43
: Harden SSR language initWrap initSsrApp in try/catch to avoid taking down SSR on transient failures; default to current i18n.language.
loader: async () => { // Setup language and theme in SSR to prevent hydratation errors if (import.meta.env.SSR) { - const { language } = await initSsrApp(); - i18n.changeLanguage(language); + try { + const { language } = await initSsrApp(); + i18n.changeLanguage(language); + } catch { + // keep existing language + } } },Using createServerFn here is correct. (tanstack.com)
38-38
: Typo in comment“hydratation” → “hydration”.
src/routes/api/openapi/app.schema.ts (2)
19-27
: Minor polish: description wording and URL normalization
- Fix copy: “Go to the Auth API”.
- Guard against double slashes if
VITE_BASE_URL
ends with/
.- description: `API Reference for the application.<br /><br /><a href="${envServer.VITE_BASE_URL}/api/openapi/auth">Go the <strong>Auth API</strong> documentation</a>`, + description: `API Reference for the application.<br /><br /><a href="${envServer.VITE_BASE_URL.replace(/\/+$/,'')}/api/openapi/auth">Go to the <strong>Auth API</strong> documentation</a>`, ... - url: `${envServer.VITE_BASE_URL}/api/rest`, + url: `${envServer.VITE_BASE_URL.replace(/\/+$/,'')}/api/rest`,Also applies to: 21-23
51-55
: Optional: add caching headers for the OpenAPI specSchema changes infrequently; consider short‑term caching to reduce load.
- return json(spec); + return json(spec, { + headers: { 'Cache-Control': 'public, max-age=600, stale-while-revalidate=86400' }, + });src/router.tsx (1)
7-18
: Inject QueryClient per request for SSR safety
src/lib/tanstack-query/query-client.tsx:5
exports a module-level singletonqueryClient
which can leak cache between users during SSR. UpdategetRouter
insrc/router.tsx
to accept a per-requestQueryClient
instead of importing the singleton:-import { queryClient } from '@/lib/tanstack-query/query-client'; +import type { QueryClient } from '@tanstack/react-query'; -export function getRouter() { +export function getRouter(queryClient: QueryClient) { return createRouter({ context: { queryClient, },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (29)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
src/components/icons/generated/IconBookOpen.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconBookOpenDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconBookOpenFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconGitBranch.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconGitBranchDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconGitBranchFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconHouse.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconHouseDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconHouseFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconUserCircle.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconUserCircleDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconUserCircleFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/index.ts
is excluded by!**/generated/**
src/components/icons/svg-sources/icon-book-open-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-book-open-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-book-open.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-git-branch-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-git-branch-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-git-branch.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-house-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-house-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-house.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-user-circle-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-user-circle-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-user-circle.svg
is excluded by!**/*.svg
src/features/auth/layout-login-image.jpg
is excluded by!**/*.jpg
src/features/auth/mascot-error.png
is excluded by!**/*.png
src/features/auth/mascot.png
is excluded by!**/*.png
📒 Files selected for processing (24)
.gitignore
(1 hunks).prettierrc.cjs
(1 hunks).storybook/preview.tsx
(1 hunks).vscode/settings.example.json
(1 hunks)README.md
(2 hunks)app/routes/api/auth.$.ts
(0 hunks)app/routes/api/dev.email.$template.ts
(0 hunks)app/routes/api/openapi/app.schema.ts
(0 hunks)app/routes/api/openapi/app.ts
(0 hunks)app/routes/api/openapi/auth.schema.ts
(0 hunks)app/routes/api/openapi/auth.ts
(0 hunks)components.json
(1 hunks)eslint.config.ts
(3 hunks)package.json
(4 hunks)run-jiti.js
(1 hunks)src/components/icons/svgr.config.cjs
(1 hunks)src/features/build-info/script-to-generate-json.ts
(1 hunks)src/lib/tanstack-query/query-client.tsx
(1 hunks)src/routeTree.gen.ts
(19 hunks)src/router.tsx
(1 hunks)src/routes/__root.tsx
(1 hunks)src/routes/api/auth.$.ts
(1 hunks)src/routes/api/dev.email.$template.ts
(1 hunks)src/routes/api/openapi/app.schema.ts
(1 hunks)
💤 Files with no reviewable changes (6)
- app/routes/api/dev.email.$template.ts
- app/routes/api/openapi/auth.ts
- app/routes/api/openapi/auth.schema.ts
- app/routes/api/auth.$.ts
- app/routes/api/openapi/app.schema.ts
- app/routes/api/openapi/app.ts
⏰ 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). (3)
- GitHub Check: 🔬 Tests (lts/*)
- GitHub Check: 🔬 Tests (22)
- GitHub Check: Playwright E2E Tests
🔇 Additional comments (15)
.gitignore (1)
14-14
: Ignore dist output — LGTMMatches the new build target (
dist/*
) and complements.vinxi
/.nitro
. No further changes needed.README.md (2)
83-87
: Icons source path updated and generator verifiedThe
pnpm gen:icons
script reads fromsrc/components/icons/svg-sources
and outputs tosrc/components/icons/generated
. LGTM.
66-69
: Verify/api/dev/email/{template}
preview endpoint — could not locate a matching route undersrc/routes/api/dev/email
; ensure the endpoint still exists after migrating to Start RC and update docs or route definitions accordingly.run-jiti.js (1)
12-12
: Verify '@/' subpath mapping exists in TS/Vite configs before updating run-jiti.js
No@/*
path in tsconfig.json orresolve.alias
entry in vite.config.* was detected—confirm and align aliases across your TypeScript and Vite configurations prior to adding the'@/'
mapping..vscode/settings.example.json (1)
10-10
: Approve locales path migration Verifiedsrc/locales
exists with JSON locale files and.vscode/settings.example.json
correctly references"src/locales"
..prettierrc.cjs (1)
13-15
: Approve: tailwindStylesheet path and stylesheet existence verifiedeslint.config.ts (2)
52-53
: Ignore pattern is safe
Verified that src/routes contains only route definitions; no non-route utilities found.
64-64
: Rule scope limited to src//* is safe; all import.meta.env references are within src. LGTM.**src/lib/tanstack-query/query-client.tsx (1)
3-3
: No stale import.meta.dev usages remainConfirmed no occurrences of
import.meta.dev
across the codebase.src/routes/api/auth.$.ts (1)
5-16
: LGTM; correct splat route for Better AuthUsing
/api/auth/$
is the right catch‑all. Forwarding both methods toauth.handler
aligns with the integration guides.If this endpoint is called cross‑origin in dev, you may need an OPTIONS handler for preflight:
server: { handlers: { GET: ({ request }) => auth.handler(request), POST: ({ request }) => auth.handler(request), + OPTIONS: () => new Response(null, { status: 204 }), }, },
Refs: TanStack splat docs and Better Auth + Start integration. (tanstack.com)
package.json (2)
141-141
: Vite compatibility check (Node and security)Vite 7.1.7 is fine with Node ≥22 and has recent security fixes; your engines field matches.
If you run CI on older Node, upgrade runners. See Vite 7 announcement and security advisory snapshot. (vite.dev)
62-66
: Pin stable TanStack package versions
Remove the invalid 1.132.23 tags and align all TanStack packages to the latest stable 1.131.36:- "@tanstack/react-router": "1.132.23", - "@tanstack/react-router-devtools": "1.132.23", - "@tanstack/react-start": "1.132.23", - "@tanstack/zod-adapter": "1.132.23", + "@tanstack/react-router": "1.131.36", + "@tanstack/react-router-devtools": "1.131.36", + "@tanstack/react-start": "1.131.36", + "@tanstack/zod-adapter": "1.131.36",Note: version 1.132.0 is currently alpha-only and not available as a stable release on npm as of September 29, 2025.
Likely an incorrect or invalid review comment.
src/routeTree.gen.ts (3)
118-142
: LGTM: new top‑level API routes are correctly registered
/api/rpc/$
,/api/rest/$
,/api/openapi/auth
,/api/openapi/app
, and/api/auth/$
are wired underrootRouteImport
with coherent ids/paths.
168-182
: LGTM: nested schema routes attached to their parents
/api/openapi/(auth|app)/schema
children are correctly attached to their respective parents withpath: '/schema'
.Also applies to: 174-177
720-727
: Verify getRouter usage
No invocations ofgetRouter(...)
were found outside its export insrc/router.tsx
. Ensure your server/client entry points callgetRouter(...)
so the SSRRegister
augmentation is actually applied.
import { envClient } from '@/env/client'; | ||
import { router } from '@/server/router'; | ||
|
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.
Use server env in server handler (avoid envClient in API route)
This handler runs on the server; import envServer
instead of envClient
to avoid client‑only env assumptions and bundling pitfalls.
-import { envClient } from '@/env/client';
+import { envServer } from '@/env/server';
And replace occurrences of envClient.VITE_BASE_URL
with envServer.VITE_BASE_URL
.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import { envClient } from '@/env/client'; | |
import { router } from '@/server/router'; | |
import { envServer } from '@/env/server'; | |
import { router } from '@/server/router'; |
🤖 Prompt for AI Agents
In src/routes/api/openapi/app.schema.ts around lines 6 to 8, the file imports
envClient which is client-side only; replace the import with envServer from
'@/env/server' (or your project equivalent) and update all occurrences of
envClient.VITE_BASE_URL to use envServer.VITE_BASE_URL so the API route uses
server environment values and avoids client-side bundling assumptions.
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: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/features/auth/permissions.ts (1)
9-42
: Fix enum import for the new Prisma generator.Switching the generator to
provider = "prisma-client"
splits the output so enums now live under theenums
entry point;client
no longer exposesUserRole
, so this import will break at compile time. Update the import to read from the generatedenums
module (and adjust any other enum imports accordingly).-import { UserRole } from '@/server/db/generated/client'; +import { UserRole } from '@/server/db/generated/enums';eslint.config.ts (2)
64-76
: Fix unknown rule and add required plugin: use n/no-process-env + import eslint-plugin-n
no-process-env
is not a core rule. In flat config it should ben/no-process-env
and you must loadeslint-plugin-n
in the same config object, otherwise ESLint errors with “Definition for rule 'no-process-env' was not found”.Apply within this block:
{ - files: ['src/**/*'], + files: ['src/**/*'], + plugins: { n }, rules: { - 'no-process-env': 'error', + 'n/no-process-env': 'error', 'no-restricted-syntax': [And add the import at the top of the file:
+import n from 'eslint-plugin-n';
79-83
: Rule from eslint-plugin-import used but plugin not loaded; also broaden stories glob
import/no-anonymous-default-export
requireseslint-plugin-import
to be registered in this config object; otherwise ESLint fails with an unknown rule error. Also, Storybook files often include ts/js/jsx/tsx/mdx.Apply within this block:
- { - files: ['**/*.stories.tsx', './src/locales/**/*'], + { + files: ['**/*.stories.{tsx,ts,jsx,js,mdx}', 'src/locales/**/*'], + plugins: { import: eslintPluginImport }, rules: { 'import/no-anonymous-default-export': 'off', }, },Add the import at the top:
+import eslintPluginImport from 'eslint-plugin-import';
🧹 Nitpick comments (1)
eslint.config.ts (1)
52-52
: Confirm scope of unicorn ignores for routesIgnoring all of
src/routes/**/*.*
for the unicorn config disablesunicorn/filename-case
(and any future unicorn rules) across every route file. If the intent is only to avoid filename-case conflicts with bracketed route files, consider narrowing the ignore (e.g., only generated files) or keep as-is if intentional. Please confirm.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
.gitignore
(2 hunks).prettierignore
(1 hunks)eslint.config.ts
(3 hunks)package.json
(6 hunks)prisma/schema.prisma
(1 hunks)src/features/auth/permissions.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- .gitignore
- package.json
⏰ 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). (3)
- GitHub Check: 🔬 Tests (24)
- GitHub Check: 🔬 Tests (lts/*)
- GitHub Check: Playwright E2E Tests
"MemberExpression[object.type='MemberExpression'][object.object.type='MetaProperty'][object.object.property.name='meta'][object.property.name='env'][property.name!=/^(DEV|PROD|MODE|SSR|BASE_URL|MANIFEST)$/]", | ||
message: | ||
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/app/env folder instead.', | ||
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/src/env folder instead.', | ||
}, |
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.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Align env guidance with your alias: '@/env' is likely correct (not '@/src/env')
If “@” maps to the src root (common here given other groups like ^@/components
), the message should reference @/env
, not @/src/env
. Suggest:
- 'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/src/env folder instead.',
+ 'Custom import.meta.env variables are not allowed. Use envClient/envServer from @/env instead.',
Run to verify alias and env module location:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Alias mapping for @/* in tsconfig files:"
fd -a -t f 'tsconfig*.json' | while read -r f; do
echo "--- $f"
jq -r '.compilerOptions.paths["@/*"] // empty' "$f" || true
done
echo
echo "Where are envClient/envServer defined?"
rg -nP -C1 --glob '!**/node_modules/**' 'export\s+(const|type|interface)\s+(envClient|envServer)\b' || true
echo
echo "Who imports env via alias?"
rg -n --glob '!**/node_modules/**' -e "from '@/env'" -e "from '@/src/env'" || true
Length of output: 459
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Finding definitions of envClient/envServer under src/"
rg -nP 'export\s+(const|type|interface)\s+(envClient|envServer)\b' -C1 src/
echo
echo "Looking for imports from '@/env'"
rg -nC1 "^import .* from ['\"]@/env" src/
echo
echo "Looking for imports from '@/src/env'"
rg -nC1 "^import .* from ['\"]@/src/env" src/
Length of output: 2574
Correct env alias in ESLint config message
Update the instruction to reference @/env
instead of @/src/env
:
- 'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/src/env folder instead.',
+ 'Custom import.meta.env variables are not allowed. Use envClient/envServer from @/env instead.',
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"MemberExpression[object.type='MemberExpression'][object.object.type='MetaProperty'][object.object.property.name='meta'][object.property.name='env'][property.name!=/^(DEV|PROD|MODE|SSR|BASE_URL|MANIFEST)$/]", | |
message: | |
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/app/env folder instead.', | |
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/src/env folder instead.', | |
}, | |
"MemberExpression[object.type='MemberExpression'][object.object.type='MetaProperty'][object.object.property.name='meta'][object.property.name='env'][property.name!=/^(DEV|PROD|MODE|SSR|BASE_URL|MANIFEST)$/]", | |
message: | |
'Custom import.meta.env variables are not allowed. Use envClient/envServer from @/env instead.', | |
}, |
🤖 Prompt for AI Agents
In eslint.config.ts around lines 71 to 74, the ESLint rule message incorrectly
references "@/src/env"; update the message string to instruct developers to use
"@/env" instead of "@/src/env" so it reads something like: "Custom
import.meta.env variables are not allowed. Use envClient and envServer from
@/env instead."
4e58963
to
1acfce5
Compare
f78bfc0
to
1acfce5
Compare
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
🧹 Nitpick comments (2)
package.json (2)
28-28
: svgr CLI likely needs an explicit --out-dir (or ensure it’s set in svgr.config).
Without --out-dir, svgr prints to stdout when given a directory. If your svgr.config doesn’t set outDir, this won’t generate files.Consider making the destination explicit:
- "gen:icons": "svgr --config-file src/components/icons/svgr.config.cjs src/components/icons/svg-sources && prettier -w src/components/icons/generated", + "gen:icons": "svgr --config-file src/components/icons/svgr.config.cjs --out-dir src/components/icons/generated src/components/icons/svg-sources && prettier -w src/components/icons/generated",
80-80
: Operational note: ensure Node runtime on Vercel for Prismapg
.
If Nitro targets edge by default, Prisma + pg won’t run. Make sure your Nitro preset/build targets Node functions on Vercel.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (2)
package.json
(6 hunks)prisma/schema.prisma
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- prisma/schema.prisma
⏰ 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). (3)
- GitHub Check: 🔬 Tests (lts/*)
- GitHub Check: 🔬 Tests (24)
- GitHub Check: Playwright E2E Tests
🔇 Additional comments (8)
package.json (8)
18-19
: Env script path updates look good.
Paths now target src/* and still use dotenv + jiti; no concerns.
24-24
: ESLint scope switch to ./src is fine.
Assuming root configs still reference tsconfig paths, this is consistent with the move.If you still lint config files at repo root, ensure your ESLint config includes them via overrides/globs.
27-27
: Build‑info generator path update LGTM.
Script still runs through dotenv + jiti; no issues spotted.
61-67
: TanStack packages bumped in lockstep — good.
Versions are aligned across router/query/devtools/zod-adapter.Confirm no peer warnings during install.
119-119
: Vite React plugin bump matches Vite 7 and React 19 — OK.
137-137
: Prisma CLI aligned to client 6.16.2 — OK.
143-143
: Vite 7.1.7 — OK.
80-80
: No change needed The nitro-nightly plugin is the officially recommended approach for @tanstack/react-start v1.132.x; continue using"nitro": "npm:[email protected]…"
and migrate to a stable v3 GA when it’s released.
package.json
Outdated
"@prisma/adapter-pg": "6.16.2", | ||
"@prisma/client": "6.16.2", | ||
"@react-email/components": "0.0.39", |
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.
🧩 Analysis chain
Prisma pg adapter requires the pg
driver at runtime — missing dependency.
@prisma/adapter-pg declares a peer on pg; without it, runtime will fail to connect (module not found).
Add pg to dependencies (pick a version compatible with your adapter):
"@prisma/adapter-pg": "6.16.2",
"@prisma/client": "6.16.2",
+ "pg": "^8",
Quick check:
🏁 Script executed:
#!/bin/bash
# Inspect peer deps to choose a matching pg version
npm view @prisma/adapter-pg peerDependencies
npm view pg version
Length of output: 6
Add missing ‘pg’ runtime dependency
Prisma’s PostgreSQL adapter (@prisma/adapter-pg) declares a peer dependency on pg ≥8.16.3; without it, the module won’t be found at runtime. Add pg@^8.16.3 to your dependencies:
"@prisma/client": "6.16.2",
+ "pg": "^8.16.3",
"@react-email/components": "0.0.39",
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"@prisma/adapter-pg": "6.16.2", | |
"@prisma/client": "6.16.2", | |
"@react-email/components": "0.0.39", | |
"@prisma/adapter-pg": "6.16.2", | |
"@prisma/client": "6.16.2", | |
"pg": "^8.16.3", | |
"@react-email/components": "0.0.39", |
🤖 Prompt for AI Agents
In package.json around lines 54 to 56, @prisma/adapter-pg requires the pg
package as a peer dependency and will fail at runtime if pg is not installed;
add "pg": "^8.16.3" to the dependencies section (not devDependencies) and run
npm install (or yarn) to ensure the pg runtime dependency is present and
satisfies the peer requirement.
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: 1
♻️ Duplicate comments (1)
package.json (1)
54-54
: If using@prisma/adapter-pg
, addpg
runtime dep; otherwise ignore.Current deps don’t include
@prisma/adapter-pg
. If the codebase still imports it,pg
is required at runtime (peer). Verify usage and addpg@^8
to dependencies if applicable.#!/bin/bash # Detect adapter usage in source rg -nP --type=ts --type=tsx --type=js --type=mjs --type=cjs "(from|require\\()\\s*['\"]@prisma/adapter-pg['\"]" -C2 || true # Confirm package entries rg -nP '"@prisma/adapter-pg"|"\bpg\b"' package.json -n -C2 || true
🧹 Nitpick comments (1)
package.json (1)
79-79
: Nightly Nitro may cause churn; prefer rc/stable pin if possible.Nightly builds can break unexpectedly. If feasible, switch to a 3.0.0-rc or stable tag matching your Nitro plugin v3 target to improve reproducibility.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (1)
package.json
(6 hunks)
🔇 Additional comments (6)
package.json (6)
24-24
: ESLint path switch to ./src looks good.
28-28
: SVGR paths updated to src; LGTM.
41-41
: Seed script moved to prisma/seed/index.ts; LGTM.
136-136
: Prisma CLI aligned with client 6.16.3; good.
118-118
: Vite and React plugin bumps look consistent.Also applies to: 142-142
18-19
: No action needed for run-jiti scripts
Therun-jiti.js
file exists at the repo root and Node will resolve./run-jiti
torun-jiti.js
, so the npm scripts will run as expected.
"gen:prisma": "prisma generate --no-hints", | ||
"gen:build-info": "dotenv -- node ./run-jiti ./app/features/build-info/script-to-generate-json.ts", | ||
"gen:icons": "svgr --config-file app/components/icons/svgr.config.cjs app/components/icons/svg-sources && prettier -w app/components/icons/generated", | ||
"gen:build-info": "dotenv -- node ./run-jiti ./src/features/build-info/script-to-generate-json.ts", |
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.
Postinstall robustness: avoid dev-only tools during production installs.
gen:build-info
uses dotenv
and the run-jiti
helper. If postinstall
runs in a production-only install (no devDeps), it can fail. Since you already call gen:build-info
in dev:app
and build
, consider removing it from postinstall
and avoid run-p
there.
Apply this change to simplify postinstall
:
- "postinstall": "run-p gen:prisma gen:build-info",
+ "postinstall": "pnpm -s gen:prisma",
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"gen:build-info": "dotenv -- node ./run-jiti ./src/features/build-info/script-to-generate-json.ts", | |
"gen:build-info": "dotenv -- node ./run-jiti ./src/features/build-info/script-to-generate-json.ts", | |
"postinstall": "pnpm -s gen:prisma", |
🤖 Prompt for AI Agents
In package.json around line 27, the postinstall currently invokes the
gen:build-info script which depends on dev-only tools like dotenv and run-jiti;
this can break production installs without devDependencies. Remove
gen:build-info (and avoid using run-p) from the postinstall entry so postinstall
only runs production-safe tasks, and ensure gen:build-info remains invoked from
dev:app and build scripts where devDependencies are available.
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: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
package.json (1)
11-11
: Postinstall fails without devDependencies
run-p
(fromnpm-run-all
) and thedotenv
CLI aren’t shipped in production installs (pnpm install --prod
), so the current postinstall crashes before Prisma can generate. Keep postinstall limited to production-safe commands.- "postinstall": "run-p gen:prisma gen:build-info", + "postinstall": "pnpm -s gen:prisma",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (1)
package.json
(6 hunks)
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: 1
♻️ Duplicate comments (3)
package.json (3)
11-11
: Postinstall should not depend on dev-only tools; remove gen:build-info and run-p.This can break production installs where devDependencies aren’t present. Keep postinstall minimal (Prisma generate only).
- "postinstall": "run-p gen:prisma gen:build-info", + "postinstall": "pnpm -s gen:prisma",Note: gen:build-info is already invoked in dev:app and build.
44-66
: If using @prisma/adapter-pg, add pg peer; otherwise ignore.Current deps don’t show @prisma/adapter-pg here. Verify repo usage to avoid a runtime “module not found”.
#!/bin/bash # Check if @prisma/adapter-pg is used anywhere rg -nP --no-ignore-vcs -C2 '@prisma/adapter-pg|from\s+["'\'']@prisma/adapter-pg["'\'']' # If present, ensure pg is installed rg -nP '"pg"\s*:\s*"' package.json || echo 'pg not listed in package.json'
17-17
: Start uses dotenv CLI but dotenv-cli is a devDependency — app won’t boot in prod.Promote dotenv-cli to dependencies.
"dependencies": { + "dotenv-cli": "8.0.0", @@ "devDependencies": { - "dotenv-cli": "8.0.0",Also applies to: 124-124
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
package.json
(6 hunks)
🔇 Additional comments (8)
package.json (8)
20-21
: LGTM: env scripts updated to src paths.
25-25
: LGTM: eslint target moved to src.
28-29
: LGTM: build-info and icons paths updated.
42-42
: LGTM: db:seed wrapped with dotenv/cross-env via run-jiti.
55-55
: LGTM: Prisma client and CLI versions aligned (6.16.3).Also applies to: 137-137
61-66
: LGTM: TanStack package versions synced.
119-119
: @vitejs/plugin-react v5 is compatible with Vite v7.1.9
@vitejs/plugin-react@5 peerDependencies include vite ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0, and [email protected] falls within this range.
80-80
: Nitro 3.0.0-rc is not available
Nightlies remain the only pre-release option—enforce reproducible installs withnpm install --frozen-lockfile
in CI and document your nightly-pinning policy.
package.json
Outdated
"dev:app": "pnpm gen:build-info && vite dev", | ||
"dev:smtp": "maildev -outgoing-host smtp.example.com --outgoing-secure --outgoing-user 'username' --outgoing-pass 'password'", | ||
"build": "cross-env NODE_ENV=production run-p env gen:build-info && vite build", | ||
"postbuild": "cp ./src/server/db/generated/libquery_engine-rhel-openssl-3.0.x.so.node ./.vercel/output/functions/__fallback.func/chunks/_", |
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.
🛠️ Refactor suggestion | 🟠 Major
Brittle postbuild copy to Vercel fallback — make conditional and resilient.
Hardcoding the Prisma libquery filename and Vercel path will break locally/CI and on engine name changes. Guard the copy, glob the filename, and only run on Vercel.
Apply this change:
- "postbuild": "cp ./src/server/db/generated/libquery_engine-rhel-openssl-3.0.x.so.node ./.vercel/output/functions/__fallback.func/chunks/_",
+ "postbuild": "node ./scripts/copy-prisma-libquery.js",
Add scripts/copy-prisma-libquery.js:
// scripts/copy-prisma-libquery.js
import fs from 'node:fs'
import path from 'node:path'
const isVercel = !!process.env.VERCEL
const srcDir = path.resolve('src/server/db/generated')
const destDir = path.resolve('.vercel/output/functions/__fallback.func/chunks/_')
// Only run on Vercel
if (!isVercel) process.exit(0)
// Find libquery file (openssl suffix can vary)
const candidates = fs.existsSync(srcDir)
? fs.readdirSync(srcDir).filter(f => /^libquery_engine.*\.node$/.test(f))
: []
if (candidates.length === 0) {
console.warn('[postbuild] Prisma libquery not found in', srcDir)
process.exit(0)
}
fs.mkdirSync(destDir, { recursive: true })
for (const f of candidates) {
fs.copyFileSync(path.join(srcDir, f), path.join(destDir, f))
console.log(`[postbuild] Copied ${f} -> ${destDir}`)
}
🤖 Prompt for AI Agents
package.json lines 16-16: the postbuild script unconditionally copies a
hardcoded Prisma libquery file to a hardcoded Vercel fallback path which is
brittle; replace it with a conditional, resilient approach: add a
scripts/copy-prisma-libquery.js that only runs when process.env.VERCEL is set,
globs the generated directory (src/server/db/generated) for files matching
/^libquery_engine.*\.node$/, warns and exits if none found, creates the
destination .vercel/output/functions/__fallback.func/chunks/_ if needed, and
copies all matching files into that destination while logging each copy; update
package.json postbuild to call this script instead of the hardcoded cp command.
d1ee209
to
d683e97
Compare
# Conflicts: # pnpm-lock.yaml
d683e97
to
1990986
Compare
|
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: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (29)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
src/components/icons/generated/IconBookOpen.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconBookOpenDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconBookOpenFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconGitBranch.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconGitBranchDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconGitBranchFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconHouse.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconHouseDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconHouseFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconUserCircle.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconUserCircleDuotone.tsx
is excluded by!**/generated/**
src/components/icons/generated/IconUserCircleFill.tsx
is excluded by!**/generated/**
src/components/icons/generated/index.ts
is excluded by!**/generated/**
src/components/icons/svg-sources/icon-book-open-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-book-open-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-book-open.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-git-branch-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-git-branch-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-git-branch.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-house-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-house-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-house.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-user-circle-duotone.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-user-circle-fill.svg
is excluded by!**/*.svg
src/components/icons/svg-sources/icon-user-circle.svg
is excluded by!**/*.svg
src/features/auth/layout-login-image.jpg
is excluded by!**/*.jpg
src/features/auth/mascot-error.png
is excluded by!**/*.png
src/features/auth/mascot.png
is excluded by!**/*.png
📒 Files selected for processing (24)
.gitignore
(2 hunks).prettierignore
(1 hunks).prettierrc.cjs
(1 hunks).storybook/preview.tsx
(1 hunks).vscode/settings.example.json
(1 hunks)README.md
(2 hunks)app/routes/api/auth.$.ts
(0 hunks)app/routes/api/dev.email.$template.ts
(0 hunks)app/routes/api/openapi/app.schema.ts
(0 hunks)app/routes/api/openapi/app.ts
(0 hunks)app/routes/api/openapi/auth.schema.ts
(0 hunks)app/routes/api/openapi/auth.ts
(0 hunks)components.json
(1 hunks)eslint.config.ts
(3 hunks)package.json
(6 hunks)prisma/schema.prisma
(1 hunks)run-jiti.js
(1 hunks)src/components/icons/svgr.config.cjs
(1 hunks)src/features/auth/permissions.ts
(1 hunks)src/features/build-info/script-to-generate-json.ts
(1 hunks)src/lib/tanstack-query/query-client.tsx
(1 hunks)src/routeTree.gen.ts
(19 hunks)src/router.tsx
(1 hunks)src/routes/__root.tsx
(1 hunks)
💤 Files with no reviewable changes (6)
- app/routes/api/openapi/auth.ts
- app/routes/api/openapi/app.schema.ts
- app/routes/api/openapi/auth.schema.ts
- app/routes/api/auth.$.ts
- app/routes/api/openapi/app.ts
- app/routes/api/dev.email.$template.ts
✅ Files skipped from review due to trivial changes (2)
- src/features/build-info/script-to-generate-json.ts
- .prettierignore
🚧 Files skipped from review as they are similar to previous changes (10)
- src/features/auth/permissions.ts
- prisma/schema.prisma
- run-jiti.js
- components.json
- .vscode/settings.example.json
- src/components/icons/svgr.config.cjs
- src/lib/tanstack-query/query-client.tsx
- README.md
- src/routes/__root.tsx
- .prettierrc.cjs
⏰ 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: Playwright E2E Tests
selector: | ||
"MemberExpression[object.type='MemberExpression'][object.object.type='MetaProperty'][object.object.property.name='meta'][object.property.name='env'][property.name!=/^(DEV|PROD|MODE|SSR|BASE_URL|MANIFEST)$/]", | ||
message: | ||
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/app/env folder instead.', | ||
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/env/client and @/env/servr folder instead.', | ||
}, |
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.
Fix typo in env guidance path
Message points readers to @/env/servr
, which doesn’t exist. Update it to reference the real @/env/server
module so the rule guidance stays accurate.
- 'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/env/client and @/env/servr folder instead.',
+ 'Custom import.meta.env variables are not allowed. Use envClient/envServer from @/env/client and @/env/server instead.',
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
selector: | |
"MemberExpression[object.type='MemberExpression'][object.object.type='MetaProperty'][object.object.property.name='meta'][object.property.name='env'][property.name!=/^(DEV|PROD|MODE|SSR|BASE_URL|MANIFEST)$/]", | |
message: | |
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/app/env folder instead.', | |
'Custom import.meta.env variables are not allowed. Use envClient and envServer from @/env/client and @/env/servr folder instead.', | |
}, | |
selector: | |
"MemberExpression[object.type='MemberExpression'][object.object.type='MetaProperty'][object.object.property.name='meta'][object.property.name='env'][property.name!=/^(DEV|PROD|MODE|SSR|BASE_URL|MANIFEST)$/]", | |
message: | |
'Custom import.meta.env variables are not allowed. Use envClient/envServer from @/env/client and @/env/server instead.', | |
}, |
🤖 Prompt for AI Agents
In eslint.config.ts around lines 70 to 74, the rule message contains a typo
pointing to "@/env/servr"; update the string to reference the correct module
"@/env/server" so it reads: 'Custom import.meta.env variables are not allowed.
Use envClient and envServer from @/env/client and @/env/server instead.' Ensure
only the path text is changed and preserve the rest of the message and rule
formatting.
This PR is not working yet.
See issue hereSummary by CodeRabbit
Refactor
New Features
Documentation
Chores