Nuxt
Learn how to use ArkEnv in a Nuxt project.
Nuxt already hydrates public config through Nitro. ArkEnv validates the schema on server and client routes, and keeps server secrets off the browser while those public keys ride runtime config.
How this host compares with Next.js, Vite, and Bun is in Frameworks.
Quickstart
arkenv init is the default on an existing Nuxt app. It registers
@arkenv/nuxt/module in your Nuxt config and writes the first schema
file.
npx arkenv initManual installation
Already ran init?
Skip this section. The CLI already registered the module and wrote the schema.
Install @arkenv/nuxt next to the engine you write schemas with, when
nuxt.config.ts is already yours and you want each package explicit in
package.json.
ArkType engine
Install @arkenv/core and its peer dependency arktype:
npm install @arkenv/core @arkenv/nuxt arktypeStandard Schema engine
If you aren't using ArkType, install @arkenv/standard with Zod or
Valibot:
npm install @arkenv/standard @arkenv/nuxt zodnpm install @arkenv/standard @arkenv/nuxt valibot @valibot/to-json-schemaModule configuration
Nuxt loads modules from nuxt.config.ts. Registering @arkenv/nuxt
there is what injects runtime config and validates variables during
development and build. Without the module, importing env only checks
the process that happens to load it.
export default defineNuxtConfig({
modules: ["@arkenv/nuxt/module"],
});Schema
One env.ts is the schema. Public keys use the NUXT_PUBLIC_ prefix
so Nitro can hydrate them on the client. Everything else stays on the
server.
Zod and Valibot both import @arkenv/nuxt/standard and register
@arkenv/nuxt/standard/module.
@arkenv/nuxt/standard binds the root @arkenv/standard engine. Zod
4.2+ coerces numbers and booleans from that entry. Valibot does not:
there is no @arkenv/nuxt/standard/valibot binding, so installing
@valibot/to-json-schema does not coerce v.number() or v.boolean()
here. Keep Valibot fields as strings on this entry, or validate them
with @arkenv/standard/valibot outside the
Nuxt module.
import from "@arkenv/nuxt";
export const = ({
DATABASE_URL: "string",
NUXT_PUBLIC_API_URL: "string = 'https://api.example.com'",
: "'development' | 'production' | 'test' = 'development'",
});Unlike Next.js, Nuxt does not emit an env.gen.ts file; @arkenv/nuxt acts as
the primary entrypoint.
If you split client and server modules for name/type isolation, never import the server module from client or Vue code. See the two-module recipe.
Read env in application code
Import { env } from "./env" in server routes and Vue components. One
module is the typed object everywhere.
Do not read process.env directly
Reading process.env skips ArkEnv. Import { env } so public keys stay
typed and coerced and server secrets stay out of the client bundle.
Standard Schema
Zod and Valibot both point the module at the standard module path.
The schema tabs above already import from @arkenv/nuxt/standard.
export default defineNuxtConfig({
modules: ["@arkenv/nuxt/standard/module"],
});Nitro boot gate and runtimeConfig hydration
Staging and production containers inject environment variables when the
process starts, not when the image is built. Vite and Bun inline
literals at build time. @arkenv/nuxt hooks into Nitro instead:
- Server boot gate: At server startup, an internal Nitro plugin runs before route handlers execute. Nuxt compiles your schema into the server bundle, then the plugin validates live environment variables against that schema and throws fail-fast errors on invalid values. A copied
.outputdirectory does not need the sourceenv.tsbeside it. - Runtime configuration hydration: An internal Nitro plugin passes validated public variables (
NUXT_PUBLIC_*) intouseRuntimeConfig().public. - Client access: Client components read public values from runtime configuration during browser rendering and hydration, avoiding hardcoded build-time literals.
You can update environment variables across deployment stages without rebuilding client JavaScript bundles. Ship one image and change env at container start for staging versus production.
Unlike Next.js env.gen.ts, @arkenv/nuxt writes no generated files to
commit or gitignore. The module validates at boot and registers public
keys on runtimeConfig.