Migrating from T3 Env
Replace createEnv and runtimeEnv with a flat ArkEnv schema.
A T3 Env Next.js setup keeps a runtimeEnv map in sync with the
schema. ArkEnv keeps the flat env object and drops that map.
T3 Env is a major inspiration for that security model. The cheatsheet of what else changes is Why ArkEnv?.
What changes
Edit files against this mapping. The flat schema replaces the nested
server / client / runtimeEnv object.
| Feature | T3 Env | ArkEnv |
|---|---|---|
| Core function | createEnv from @t3-oss/env-nextjs | arkenv from @arkenv/nextjs or @arkenv/core |
| Schema structure | Nested { server, client, runtimeEnv } | Flat schema (optional two-module recipe for name isolation) |
| Client inlining | Manual runtimeEnv object | withArkEnv writes the mapping |
| Validator | Zod only | ArkType via @arkenv/core, or Zod and Valibot via @arkenv/standard |
A flat layout still infers types and throws if client code reads a server key. Use the two-module recipe when secret names must stay out of the client graph.
Next.js migration steps
Work through these steps on an existing Next.js app.
Install ArkEnv and remove T3 Env
ArkType:
npm install @arkenv/core @arkenv/nextjs arktype
npm rm @t3-oss/env-nextjsZod:
npm install @arkenv/standard @arkenv/nextjs zod
npm rm @t3-oss/env-nextjsValibot:
npm install @arkenv/standard @arkenv/nextjs valibot @valibot/to-json-schema
npm rm @t3-oss/env-nextjsWrap next.config.ts
import type { NextConfig } from "next";
import { } from "@arkenv/nextjs/config";
const : NextConfig = {};
export default ();Without ArkType, import withArkEnv from
@arkenv/nextjs/standard/config.
Replace createEnv with a flat schema
T3 Env:
import { createEnv } from "@t3-oss/env-nextjs";
import * as z from "zod";
export const env = createEnv({
server: {
DATABASE_URL: z.url(),
},
client: {
NEXT_PUBLIC_APP_URL: z.url(),
},
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
},
});ArkEnv. withArkEnv generates .arkenv/env.gen.ts. Zod and Valibot
import withArkEnv from @arkenv/nextjs/standard/config.
import from "@/.arkenv";
export const = ({
DATABASE_URL: "string.url",
NEXT_PUBLIC_APP_URL: "string.url",
});You do not copy keys into runtimeEnv. NEXT_PUBLIC_ marks client
variables.
Retarget imports
Change import { env } from "~/env" (or src/env.js) to your new
./env module.
Optional: two-module recipe
If you used two createEnv calls in T3 Env for name/type isolation,
mirror that with two ArkEnv modules and two imports — not a CLI
--strict flag. See
Client vs. server.