-
-
Notifications
You must be signed in to change notification settings - Fork 167
feat: add T3 Env support (needs testing) #544
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
base: main
Are you sure you want to change the base?
Conversation
/demo.gif -- 1,188.08kb -> 1,051.18kb (11.52%) Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
WalkthroughIntroduces a new CLI addon “t3env” for type-safe environment variables. Updates CLI constants, prompts, types, addon setup flow, and adds templates for Next/Nuxt env scaffolding. Adjusts defaults/presets to include t3env, updates docs and website to surface the addon, and adds required dependency versions. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant CLI as CLI (create)
participant Addons as setupAddons
participant T3Env as setupT3Env
participant FS as fs-extra
participant Pkg as addPackageDependency
User->>CLI: run with --addons ... t3env ...
CLI->>Addons: setupAddons(config)
Addons->>Addons: if addons includes "t3env"
Addons->>T3Env: setupT3Env(config)
rect rgba(230,230,255,0.4)
note right of T3Env: Start spinner: "Setting up T3 Env"
T3Env->>FS: check apps/server, apps/web existence
alt Frontend: Next
T3Env->>Pkg: add @t3-oss/env-nextjs (+ zod if needed)
else Frontend: Nuxt
T3Env->>Pkg: add @t3-oss/env-nuxt + zod
else Other web
T3Env->>Pkg: add @t3-oss/env-core + zod
end
opt Server present
T3Env->>Pkg: add @t3-oss/env-core + zod (server)
end
end
T3Env-->>Addons: success or error (spinner stop)
Addons-->>CLI: continue other addon setups
CLI-->>User: generated project with T3 Env scaffolding
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 11
🧹 Nitpick comments (18)
apps/web/src/app/(home)/_components/npm-package.tsx (3)
15-17
: Guard against empty or unexpected GitHub releases payloadAccessing
data[0].tag_name
will throw if there are no releases or the payload shape changes. Add a defensive check and a safe fallback.Apply this diff:
- const data = await res.json(); - const latestVersion = data[0].tag_name.replace(/^v/, ""); - setVersion(latestVersion); + const data = await res.json(); + const tag = + Array.isArray(data) && data.length > 0 && typeof data[0]?.tag_name === "string" + ? data[0].tag_name + : null; + setVersion(tag ? tag.replace(/^v/, "") : "latest");
8-24
: Prevent state update on unmounted component; add AbortController and pass signal to fetchIf the component unmounts before the request resolves,
setVersion
may run after unmount. Abort the fetch and avoid potential React warnings. This also sets you up to add caching or retries later.Apply this diff:
useEffect(() => { - const getLatestVersion = async () => { + const controller = new AbortController(); + const getLatestVersion = async () => { try { - const res = await fetch( - "https://api.github.com/repos/AmanVarshney01/create-better-t-stack/releases", - ); + const res = await fetch( + "https://api.github.com/repos/AmanVarshney01/create-better-t-stack/releases", + { signal: controller.signal }, + ); if (!res.ok) throw new Error("Failed to fetch version"); - const data = await res.json(); + const data = await res.json(); const latestVersion = data[0].tag_name.replace(/^v/, ""); setVersion(latestVersion); } catch (error) { console.error("Error fetching NPM version:", error); setVersion("latest"); } }; getLatestVersion(); - }, []); + return () => controller.abort(); + }, []);Architecture note: For a public homepage, an unauthenticated client-side call to GitHub’s API risks rate limits. Consider moving this to a server component/route with caching (e.g., revalidate) or switching to the npm registry endpoint for the package’s
dist-tags.latest
, which is simpler to parse and cacheable by your edge/CDN.
19-20
: Clarify log message sourceThe message says “NPM” but the data source is GitHub. Align the message to reduce confusion during debugging.
- console.error("Error fetching NPM version:", error); + console.error("Error fetching version from GitHub releases:", error);apps/web/src/app/layout.tsx (1)
39-40
: Minor SEO nit: add common synonyms for the new keywordAdding a couple of variants can help searchability without changing behavior.
Apply this diff to extend the keywords list:
- "t3env", + "t3env", + "t3 env", + "t3-oss/env",apps/web/src/app/(home)/_components/stack-builder.tsx (1)
1166-1179
: Avoid hardcoding addon ids; derive from TECH_OPTIONS to prevent future driftvalidAddons is a hardcoded whitelist. It can silently drift from TECH_OPTIONS or the CLI if new addons are added later. Use TECH_OPTIONS.addons to derive the allowed set and filter out "none".
Apply this diff to make the list source-of-truth driven:
- const validAddons = stackState.addons.filter((addon) => - [ - "pwa", - "tauri", - "starlight", - "biome", - "husky", - "turborepo", - "ultracite", - "fumadocs", - "oxlint", - "ruler", - "t3env", - ].includes(addon), - ); + const knownAddons = + (TECH_OPTIONS.addons ?? []) + .map((opt) => opt.id) + .filter((id) => id !== "none"); + const validAddons = stackState.addons.filter((addon) => + knownAddons.includes(addon), + );apps/cli/package.json (1)
52-59
: Optional: consider migrating tests to Bun’s built-in runnerPer project guidelines, prefer “bun test” over external runners. This is out-of-scope for this PR but worth a follow-up to simplify toolchain and devDependencies.
Example scripts section using Bun’s runner:
{ "scripts": { "build": "tsdown", "dev": "tsdown --watch", "check-types": "tsc --noEmit", "check": "biome check --write .", "test": "bun test", "test:ui": "bun test --watch", "prepublishOnly": "npm run build" } }I can open a small follow-up PR to migrate tests and remove unused deps if you’d like.
apps/web/content/docs/cli/options.mdx (1)
248-248
: Docs LGTM: Addons list now includest3env
Reads well and matches the CLI flag. Consider adding a one-liner note that the CLI wires T3 Env with zod and provides Next/Nuxt env templates so users know what to expect.
Possible clarification right under the bullet:
- “The CLI sets up T3 Env with zod. Client/server templates are provided for Next/Nuxt; server-only uses env-core.”
If helpful, I can add a short “Usage” snippet showing
--addons t3env
in a full command.apps/cli/README.md (3)
44-44
: Keep feature list in sync with CLI options (missing addons in table).The Addons row omits several options present in the CLI (fumadocs, ultracite, oxlint, ruler). Add them for consistency.
-| **Addons** | • PWA support<br>• Tauri (desktop applications)<br>• Starlight (documentation site)<br>• Biome (linting and formatting)<br>• Husky (Git hooks)<br>• Turborepo (optimized builds)<br>• T3 Env (Type-safe environment variables) | +| **Addons** | • PWA support<br>• Tauri (desktop applications)<br>• Starlight (documentation site)<br>• Biome (linting and formatting)<br>• Husky (Git hooks)<br>• Turborepo (optimized builds)<br>• T3 Env (Type-safe environment variables)<br>• Fumadocs (documentation site)<br>• Ultracite (Biome preset + AI)<br>• Oxlint (Rust linter)<br>• Ruler (AI rules) |
61-61
: Add missing addon "ruler" to the CLI flag help.The
--addons
list is missingruler
, which exists in code (ADDON_COMPATIBILITY
and web constants). Add it to prevent confusion.- --addons <types...> Additional addons (pwa, tauri, starlight, biome, husky, turborepo, fumadocs, ultracite, oxlint, t3env, none) + --addons <types...> Additional addons (pwa, tauri, starlight, biome, husky, turborepo, fumadocs, ultracite, oxlint, ruler, t3env, none)
195-195
: Generalize or update the "Addons 'none'" note to include all addons.Currently lists a subset; either remove the parenthetical or include all addons to avoid drift.
-- **Addons 'none'**: Skips all addons (PWA, Tauri, Starlight, Biome, Husky, Turborepo, T3 Env). +- **Addons 'none'**: Skips all addons (e.g., PWA, Tauri, Starlight, Biome, Husky, Turborepo, T3 Env, Fumadocs, Ultracite, Oxlint, Ruler).apps/cli/src/helpers/addons/t3env-setup.ts (3)
23-29
: Server deps: LGTM, but gate on backend existence.Install
@t3-oss/env-core
+zod
only if a server app exists andbackend !== "none"
.- const serverDir = path.join(projectDir, "apps/server"); - if (await fs.pathExists(serverDir)) { + const serverDir = path.join(projectDir, "apps/server"); + if (backend !== "none" && (await fs.pathExists(serverDir))) {
43-47
: Fix misleading comment for Nuxt branch.The comment says “use the core package” but you install
@t3-oss/env-nuxt
. Update the comment.- // For Nuxt, we'll use the core package + // For Nuxt, use the Nuxt-specific package
57-63
: Success/error messaging: enhance clarity.Consider coloring success with
pc.green
and include which apps were configured (server/web) to aid debugging in multi-app repos.- s.stop("T3 Env configured successfully!"); + s.stop(pc.green("T3 Env configured successfully!"));apps/web/src/lib/constant.ts (1)
513-520
: Icon path consistency for t3env.Most icons use
ICON_BASE_URL
;t3env
points to a local/icon/t3env.svg
. Prefer a consistent source (or confirm the asset exists inpublic/icon/
and is deployed).- icon: "/icon/t3env.svg", + icon: `${ICON_BASE_URL}/t3env.svg`,If the remote asset doesn’t exist yet, add it to the CDN or keep the local path and ensure the file is present in the web app’s public assets.
apps/cli/src/helpers/addons/addons-setup.ts (1)
63-65
: Consider allowing T3 Env without a backend
setupT3Env
exits early whenbackend === "none"
. T3 Env can still be valuable for Next-only apps (client/public env validation). Consider relaxing the restriction and running the web dependency/setup path even without a backend.If you choose to keep the restriction, make sure the prompt/README explicitly calls it out to avoid user confusion.
apps/cli/templates/addons/t3env/apps/server/next/src/env/server.ts.hbs (1)
1-15
: Tighten runtimeEnv mapping and add opt-out for validation in CICurrent config passes
experimental__runtimeEnv: process.env
but doesn’t explicitly scoperuntimeEnv
. To prevent accidental exposure and to improve treeshaking, explicitly map only the keys you declare. Also, add askipValidation
flag controlled bySKIP_ENV_VALIDATION
(commonly used in CI).Apply this diff:
export const env = createEnv({ server: { DATABASE_URL: z.string().url(), BETTER_AUTH_SECRET: z.string().min(1), BETTER_AUTH_URL: z.string().url(), CORS_ORIGIN: z.string().url(), {{#if (includes examples 'ai')}} GOOGLE_GENERATIVE_AI_API_KEY: z.string().min(1), {{/if}} }, - experimental__runtimeEnv: process.env, + // Only provide the vars you defined above to the runtime mapping + runtimeEnv: { + DATABASE_URL: process.env.DATABASE_URL, + BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET, + BETTER_AUTH_URL: process.env.BETTER_AUTH_URL, + CORS_ORIGIN: process.env.CORS_ORIGIN, + {{#if (includes examples 'ai')}} + GOOGLE_GENERATIVE_AI_API_KEY: process.env.GOOGLE_GENERATIVE_AI_API_KEY, + {{/if}} + }, + // Optional: allow skipping validation in CI/local scripts + skipValidation: !!process.env.SKIP_ENV_VALIDATION, + experimental__runtimeEnv: process.env, });Please confirm the targeted
@t3-oss/env-nextjs
version still recommendsexperimental__runtimeEnv
with Next.js, and whether you wantCORS_ORIGIN
to support multiple origins (array or CSV). If yes, we can tweak the schema accordingly.apps/cli/templates/addons/t3env/apps/web/next/src/env/client.ts.hbs (2)
4-17
: Add skipValidation and emptyStringAsUndefined for better DX and CI ergonomics.This prevents noisy failures in CI or on platforms that inject empty strings. It’s a common pattern across T3 Env templates.
Apply this diff:
export const env = createEnv({ client: { NEXT_PUBLIC_SERVER_URL: z.string().url(), {{#if (eq backend 'convex')}} NEXT_PUBLIC_CONVEX_URL: z.string().url(), {{/if}} }, runtimeEnv: { NEXT_PUBLIC_SERVER_URL: process.env.NEXT_PUBLIC_SERVER_URL, {{#if (eq backend 'convex')}} NEXT_PUBLIC_CONVEX_URL: process.env.NEXT_PUBLIC_CONVEX_URL, {{/if}} - }, + }, + // Skip validation in CI or when explicitly requested. + skipValidation: + process.env.CI === "true" || process.env.SKIP_ENV_VALIDATION === "true", + // Treat empty strings as undefined to avoid false positives on some hosts. + emptyStringAsUndefined: true, });
7-9
: Convex key naming LGTM; confirm docs alignment.
NEXT_PUBLIC_CONVEX_URL
matches typical Convex examples. Just ensure the CLI scaffold also writes this key into .env (local) and docs/readme so users don’t miss it.If helpful, I can add .env(.example) insertion and a short README section for Convex with a checklist.
Also applies to: 13-15
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
apps/web/public/icon/t3env.svg
is excluded by!**/*.svg
demo.gif
is excluded by!**/*.gif
📒 Files selected for processing (22)
README.md
(1 hunks)apps/cli/README.md
(3 hunks)apps/cli/package.json
(1 hunks)apps/cli/src/constants.ts
(3 hunks)apps/cli/src/helpers/addons/addons-setup.ts
(2 hunks)apps/cli/src/helpers/addons/t3env-setup.ts
(1 hunks)apps/cli/src/helpers/core/create-readme.ts
(1 hunks)apps/cli/src/prompts/addons.ts
(2 hunks)apps/cli/src/types.ts
(1 hunks)apps/cli/templates/addons/t3env/apps/server/next/next.config.ts
(1 hunks)apps/cli/templates/addons/t3env/apps/server/next/src/env/server.ts.hbs
(1 hunks)apps/cli/templates/addons/t3env/apps/web/next/src/env/client.ts.hbs
(1 hunks)apps/cli/templates/addons/t3env/apps/web/next/src/next.config.ts.hbs
(1 hunks)apps/cli/templates/addons/t3env/apps/web/nuxt/src/env/client.ts.hbs
(1 hunks)apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs
(1 hunks)apps/web/content/docs/cli/options.mdx
(1 hunks)apps/web/content/docs/index.mdx
(1 hunks)apps/web/src/app/(home)/_components/npm-package.tsx
(1 hunks)apps/web/src/app/(home)/_components/stack-builder.tsx
(1 hunks)apps/web/src/app/(home)/analytics/_components/types.ts
(1 hunks)apps/web/src/app/layout.tsx
(1 hunks)apps/web/src/lib/constant.ts
(7 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{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 = ...)
Files:
apps/cli/templates/addons/t3env/apps/server/next/next.config.ts
apps/cli/src/prompts/addons.ts
apps/cli/src/types.ts
apps/web/src/app/(home)/_components/stack-builder.tsx
apps/cli/src/helpers/core/create-readme.ts
apps/web/src/app/(home)/_components/npm-package.tsx
apps/cli/src/helpers/addons/t3env-setup.ts
apps/cli/src/helpers/addons/addons-setup.ts
apps/web/src/app/layout.tsx
apps/web/src/app/(home)/analytics/_components/types.ts
apps/cli/src/constants.ts
apps/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:sqlite
for SQLite; do not usebetter-sqlite3
UseBun.redis
for Redis; do not useioredis
UseBun.sql
for Postgres; do not usepg
orpostgres.js
Use built-inWebSocket
; do not usews
PreferBun.file
overnode:fs
readFile/writeFile
UseBun.$
instead ofexeca
for shelling out
Files:
apps/cli/templates/addons/t3env/apps/server/next/next.config.ts
apps/cli/src/prompts/addons.ts
apps/cli/src/types.ts
apps/web/src/app/(home)/_components/stack-builder.tsx
apps/cli/src/helpers/core/create-readme.ts
apps/web/src/app/(home)/_components/npm-package.tsx
apps/cli/src/helpers/addons/t3env-setup.ts
apps/cli/src/helpers/addons/addons-setup.ts
apps/web/src/app/layout.tsx
apps/web/src/app/(home)/analytics/_components/types.ts
apps/cli/src/constants.ts
apps/web/src/lib/constant.ts
**/package.json
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
In package.json scripts, prefer running files with
bun <file>
instead ofnode <file>
orts-node <file>
Files:
apps/cli/package.json
{**/package.json,**/@(jest|vitest).config.@(js|ts|mjs|cjs)}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
{**/package.json,**/@(jest|vitest).config.@(js|ts|mjs|cjs)}
: Usebun test
instead ofjest
orvitest
Usebun test
to run tests
Files:
apps/cli/package.json
{**/package.json,**/webpack.config.@(js|ts|mjs|cjs),**/esbuild.config.@(js|ts|mjs|cjs)}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use
bun build <file>
instead ofwebpack
oresbuild
Files:
apps/cli/package.json
{**/package.json,**/vite.config.@(js|ts|mjs|cjs)}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use HTML imports with
Bun.serve()
; do not usevite
Files:
apps/cli/package.json
🧬 Code graph analysis (2)
apps/cli/src/helpers/addons/t3env-setup.ts (2)
apps/cli/src/types.ts (1)
ProjectConfig
(160-179)apps/cli/src/utils/add-package-deps.ts (1)
addPackageDependency
(6-43)
apps/cli/src/helpers/addons/addons-setup.ts (1)
apps/cli/src/helpers/addons/t3env-setup.ts (1)
setupT3Env
(9-64)
🪛 LanguageTool
README.md
[grammar] ~42-~42: There might be a mistake here.
Context: ...madocs, Ruler, Ultracite, Oxlint, T3 Env - Examples: Todo, AI - DB Setup: Turso, Ne...
(QB_NEW_EN)
🔇 Additional comments (19)
apps/web/src/app/(home)/_components/npm-package.tsx (1)
34-34
: LGTM: export formatting onlyNo behavioral change; default export remains intact.
README.md (1)
42-42
: LGTM: Added “T3 Env” to the feature listThe documentation change is consistent with the new addon’s display name used elsewhere. No issues.
apps/web/src/app/(home)/_components/stack-builder.tsx (1)
1166-1179
: t3env wiring verified end-to-endAll expected references to
t3env
have been found and correctly configured across the repository:
- CLI constants, types, and prompts (
apps/cli/src/constants.ts
,types.ts
,prompts/addons.ts
)- Dependency map including
@t3-oss/env-*
packages andzod
inapps/cli/src/constants.ts
- Addon setup module (
apps/cli/src/helpers/addons/t3env-setup.ts
)- Templates under
apps/cli/templates/addons/t3env
(with nodotenv
usage)- Web UI constants and types (
apps/web/src/lib/constant.ts
,layout.tsx
, analytics types)- Documentation mentions in CLI options and site docs (
apps/web/content/docs
)No missing wiring detected; this comment can be resolved.
apps/cli/package.json (1)
39-41
: LGTM: Added “t3env” to keywordsThe keyword helps npm search visibility and aligns with the new addon. No functional impact.
apps/cli/src/types.ts (1)
51-53
: Exhaustivet3env
coverage confirmed
All references to the newt3env
addon have been verified across the CLI and web layers, including:
- apps/cli/src/constants.ts (defaults & dependency map)
- apps/cli/src/prompts/addons.ts (prompt label/hint and grouping)
- apps/cli/src/helpers/core/create-readme.ts (README generation)
- apps/cli/src/helpers/addons/addons-setup.ts (import & invocation of setupT3Env)
- apps/web/src/lib/constant.ts (display metadata & default presets)
- apps/web/src/app/layout.tsx, analytics types, and stack-builder component
- Documentation in apps/web/content/docs (options.mdx & index.mdx)
Type narrowing for
Addons
remains exhaustive and consistent. No missing references detected—ready to merge.apps/cli/src/helpers/core/create-readme.ts (1)
471-473
: Feature blurb for T3 Env — good additionAccurately describes the addon and matches naming used elsewhere (“T3 Env”). No changes needed.
apps/cli/templates/addons/t3env/apps/web/nuxt/src/env/client.ts.hbs (1)
1-11
: Nuxt client env schema is correct; no runtimeEnv needed
@t3-oss/env-nuxt
auto-fillsruntimeEnv
, so providing only theclient
schema is expected. Validations for public URLs look good. (env.t3.gg)apps/web/src/app/(home)/analytics/_components/types.ts (1)
355-358
: Analytics config: New addon entry for T3 Env looks good.Label and color slot are consistent with neighboring entries.
apps/cli/src/constants.ts (2)
166-167
: Addon compatibility entry for t3env set to [] looks fine.No hard constraints makes sense since env tooling spans frameworks. Revisit later if specific frameworks require special handling.
17-17
: Addon Compatibility for “t3env” Verified– The
ADDON_COMPATIBILITY
map explicitly listst3env: []
, meaning it’s considered compatible by default (no frontend constraint) since an empty array is treated as “always compatible.”
– In the interactive prompt (getAddonsChoice
),validateAddonCompatibility("t3env", frontends)
always returnsisCompatible: true
, so “T3 Env” remains selectable even if no frontends are chosen.
– During scaffold execution,t3env
setup (helpers/addons/t3env-setup.ts
) bails out with a warning ifbackend === "none"
, skipping environment-file generation but not failing the overall flow.No further auto-removal logic exists for
t3env
when either backend or frontend is “none,” but the warning int3env-setup.ts
ensures graceful handling.No action required unless you’d prefer stricter UX (e.g., filtering “T3 Env” out of the prompt when
backend: none
or whenfrontend: none
).apps/cli/src/helpers/addons/t3env-setup.ts (1)
49-54
: No changes needed for the fallback branch’szod
dependency
The@t3-oss/env-core
package relies onzod
(as a peer dependency), so includingzod
alongside@t3-oss/env-core
in the “other frameworks” fallback is correct. There’s no template‐level import to correlate here—zod
is required at runtime by the core environment package.apps/web/src/lib/constant.ts (3)
600-601
: Preset default: including t3env by default is fine.Matches CLI defaults. Ensure “Generate command” and docs reflect this to avoid surprises for users.
736-737
: DEFAULT_STACK includes t3env: LGTM.Keeps the marketing site and CLI in sync.
622-623
: Verify T3 Env addon only targets the web layer in the Convex presetThe Convex preset still pulls in the
t3env
addon even though it setsruntime: "none"
and omits any server scaffolding. Please double-check thatsetupT3Env
does not assume or mutate a traditional backend package—i.e. it only operates on your web project and won’t touchapps/server
(or any non-existent serverpackage.json
).• In
apps/cli/src/helpers/addons/t3env-setup.ts
, confirm all file operations and dependency injections are scoped to the web app (e.g. underapps/web
or its equivalent).
• Ensure there are no references toapps/server
,serverAppDir
, or direct writes to a backendpackage.json
whenconfig.backend === "convex"
.
• If you’re unsure, run a targeted grep for backend paths in that file:
•grep -R "apps/server" -n apps/cli/src/helpers/addons/t3env-setup.ts
•grep -R "package\\.json" -n apps/cli/src/helpers/addons/t3env-setup.ts
If
setupT3Env
is already isolated to the web directory, no changes are needed here.apps/cli/templates/addons/t3env/apps/web/next/src/next.config.ts.hbs (1)
1-1
: Use a relative import for the env module in next.config.tsNext.js loads next.config.ts via Node at runtime and does not resolve TypeScript path aliases like
"@/…"
. In your template, next.config.ts is placed under src/, so you should import the env client using a path relative to that file:- import "@/env/client"; + import "./env/client";If you ever move next.config.ts to the project root (outside src/), then use:
import "./src/env/client";Please confirm where the generator emits next.config.ts —in src/ or at the project root—and update the import path accordingly.
apps/cli/src/helpers/addons/addons-setup.ts (1)
12-12
: Import placement LGTMImporting
setupT3Env
alongside other addon setup helpers is consistent with the existing pattern.apps/cli/src/prompts/addons.ts (2)
61-64
: Addon display for “T3 Env” looks goodLabel and hint are concise and consistent with other entries.
76-76
: Grouping under “Other” is reasonable; no conflicts detected
t3env
sits well with other cross-cutting addons. No compatibility side-effects here.apps/cli/templates/addons/t3env/apps/web/next/src/env/client.ts.hbs (1)
1-2
: Imports look correct and minimal.No issues. These are the expected imports for the T3 Env + Zod setup in a Next.js client env module.
zod: "^4.0.14", | ||
"@t3-oss/env-core": "^0.13.8", | ||
"@t3-oss/env-nextjs": "^0.13.8", | ||
"@t3-oss/env-nuxt": "^0.13.8", |
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.
💡 Verification agent
🧩 Analysis chain
Pin checks: ensure versions exist and are compatible (Zod v4 + @t3-oss/env).*
Zod v4 is specified. Some ecosystems still assume v3; ensure templates and @t3-oss/env* peer ranges are compatible with v4 to avoid runtime/TS errors.
🏁 Script executed:
#!/bin/bash
# Check published versions and peer deps for compatibility.
for pkg in zod @t3-oss/env-core @t3-oss/env-nextjs @t3-oss/env-nuxt; do
echo "== $pkg latest =="
npm view "$pkg" version
echo "== $pkg peerDependencies =="
npm view "$pkg" peerDependencies --json | jq .
done
Length of output: 1642
Ensure zod version matches @t3-oss/env peer dependency*
The published v0.13.8 of @t3-oss/env-core, env-nextjs, and env-nuxt peer-depend on
"zod": "^3.24.0 || ^4.0.0-beta.0"
which does not include the stable v4.0.14 you’ve pinned. Installing zod@^4.0.14 will trigger a peer-dependency conflict.
You have two remediation paths:
• Pin to a prerelease zod that satisfies the peer range:
– In apps/cli/src/constants.ts (lines 147–150), change
- zod: "^4.0.14",
+ zod: "^4.0.0-beta.0",
This will align with the existing peer-dependency and avoid install-time errors.
• Upgrade to a future @t3-oss/env-* release that adds stable zod v4 support (once published).
🤖 Prompt for AI Agents
In apps/cli/src/constants.ts around lines 147–150, the pinned "zod": "^4.0.14"
conflicts with the peer range declared by @t3-oss/env-* (which accepts "zod":
"^3.24.0 || ^4.0.0-beta.0"); to fix, either change the zod entry to a prerelease
that satisfies the peer range (for example use a ^4.0.0-beta.x prerelease
specifier) so installs don't produce peer-dependency conflicts, or upgrade the
@t3-oss/env-* packages to a future release that formally supports stable zod v4
and then pin zod to a stable v4 once that dependency change is available.
💡 Verification agent
🧩 Analysis chain
Consider gating/removing dotenv when T3 Env is present.
Since T3 Env is now default and the guidelines discourage dotenv with Bun, ensure scaffolding doesn’t include both, to avoid duplicated/conflicting env loading.
🏁 Script executed:
#!/bin/bash
# Find any templates or code that still import/use dotenv.
rg -nP -C2 '\bdotenv\b|\bconfig\s*\(' apps/cli/templates apps || true
Length of output: 14762
Remove direct dotenv usage from CLI scaffolding now that T3 Env is the default
T3 Env packages (@t3-oss/env-core
, env-nextjs
, env-nuxt
, etc.) now handle .env
loading across runtimes, and Bun auto-loads .env
files out of the box. Keeping dotenv
imports/dependencies leads to duplicated or conflicting environment loading. Please remove or gate all direct dotenv
usage in your scaffolding and helper code:
• In apps/cli/src/constants.ts
– Remove the "dotenv": "^17.2.1",
entry.
• In all Prisma templates (apps/cli/templates/db/prisma/*/prisma.config.ts.hbs
)
– Drop the top-level import "dotenv/config";
.
• In backend server templates (apps/cli/templates/backend/server/**/src/index.ts.hbs
)
– Remove any import "dotenv/config";
(Hono, Elysia, Fastify, Express). If you still need to support plain Node projects without Bun, you can instead wrap this import under a {{#if (eq runtime "node")}}…{{/if}}
check.
• In package-template JSON files
– apps/cli/templates/backend/server/server-base/package.json.hbs
and …/next/package.json.hbs
: drop the "dotenv": "^17.2.1"
dependency.
• In deployment scripts and helpers
– apps/cli/templates/deploy/alchemy/alchemy.run.ts.hbs
: remove the import { config } from "dotenv";
and all config({ path: … })
calls.
– All Alchemy setup helpers (alchemy-*.ts
under src/helpers/deployment/alchemy/
): remove "dotenv"
from the devDependencies
arrays passed to addPackageDependency
.
• In database-provider setup code
– apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts
: stop injecting import "dotenv/config";
into the generated Prisma config.
By eliminating these, you’ll avoid double-loading environment variables and fully rely on T3 Env’s loading across both Bun and Node runtimes.
🤖 Prompt for AI Agents
In apps/cli/src/constants.ts around lines 147 to 150, the package list still
includes a direct dotenv dependency which must be removed; delete the line
containing "dotenv": "^17.2.1" and ensure no other code in this file imports or
references dotenv. Also sweep the CLI scaffolding and templates as described in
the review: remove top-level import "dotenv/config" from Prisma and backend
server template files (or guard it with a {{#if (eq runtime "node")}}…{{/if}}),
drop "dotenv" from the package-template JSON files listed, remove dotenv imports
and config(...) calls from deployment scripts/helpers, and stop injecting import
"dotenv/config"; in prisma-postgres-setup.ts so T3 Env/Bun handle .env loading
exclusively.
if (addons.includes("t3env")) { | ||
await setupT3Env(config); | ||
} |
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.
💡 Verification agent
🧩 Analysis chain
Ensure zod is installed for Next.js web when adding T3 Env
The client
/server
env templates rely on zod. In t3env-setup.ts
, Next.js branch currently installs @t3-oss/env-nextjs
only. It should also add zod
to the web app to avoid build-time errors in env/client.ts
and/or env/server.ts
.
Apply this diff in apps/cli/src/helpers/addons/t3env-setup.ts
:
- if (hasNext) {
- await addPackageDependency({
- dependencies: ["@t3-oss/env-nextjs"],
- projectDir: webDir,
- });
- } else if (hasNuxt) {
+ if (hasNext) {
+ await addPackageDependency({
+ dependencies: ["@t3-oss/env-nextjs", "zod"],
+ projectDir: webDir,
+ });
+ } else if (hasNuxt) {
// For Nuxt, we'll use the core package
await addPackageDependency({
dependencies: ["@t3-oss/env-nuxt", "zod"],
projectDir: webDir,
});
} else {
// For other frameworks, use the core package
await addPackageDependency({
dependencies: ["@t3-oss/env-core", "zod"],
projectDir: webDir,
});
}
Also confirm dependencyVersionMap
includes pinned versions for zod
, @t3-oss/env-core
, @t3-oss/env-nextjs
, and @t3-oss/env-nuxt
to keep installs deterministic.
🏁 Script executed:
#!/bin/bash
# Inspect Next.js branch in t3env-setup.ts to verify if "zod" is included
rg -n "addPackageDependency" -C3 --glob "apps/cli/src/helpers/addons/t3env-setup.ts"
# Locate dependencyVersionMap to ensure pinned versions for required packages
rg -n "dependencyVersionMap" -C3
Length of output: 5018
🏁 Script executed:
#!/bin/bash
# Display the section of dependencyVersionMap around @t3-oss/env-core, @t3-oss/env-nextjs, and zod
sed -n '120,160p' apps/cli/src/constants.ts
Length of output: 1224
Ensure zod
is added to the Next.js branch in t3env-setup.ts
The Next.js path in setupT3Env
currently installs only @t3-oss/env-nextjs
, but the generated env/client.ts
/env/server.ts
rely on zod
, which will lead to build failures.
• File: apps/cli/src/helpers/addons/t3env-setup.ts
(around line 38)
- if (hasNext) {
- await addPackageDependency({
- dependencies: ["@t3-oss/env-nextjs"],
- projectDir: webDir,
- });
- } else if (hasNuxt) {
+ if (hasNext) {
+ await addPackageDependency({
+ dependencies: ["@t3-oss/env-nextjs", "zod"],
+ projectDir: webDir,
+ });
+ } else if (hasNuxt) {
• I’ve confirmed in apps/cli/src/constants.ts
that dependencyVersionMap
pins versions for
– zod
(^4.0.14
)
– @t3-oss/env-core
(^0.13.8
)
– @t3-oss/env-nextjs
(^0.13.8
)
– @t3-oss/env-nuxt
(^0.13.8
)
so installs remain deterministic.
📝 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.
if (addons.includes("t3env")) { | |
await setupT3Env(config); | |
} | |
if (hasNext) { | |
await addPackageDependency({ | |
dependencies: ["@t3-oss/env-nextjs", "zod"], | |
projectDir: webDir, | |
}); | |
} else if (hasNuxt) { |
🤖 Prompt for AI Agents
In apps/cli/src/helpers/addons/t3env-setup.ts around line 38, the Next.js branch
of setupT3Env currently only installs @t3-oss/env-nextjs but omits zod (and
should also include @t3-oss/env-core), causing generated env/client.ts and
env/server.ts to fail; update the Next.js install step to add zod and
@t3-oss/env-core to the list of packages to install (using the pinned versions
from dependencyVersionMap/constants) so installs remain deterministic and match
the generated code's runtime dependencies.
// T3 Env requires a backend to be present | ||
if (backend === "none") { | ||
s.stop(pc.yellow("T3 Env requires a backend to be configured")); | ||
return; | ||
} |
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.
Incorrect early return and spinner misuse block web-only setups.
- T3 Env does not require a separate backend; Next/Nuxt-only projects should still be configured.
- Calling
s.stop()
befores.start()
is an API misuse.
Refactor to always process the web app and only skip the server section when no backend/server app exists.
- // T3 Env requires a backend to be present
- if (backend === "none") {
- s.stop(pc.yellow("T3 Env requires a backend to be configured"));
- return;
- }
+ // Proceed regardless of backend; we'll conditionally configure server/web below.
📝 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.
// T3 Env requires a backend to be present | |
if (backend === "none") { | |
s.stop(pc.yellow("T3 Env requires a backend to be configured")); | |
return; | |
} | |
- // T3 Env requires a backend to be present | |
- if (backend === "none") { | |
- s.stop(pc.yellow("T3 Env requires a backend to be configured")); | |
- return; | |
// Proceed regardless of backend; we'll conditionally configure server/web below. |
🤖 Prompt for AI Agents
In apps/cli/src/helpers/addons/t3env-setup.ts around lines 13 to 17, remove the
early return and the s.stop() call so web-only projects still run; always run
the web app configuration path and only skip the server/backend configuration
when backend === "none" (or when there is no server app detected). Ensure you
never call s.stop() before s.start(): start the spinner before any long-running
step and stop it after that specific step completes or fails, and isolate
spinner usage to the server/backend section so skipping the server does not
attempt to stop a spinner that was never started.
try { | ||
s.start("Setting up T3 Env for type-safe environment variables..."); | ||
|
||
// Add dependencies to server | ||
const serverDir = path.join(projectDir, "apps/server"); | ||
if (await fs.pathExists(serverDir)) { | ||
await addPackageDependency({ | ||
dependencies: ["@t3-oss/env-core", "zod"], | ||
projectDir: serverDir, | ||
}); | ||
} |
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
Start the spinner before any conditional exits; improve messaging.
Begin the spinner first, then handle per-app setup. This avoids calling stop before start and provides clearer UX.
- try {
- s.start("Setting up T3 Env for type-safe environment variables...");
+ try {
+ s.start("Setting up T3 Env for type-safe environment variables...");
Optionally, after computing presence, add a note if neither app exists:
+ const serverDir = path.join(projectDir, "apps/server");
+ const webDir = path.join(projectDir, "apps/web");
+ const hasServer = await fs.pathExists(serverDir);
+ const hasWeb = await fs.pathExists(webDir);
+ if (!hasServer && !hasWeb) {
+ s.stop(pc.yellow("No apps/server or apps/web found; skipping T3 Env setup."));
+ return;
+ }
📝 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.
try { | |
s.start("Setting up T3 Env for type-safe environment variables..."); | |
// Add dependencies to server | |
const serverDir = path.join(projectDir, "apps/server"); | |
if (await fs.pathExists(serverDir)) { | |
await addPackageDependency({ | |
dependencies: ["@t3-oss/env-core", "zod"], | |
projectDir: serverDir, | |
}); | |
} | |
try { | |
s.start("Setting up T3 Env for type-safe environment variables..."); | |
const serverDir = path.join(projectDir, "apps/server"); | |
const webDir = path.join(projectDir, "apps/web"); | |
const hasServer = await fs.pathExists(serverDir); | |
const hasWeb = await fs.pathExists(webDir); | |
if (!hasServer && !hasWeb) { | |
s.stop(pc.yellow("No apps/server or apps/web found; skipping T3 Env setup.")); | |
return; | |
} | |
// Add dependencies to server | |
if (hasServer) { | |
await addPackageDependency({ | |
dependencies: ["@t3-oss/env-core", "zod"], | |
projectDir: serverDir, | |
}); | |
} |
🤖 Prompt for AI Agents
In apps/cli/src/helpers/addons/t3env-setup.ts around lines 19 to 29, the spinner
is started only inside a branch which can lead to stop being called before start
and unclear messaging; move s.start("Setting up T3 Env for type-safe environment
variables...") to before checking app directories so the spinner begins
unconditionally, then compute existence of apps (server/client) and run per-app
setup while updating spinner messages per-app; if neither app exists, update the
spinner or log a clear message indicating no apps found and then stop the
spinner.
if (hasNext) { | ||
await addPackageDependency({ | ||
dependencies: ["@t3-oss/env-nextjs"], | ||
projectDir: webDir, | ||
}); | ||
} else if (hasNuxt) { |
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.
Next.js branch should also add zod.
Templates typically import zod schemas; env-nextjs
doesn’t pull zod
transitively. Add it to avoid compile-time errors.
- if (hasNext) {
+ if (hasNext) {
await addPackageDependency({
- dependencies: ["@t3-oss/env-nextjs"],
+ dependencies: ["@t3-oss/env-nextjs", "zod"],
projectDir: webDir,
});
📝 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.
if (hasNext) { | |
await addPackageDependency({ | |
dependencies: ["@t3-oss/env-nextjs"], | |
projectDir: webDir, | |
}); | |
} else if (hasNuxt) { | |
if (hasNext) { | |
await addPackageDependency({ | |
dependencies: ["@t3-oss/env-nextjs", "zod"], | |
projectDir: webDir, | |
}); | |
} else if (hasNuxt) { |
🤖 Prompt for AI Agents
In apps/cli/src/helpers/addons/t3env-setup.ts around lines 37 to 42, the Next.js
branch adds @t3-oss/env-nextjs but omits zod which is not pulled transitively;
update the call to addPackageDependency in the hasNext branch to also include
"zod" in the dependencies array so zod is installed alongside @t3-oss/env-nextjs
to prevent compile-time errors from missing schema imports.
@@ -0,0 +1 @@ | |||
import "@/env/server"; |
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.
💡 Verification agent
🧩 Analysis chain
Same alias-resolution pitfall: switch to a relative import in server Next config
Using "@/env/server" in next.config.ts
is prone to resolution failures. Use a relative path.
-import "@/env/server";
+// If next.config.ts is at the app root:
+import "./src/env/server";
+// If placed under src/:
+// import "./env/server";
Double-check the final file location produced by the generator and align the relative path accordingly.
🏁 Script executed:
#!/bin/bash
set -e
# Print current working directory
pwd
# List files under the Next.js config directory
find apps/cli/templates/addons/t3env/apps/server/next -maxdepth 2 -type f -print
# Find environment schema files in the template
find apps/cli/templates/addons/t3env -type f \( -name "server.ts" -o -name "env.ts" \) -print
Length of output: 274
🏁 Script executed:
#!/bin/bash
set -e
echo "Listing all files under apps/cli/templates/addons/t3env:"
find apps/cli/templates/addons/t3env -type f
Length of output: 518
🏁 Script executed:
#!/bin/bash
# Display the beginning of the Next.js server template config to inspect import paths
sed -n '1,100p' apps/cli/templates/addons/t3env/apps/server/next/next.config.ts
Length of output: 102
Switch to a relative import in next.config.ts
Importing via the @/...
alias in your Next.js config isn’t supported at load time, causing resolution failures. Update the import to a relative path from the next.config.ts
file to the generated server.ts
module:
• File needing update:
– apps/server/next/next.config.ts
• Change the import to point at src/env/server.ts
:
-import "@/env/server";
+import "./src/env/server";
Verify this path matches your final project structure (e.g., if next.config.ts
ends up under a different directory, adjust accordingly).
📝 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 "@/env/server"; | |
import "./src/env/server"; |
🤖 Prompt for AI Agents
In apps/cli/templates/addons/t3env/apps/server/next/next.config.ts around line
1, the file uses an absolute alias import "@" which Next.js can't resolve at
config load time; replace the aliased import with a relative import pointing to
the generated server module (e.g., "./src/env/server" or "../src/env/server"
depending on next.config.ts location) so the config uses a filesystem path;
update the import to the correct relative path to src/env/server and verify the
path matches the final project layout.
client: { | ||
NEXT_PUBLIC_SERVER_URL: z.string().url(), | ||
{{#if (eq backend 'convex')}} | ||
NEXT_PUBLIC_CONVEX_URL: z.string().url(), | ||
{{/if}} | ||
}, |
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.
💡 Verification agent
🧩 Analysis chain
Keep client keys and runtimeEnv in lockstep.
Given the conditional Convex block, any future additions to client
must be mirrored in runtimeEnv
. T3 Env will usually catch mismatches at compile time, but template drift can still happen during refactors.
Run this quick repo check to ensure the Next template importing this file resolves path aliases and that the dependency is declared:
Also applies to: 11-16
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Verify next.config imports the client env (fail fast validation at build time)
rg -n --color=always $'from\\s+[\'"]@/env/client[\'"]' apps/cli/templates/addons/t3env/apps/web/next/src/next.config.ts.hbs || {
echo "Missing import of '@/env/client' in next.config.ts.hbs" >&2; exit 1; }
# 2) Ensure '@' path alias exists in the Next web template tsconfig
tsconfigs=$(fd -t f --full-path 'apps/cli/templates/addons/t3env/apps/web/next/.*tsconfig.*' || true)
if [ -n "$tsconfigs" ]; then
echo "$tsconfigs" | xargs -I{} rg -n -C2 --color=always '"paths"\s*:\s*\{\s*"@/\*"\s*:\s*\["\./src/\*"\]' {} || {
echo "Missing '@/ -> ./src/*' path alias in Next web tsconfig" >&2; exit 1; }
else
echo "No tsconfig found for Next web template; please verify alias setup." >&2; exit 1
fi
# 3) Confirm the dependency is declared somewhere in templates
rg -n --color=always '@t3-oss/env-nextjs' || {
echo "Dependency '@t3-oss/env-nextjs' not found in template manifests" >&2; exit 1; }
Length of output: 281
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 2) Verify tsconfig path alias for '@/*'
echo "Checking tsconfig path aliases..."
tsconfigs=$(fd -t f --full-path 'apps/cli/templates/addons/t3env/apps/web/next/.*tsconfig.*' || true)
if [ -n "$tsconfigs" ]; then
echo "$tsconfigs" | while read -r f; do
echo "-- Inspecting $f --"
rg -n -C2 '"paths"\s*:\s*\{[^}]*"@/\*"\s*:\s*\["\.\/src\/\*"\]' "$f" \
|| echo "Missing '@/*' path alias in $f"
done
else
echo "No tsconfig found for Next web template"
fi
# 3) Confirm the dependency '@t3-oss/env-nextjs'
echo
echo "Checking for '@t3-oss/env-nextjs' dependency..."
rg -n '@t3-oss/env-nextjs' || echo "Dependency '@t3-oss/env-nextjs' not found in template manifests"
Length of output: 836
Action required: Add missing client env import & verify path alias
The repo check indicates two critical gaps in the Next web template:
- Missing import of the client env in
next.config.ts.hbs
.
The fileapps/cli/templates/addons/t3env/apps/web/next/src/next.config.ts.hbs
does not import the client-side environment, causing failsafe validation to be bypassed run1. - No TypeScript config found for path alias.
Our search didn’t locate anytsconfig.json
underapps/cli/templates/addons/t3env/apps/web/next/
, so the@/* → ./src/*
alias may be unset or in a differently named config run2.
The dependency @t3-oss/env-nextjs
is already declared and used in templates—no action needed there run2.
Please address the following:
• In apps/cli/templates/addons/t3env/apps/web/next/src/next.config.ts.hbs
, add at the top:
+ import { createEnv } from '@/env/client';
• Locate (or create) the Next web template’s TypeScript config (tsconfig.json
or tsconfig.base.json
) and ensure it includes:
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}
🤖 Prompt for AI Agents
In apps/cli/templates/addons/t3env/apps/web/next/src/client.ts.hbs around lines
5 to 10, the template defines client env schema but the Next template
next.config.ts.hbs is missing the required import of the generated client env;
update apps/cli/templates/addons/t3env/apps/web/next/src/next.config.ts.hbs to
import the client env at the top (import { clientEnv } from
'<path-to-client-env>') and use it with env-nextjs middleware as needed, and
also locate or create the Next web template TypeScript config (tsconfig.json or
tsconfig.base.json) under apps/cli/templates/addons/t3env/apps/web/next/ and add
the compilerOptions.paths mapping to map "@/*" to "./src/*" so the import path
alias resolves correctly.
@@ -1,3 +1,5 @@ | |||
import "./env"; |
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.
💡 Verification agent
🧩 Analysis chain
Import path and unconditional import will break non-t3env scaffolds
- Path is wrong: the generated file is
src/env/client.ts
, not./env
. - Import is unconditional; projects without the addon will fail at build/TS time.
Gate the import behind the addon flag and point to the correct file.
Apply:
- import "./env";
+ {{#if (includes addons "t3env")}}import "~/env/client";{{/if}}
If the includes
helper isn’t available in your Handlebars runtime, switch to whatever helper you already use for array membership (or add one) and keep the same intent.
To confirm helper availability across templates:
🏁 Script executed:
#!/usr/bin/env bash
# Look for existing array-membership helpers in templates
rg -n -C2 "{{#if \(includes " apps/cli/templates || true
rg -n -C2 "{{#if \(some " apps/cli/templates || true
Length of output: 293
🏁 Script executed:
#!/usr/bin/env bash
# Search for includes helper usage in Handlebars templates
rg -nF '{{#if (includes' -g '*.hbs' apps/cli/templates || true
# Search for 'some' helper usage in Handlebars templates
rg -nF '{{#if (some' -g '*.hbs' apps/cli/templates || true
# Search for includes helper registration in TypeScript code
rg -nP 'registerHelper\(\s*["'\'']?includes["'\'']?,' -g '*.ts' apps/cli || true
# Search for any helper registrations to locate available helpers
rg -n 'registerHelper' -g '*.ts' apps/cli || true
Length of output: 4376
🏁 Script executed:
#!/usr/bin/env bash
# Display the beginning of the helper registration file to verify available helpers
sed -n '1,200p' apps/cli/src/utils/template-processor.ts
Length of output: 1334
Fix conditional Nuxt env import for t3env addon
The Nuxt scaffold currently unconditionally imports ./env
, but the generated file actually lives at src/env/client.ts
, and projects without the t3env
addon will break at build time. We’ve confirmed that the includes
helper is already registered (see apps/cli/src/utils/template-processor.ts
) and used throughout other templates.
• File to update:
• apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs (line 1)
• Change the import to be conditional on the t3env
addon and point to the correct path:
- import "./env";
+ {{#if (includes addons "t3env")}}import "~/env/client";{{/if}}
This ensures that only projects with the t3env
addon include the client‐side env shim, and the module resolution aligns with the actual file location.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import "./env"; | |
++ b/apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs | |
@@ -1,1 +1,1 | |
{{#if (includes addons "t3env")}}import "~/env/client";{{/if}} |
🤖 Prompt for AI Agents
In apps/cli/templates/frontend/nuxt/nuxt.config.ts.hbs around line 1, the
template currently unconditionally imports ./env which breaks projects without
the t3env addon and points to the wrong location; update the template to
conditionally include the client shim only when the t3env addon is present by
using the existing includes helper to wrap the import, and change the import
target to the correct client path (src/env/client.ts) so only projects with
t3env will import the client-side env shim.
@@ -114,7 +114,7 @@ Skip prompts and use the default stack: | |||
--database sqlite \ | |||
--orm drizzle \ | |||
--auth \ | |||
--addons turborepo | |||
--addons turborepo t3env |
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.
Docs inconsistency: only npm example includes t3env; bun/pnpm examples and the flags list omit it
This will confuse users about the default stack. Align all tabs and the cheat sheet.
Apply these diffs:
@@
<Tab value="bun">
```bash
bun create better-t-stack@latest my-webapp \
--frontend tanstack-router \
--backend hono \
--database sqlite \
--orm drizzle \
--auth \
- --addons turborepo
+ --addons turborepo t3env
```
</Tab>
@@
<Tab value="pnpm">
```bash
pnpm create better-t-stack@latest my-webapp \
--frontend tanstack-router \
--backend hono \
--database sqlite \
--orm drizzle \
--auth \
- --addons turborepo
+ --addons turborepo t3env
```
</Tab>
@@
- --addons turborepo t3env
+ --addons turborepo t3env
```
</Tab>
Also add t3env to the flags cheat sheet:
- - `--addons`: turborepo, pwa, tauri, biome, husky, starlight, fumadocs, ultracite, oxlint, ruler, none
+ - `--addons`: turborepo, pwa, tauri, biome, husky, starlight, fumadocs, ultracite, oxlint, ruler, t3env, none
🤖 Prompt for AI Agents
In apps/web/content/docs/index.mdx around line 117, the install command examples
are inconsistent: only the npm example includes the "--addons t3env" flag while
the bun and pnpm examples and the flags cheat sheet omit it; update the bun and
pnpm command blocks to add "--addons turborepo t3env" (matching the npm example)
and add an entry for "t3env" to the flags cheat sheet so all tabs and the cheat
sheet consistently show the t3env addon.
color: "hsl(var(--chart-7))", | ||
}, | ||
none: { | ||
label: "No Addons", | ||
color: "hsl(var(--chart-7))", | ||
color: "hsl(var(--chart-8))", | ||
}, |
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.
💡 Verification agent
🧩 Analysis chain
Verify availability of CSS token --chart-8 before using it.
You bumped turborepo to --chart-7
and none
to --chart-8
. Ensure --chart-8
exists in the theme; otherwise charts will fallback or render inconsistently.
🏁 Script executed:
#!/bin/bash
# Verify that --chart-8 is defined somewhere in CSS/vars.
rg -nP --type css --type scss --type tsx --type ts -C2 'var\(--chart-8\)' || true
rg -nP --type css --type scss --type tsx --type ts -C2 '--chart-8:' || true
Length of output: 599
🏁 Script executed:
#!/bin/bash
# Search for any definitions or usages of --chart-7 and --chart-8 across the codebase
# Find where --chart-7 is defined to locate the CSS variable declarations
rg -n -- '--chart-7' -C2
# Find any occurrences of --chart-8 (definition or usage)
rg -n -- '--chart-8' -C2
Length of output: 137
🏁 Script executed:
#!/bin/bash
# Correctly search for CSS variable definitions and usages of --chart-7 and --chart-8
# 1. Definitions in CSS/SCSS files
rg -n -C2 '\-\-chart-(7|8)\s*:' -g '*.css' -g '*.scss'
# 2. Usages via var(...) in CSS/SCSS/TS/TSX
rg -n -C2 'var\(--chart-(7|8)\)' -g '*.css' -g '*.scss' -g '*.ts' -g '*.tsx'
Length of output: 10659
Add missing CSS variable --chart-8
in your global styles
The lookup shows that --chart-8
is referenced in apps/web/src/app/(home)/analytics/_components/types.ts (lines 365–366) but not defined in your global stylesheet (only --chart-5
, --chart-6
, and --chart-7
exist). Without a definition, any usage of hsl(var(--chart-8))
will be invalid and render inconsistently.
Please add a matching entry for --chart-8
in apps/web/src/app/global.css alongside the other chart variables:
• File: apps/web/src/app/global.css
• Insert after the existing --chart-7
definition
diff --git a/apps/web/src/app/global.css b/apps/web/src/app/global.css
index abcdef0..1234567 100644
--- a/apps/web/src/app/global.css
+++ b/apps/web/src/app/global.css
@@ -191,6 +191,7 @@
--chart-5: 27 87% 67%;
--chart-6: 210 80% 55%;
--chart-7: 330 75% 60%;
+ --chart-8: 90 70% 50%; /* <-- define this to match your theme palette */
--sidebar: oklch(0.93 0.01 264.52);
--sidebar-foreground: oklch(0.44 0.04 279.33);
Adjust the HSL values (90 70% 50%
) to fit your design’s color scheme. Once defined, hsl(var(--chart-8))
will resolve correctly.
📝 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.
color: "hsl(var(--chart-7))", | |
}, | |
none: { | |
label: "No Addons", | |
color: "hsl(var(--chart-7))", | |
color: "hsl(var(--chart-8))", | |
}, | |
++ b/apps/web/src/app/global.css | |
@@ -191,6 +191,7 @@ | |
--chart-5: 27 87% 67%; | |
--chart-6: 210 80% 55%; | |
--chart-8: 90 70% 50%; /* define this to match your theme palette */ | |
--sidebar: oklch(0.93 0.01 264.52); | |
--sidebar-foreground: oklch(0.44 0.04 279.33); |
🤖 Prompt for AI Agents
In apps/web/src/app/(home)/analytics/_components/types.ts around lines 361–366
the color uses hsl(var(--chart-8)) but --chart-8 is missing from the global
stylesheet; open apps/web/src/app/global.css and add a --chart-8 variable entry
immediately after the existing --chart-7 definition (use HSL values appropriate
for your theme, e.g., "90 70% 50%" or other chosen values) so that
hsl(var(--chart-8)) resolves correctly across the app.
Possible alternative: https://envin.turbostarter.dev/ |
plz |
This pull request introduces support for the T3 Env addon.
Next Steps
References:
[Feature Request] Add Support for t3-env package and backend static serving #253
Request for T3 ENV #422
Summary by CodeRabbit
New Features
Documentation
Chores