@arkenv/nextjs
Next.js integration framework for ArkEnv.
Next.js does not validate an env schema during next dev or
next build on its own. @arkenv/nextjs adds that check, Next-aware
arkenv() entries, and .arkenv codegen. This page is the subpath and
option list. Setup recipes live in the
Next.js guide.
Flat arkenv(schema, { exposeToClient }) is the only call shape.
Nested bags and expose / shared aliases were removed — see
Migrating to v1.
Installation
Install the adapter next to the engine you write schemas with. The
adapter does not bundle @arkenv/core or @arkenv/standard.
npm install @arkenv/core @arkenv/nextjs arktypeOr if you use Zod, Valibot, or another Standard Schema validator:
npm install @arkenv/standard @arkenv/nextjs zodSubpaths
| Subpath | Role |
|---|---|
. | Unified arkenv (react-server condition for RSC, default for client/SSR) |
./config | withArkEnv, runCodegen, config types |
./standard | Standard Schema unified entry (react-server for RSC, default for client) |
./standard/config | Standard withArkEnv (forces Standard codegen) |
withArkEnv options
import type { NextConfig } from "next";
import { withArkEnv } from "@arkenv/nextjs/config";
const nextConfig: NextConfig = {};
export default withArkEnv(nextConfig);Function-form next.config is supported. ArkEnv awaits the factory and
applies aliases to the resolved object:
import type { NextConfig } from "next";
import { withArkEnv } from "@arkenv/nextjs/config";
export default withArkEnv(async (phase, { defaultConfig }): Promise<NextConfig> => ({
...defaultConfig,
reactStrictMode: phase !== "phase-test",
}));Your app schema imports the generated factory:
import arkenv from "@/.arkenv";
export const env = arkenv({
DATABASE_URL: "string",
NEXT_PUBLIC_API_URL: "string = 'https://api.example.com'",
NODE_ENV: "'development' | 'production' | 'test' = 'development'",
});Zod and Valibot import withArkEnv from
@arkenv/nextjs/standard/config. See
Standard Schema codegen.
withArkEnv options
Pass a second argument to change codegen or validation.
| Option | Default | Meaning |
|---|---|---|
codegen | true | Write env.gen.ts |
validate | true | Validate during config/build |
schemaPath | auto | Schema entry path |
outputPath | auto | Generated file path |
logger | console | Build-time logger |
logLevel | (none) | Minimum log level |
A custom outputPath still imports as @/.arkenv. Next.js aliases the
specifier; codegen keeps .arkenv/index.ts re-exporting that file so
tsc --noEmit matches.
Skip generation during CLI scaffolds with
npx arkenv init --no-codegen.
Programmatic codegen
import { runCodegen } from "@arkenv/nextjs/config";
await runCodegen(schemaPath, outputPath);Standard Schema codegen
Import withArkEnv from @arkenv/nextjs/standard/config to force
Standard Schema-compatible generated imports.
import { withArkEnv } from "@arkenv/nextjs/standard/config";
export default withArkEnv(nextConfig);Client and server keys
Public keys use the NEXT_PUBLIC_ prefix. One schema file plus a runtime
Proxy blocks server-key reads on the client.
. and ./standard publish the same export conditions. Next.js resolves
react-server in Server Components and Route Handlers, so those imports
see every schema key. Client Components and SSR resolve default, which
exposes public keys only. Generated env.gen.ts still imports
@arkenv/nextjs or @arkenv/nextjs/standard. The bundler selects the
build from the importing context.
For name/type isolation beyond values, see the two-module recipe.