arkenv
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArkEnv
ArkEnv
ArkEnv is a typesafe environment variable validation library for modern JavaScript and TypeScript frameworks. It provides a single canonical surface across all frameworks: .
import { env } from "./env"In v1, ArkEnv offers two first-class validation engines:
- : Built-in ArkType DSL engine for high-performance schema definition and automatic coercion.
@arkenv/core - : Standard Schema engine supporting any compliant validator (Zod, Valibot, etc.).
@arkenv/standard
ArkEnv 是面向现代 JavaScript 和 TypeScript 框架的类型安全环境变量校验库。它提供 跨所有框架的统一规范入口:。
import { env } from "./env"在 v1 中,ArkEnv 提供两个一等验证引擎:
- :内置 ArkType DSL 引擎,用于高性能 Schema 定义和自动类型转换。
@arkenv/core - :Standard Schema 引擎,支持任何符合规范的验证器(Zod、Valibot 等)。
@arkenv/standard
Capabilities
功能
Core usage
核心用法
- Define typesafe schemas using ArkType DSL strings or
@arkenv/corewith Zod / Valibot.@arkenv/standard - Automatic coercion (,
string.numeric, booleans, JSON objects, arrays) and default values (number.port)."boolean = true" - Single, uniform developer experience: import directly across frontend and backend code.
env
- 使用 的 ArkType DSL 字符串,或使用
@arkenv/core配合 Zod / Valibot 定义类型安全的 Schema。@arkenv/standard - 自动类型转换(、
string.numeric、布尔值、JSON 对象、数组)和默认值(number.port)。"boolean = true" - 统一一致的开发体验:在前端和后端代码中直接导入 。
env
Framework integration
框架集成
- Vite (): Plugin operates in transform mode, rewriting imports from
@arkenv/vite-pluginin the client graph to inline publicenv.tsliterals and replacing private server keys with throwing runtime guards.VITE_* - Bun (): Plugin intercepts
@arkenv/bun-pluginimports inenv.ts/Bun.buildto inline publicBun.servevalues while guarding server secrets.BUN_PUBLIC_* - Next.js (): Build-time and runtime validation with automatic client/server isolation proxy.
@arkenv/nextjs - Nuxt (): Nuxt module with Nitro boot validation and runtime proxy guard.
@arkenv/nuxt - Node.js: Direct boot-time validation via or
@arkenv/core.@arkenv/standard
- Vite():插件以 transform 模式运行,将客户端图(client graph)中来自
@arkenv/vite-plugin的导入重写为内联的公共env.ts字面量,并将私有服务端密钥替换为访问时抛出错误的运行时守卫。VITE_* - Bun():插件拦截
@arkenv/bun-plugin/Bun.build中的Bun.serve导入,内联公共env.ts值,同时守卫服务端密钥。BUN_PUBLIC_* - Next.js():提供构建时和运行时验证,并自动创建客户端/服务端隔离代理。
@arkenv/nextjs - Nuxt():Nuxt 模块支持 Nitro 启动验证和运行时代理守卫。
@arkenv/nuxt - Node.js:通过 或
@arkenv/core直接在启动时进行验证。@arkenv/standard
CLI (setup & DevOps)
CLI(设置与 DevOps)
- Initialize ArkEnv in new or existing projects using (or
pnpm dlx arkenv init).npx arkenv init - Automatically detect frameworks (,
Next.js,Nuxt,Vite, etc.) and scaffoldBun.env.ts - Select hosting provider preset during init ().
--preset, -P <provider> - Automatically configure when needed. Schema discovery for CLI commands uses
tsconfig.jsonor flat convention paths (--schema,env.ts) — not asrc/env.tspackage.jsonfield, and not leftover split-layout filenames such as"arkenv".env/server.ts
- 使用 (或
pnpm dlx arkenv init)在新建或现有项目中初始化 ArkEnv。npx arkenv init - 自动检测框架(、
Next.js、Nuxt、Vite等)并生成Bun脚手架。env.ts - 初始化期间选择托管提供商预设()。
--preset, -P <provider> - 根据需要自动配置 。CLI 命令的 Schema 发现机制使用
tsconfig.json或扁平约定路径(--schema、env.ts),而不是src/env.ts中的package.json字段,也不使用"arkenv"等旧版拆分布局文件名。env/server.ts
Hosting presets
托管提供商预设
ArkEnv is code-first. You can select a hosting provider preset during initial project setup (, , , , , ) or copy-paste provider fields directly into from the documentation (). There are no machine-managed comment blocks or CLI mutation commands.
--preset vercelnetlifycloudflarerailwayrenderfly./env.ts/docs/core-concepts/hosting-presetsArkEnv 采用 code-first 模式。你可以在初始项目设置期间选择托管提供商预设(、、、、、),也可以从文档()中直接复制提供商字段到 。不存在由机器管理的注释块或 CLI 变更命令。
--preset vercelnetlifycloudflarerailwayrenderfly/docs/core-concepts/hosting-presets./env.tsAgent setup (machine-readable)
Agent 设置(机器可读)
AI agents SHOULD always use the CLI for project initialization to ensure consistency and reliability. Use the flag for a fully automated, machine-readable experience.
--agent- Command:
pnpm dlx arkenv init --agent - Behavior: The flag automatically enables the following behaviors:
--agent- : Bypasses all interactive prompts and uses recommended defaults.
--yes - : Suppresses spinners and ANSI formatting for cleaner terminal logs.
--quiet - : Emits a structured JSON summary to
--jsonupon completion (all other output is sent tostdout).stderr
- Success Verification: Parse the JSON settlement envelope on . Success is
stdoutwithok: true; details (e.g. scaffolded paths) live undercommandId: "init".result
AI Agent 应始终使用 CLI 初始化项目,以确保一致性和可靠性。使用 标志可获得全自动、机器可读的体验。
--agent- 命令:
pnpm dlx arkenv init --agent - 行为:标志会自动启用以下行为:
--agent- :跳过所有交互式提示,并使用推荐默认值。
--yes - :抑制 spinner 和 ANSI 格式化,使终端日志更加简洁。
--quiet - :完成后向
--json输出结构化 JSON 摘要(所有其他输出发送到stdout)。stderr
- 成功验证:解析 上的 JSON settlement envelope。成功时为
stdout且ok: true;详细信息(例如已生成的路径)位于commandId: "init"中。result
Handling refusals (ok: false
)
ok: false处理拒绝(ok: false
)
ok: false--agent--forcestdoutjson
{
"ok": false,
"commandId": "init",
"error": {
"code": "CLI.GIT_TREE_DIRTY",
"severity": "error",
"summary": "Git working tree is not clean.",
"why": "Commit or stash your changes before running arkenv init.",
"nextActions": [
{
"kind": "run-command",
"label": "Re-run with --force to bypass git working tree check",
"command": "arkenv init --force"
}
]
},
"diagnostics": [],
"nextActions": [
{
"kind": "run-command",
"label": "Re-run with --force to bypass git working tree check",
"command": "arkenv init --force"
}
]
}- : a stable dotted identifier you can branch on (
error.code,CLI.REQUIREMENTS_NOT_MET,CLI.GIT_TREE_DIRTY, …).CLI.NON_EMPTY_DIRmeans the CLI broke rather than refused — retrying with flags will not help.CLI.INTERNAL_ERROR - : remediation steps. A
nextActionsaction that includesrun-commandmeans the refusal is bypassable; empty--forcemeans it is not.nextActions
Escalation pattern: always run without first. If you get , inspect and . Only re-run with (or the command from a action) once you have deliberately decided the refusal is safe to bypass — do not add pre-emptively.
init --agent--forceok: falseerror.codenextActions--forcerun-command--force--agent--forcestdoutjson
{
"ok": false,
"commandId": "init",
"error": {
"code": "CLI.GIT_TREE_DIRTY",
"severity": "error",
"summary": "Git working tree is not clean.",
"why": "Commit or stash your changes before running arkenv init.",
"nextActions": [
{
"kind": "run-command",
"label": "Re-run with --force to bypass git working tree check",
"command": "arkenv init --force"
}
]
},
"diagnostics": [],
"nextActions": [
{
"kind": "run-command",
"label": "Re-run with --force to bypass git working tree check",
"command": "arkenv init --force"
}
]
}- :可用于分支判断的稳定点分标识符(
error.code、CLI.REQUIREMENTS_NOT_MET、CLI.GIT_TREE_DIRTY等)。CLI.NON_EMPTY_DIR表示 CLI 本身发生故障,而不是主动拒绝执行——重新尝试并添加标志不会有帮助。CLI.INTERNAL_ERROR - :补救步骤。包含
nextActions的--force操作表示可以绕过此次拒绝;run-command为空则表示无法绕过。nextActions
升级处理模式:始终先运行 ,不要预先添加 。如果返回 ,请检查 和 。只有在明确判断绕过拒绝是安全操作后,才使用 或 操作中的命令重新运行。
init --agent--forceok: falseerror.codenextActions--forcerun-commandCLI commands
CLI 命令
init
initinit
initSet up ArkEnv in your project. It detects your framework and configures the appropriate plugin and schema.
bash
pnpm dlx arkenv init [options]在项目中设置 ArkEnv。CLI 会检测框架并配置相应的插件和 Schema。
bash
pnpm dlx arkenv init [options]Options:
选项:
- : Specify hosting provider preset (none, vercel, netlify, cloudflare, railway, render, fly).
--preset, -P <preset> - : Disable Next.js codegen configuration setup.
--no-codegen - : Bypass clean git working tree safety check.
--force, -f
- :指定托管提供商预设(none、vercel、netlify、cloudflare、railway、render、fly)。
--preset, -P <preset> - :禁用 Next.js codegen 配置设置。
--no-codegen - :绕过 Git 工作树必须保持干净的 safety check。
--force, -f
check
checkcheck
checkValidate the environment against your schema file.
bash
pnpm arkenv check [options]根据 Schema 文件验证环境变量。
bash
pnpm arkenv check [options]Options:
选项:
- : Explicit path to the schema module (overrides convention discovery).
--schema, -s <path> - : Verify that all declared schema keys are present in
--verify-example [file](or a custom example file path) without mutating files..env.example - : Specify one or more custom environment files to load.
--env-file <path> - : Output structured JSON diagnostics to stdout.
--json
- :显式指定 Schema 模块路径(覆盖约定发现机制)。
--schema, -s <path> - :验证所有已声明的 Schema 键是否都存在于
--verify-example [file]或自定义示例文件路径中,且不会修改文件。.env.example - :指定一个或多个要加载的自定义环境变量文件。
--env-file <path> - :向 stdout 输出结构化 JSON 诊断信息。
--json
Defining Schemas & Importing env
env定义 Schema 与导入 env
env@arkenv/core
(ArkType DSL)
@arkenv/core@arkenv/core
(ArkType DSL)
@arkenv/corets
import arkenv from "@arkenv/core";
export const env = arkenv({
PORT: "number.port = 3000",
DATABASE_URL: "string",
VITE_API_URL: "string",
NODE_ENV: "'development' | 'production' | 'test' = 'development'",
});ts
import arkenv from "@arkenv/core";
export const env = arkenv({
PORT: "number.port = 3000",
DATABASE_URL: "string",
VITE_API_URL: "string",
NODE_ENV: "'development' | 'production' | 'test' = 'development'",
});@arkenv/standard
(Standard Schema: Zod, Valibot)
@arkenv/standard@arkenv/standard
(Standard Schema:Zod、Valibot)
@arkenv/standardts
import arkenv from "@arkenv/standard";
import * as z from "zod";
export const env = arkenv({
PORT: z.number().default(3000),
DATABASE_URL: z.string(),
VITE_API_URL: z.url(),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
});Valibot uses the subpath (install as well):
/valibot@valibot/to-json-schemats
import { arkenv } from "@arkenv/standard/valibot";
import * as v from "valibot";
export const env = arkenv({
PORT: v.optional(v.number(), 3000),
DATABASE_URL: v.pipe(v.string(), v.url()),
});ts
import arkenv from "@arkenv/standard";
import * as z from "zod";
export const env = arkenv({
PORT: z.number().default(3000),
DATABASE_URL: z.string(),
VITE_API_URL: z.url(),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
});Valibot 使用 子路径(还需安装 ):
/valibot@valibot/to-json-schemats
import { arkenv } from "@arkenv/standard/valibot";
import * as v from "valibot";
export const env = arkenv({
PORT: v.optional(v.number(), 3000),
DATABASE_URL: v.pipe(v.string(), v.url()),
});Consuming env
in Application Code
env在应用代码中使用 env
envAlways import and read properties directly from the canonical object:
envtsx
import { env } from "./env";
export default function App() {
const apiUrl = env.VITE_API_URL; // string
return <div>API URL: {apiUrl}</div>;
}始终直接从规范 对象导入并读取属性:
envtsx
import { env } from "./env";
export default function App() {
const apiUrl = env.VITE_API_URL; // string
return <div>API URL: {apiUrl}</div>;
}Framework Setup Patterns
框架设置模式
1. Vite (@arkenv/vite-plugin
)
@arkenv/vite-plugin1. Vite(@arkenv/vite-plugin
)
@arkenv/vite-pluginRegister the plugin in without schema arguments:
vite.config.tsts
import { defineConfig } from "vite";
import arkenvPlugin from "@arkenv/vite-plugin";
export default defineConfig({
plugins: [arkenvPlugin()],
});If you need environment variables inside itself (e.g. ), validate them with :
vite.config.tsserver.portloadEnvts
import { defineConfig, loadEnv } from "vite";
import arkenvPlugin from "@arkenv/vite-plugin";
import arkenv, { type } from "@arkenv/core";
export const Env = type({
PORT: "number.port = 5173",
VITE_API_URL: "string",
});
export default defineConfig(({ mode }) => {
const env = arkenv(Env, { env: loadEnv(mode, process.cwd(), "") });
return {
plugins: [arkenvPlugin()],
server: { port: env.PORT },
};
});在 中注册插件,无需传入 Schema 参数:
vite.config.tsts
import { defineConfig } from "vite";
import arkenvPlugin from "@arkenv/vite-plugin";
export default defineConfig({
plugins: [arkenvPlugin()],
});如果需要在 内部使用环境变量(例如 ),请使用 对其进行验证:
vite.config.tsserver.portloadEnvts
import { defineConfig, loadEnv } from "vite";
import arkenvPlugin from "@arkenv/vite-plugin";
import arkenv, { type } from "@arkenv/core";
export const Env = type({
PORT: "number.port = 5173",
VITE_API_URL: "string",
});
export default defineConfig(({ mode }) => {
const env = arkenv(Env, { env: loadEnv(mode, process.cwd(), "") });
return {
plugins: [arkenvPlugin()],
server: { port: env.PORT },
};
});2. Bun (@arkenv/bun-plugin
)
@arkenv/bun-plugin2. Bun(@arkenv/bun-plugin
)
@arkenv/bun-pluginIn :
bunfig.tomltoml
[serve.static]
plugins = ["@arkenv/bun-plugin"]In :
Bun.buildts
import arkenvPlugin from "@arkenv/bun-plugin";
await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./dist",
plugins: [arkenvPlugin],
});在 中:
bunfig.tomltoml
[serve.static]
plugins = ["@arkenv/bun-plugin"]在 中:
Bun.buildts
import arkenvPlugin from "@arkenv/bun-plugin";
await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./dist",
plugins: [arkenvPlugin],
});Security Boundaries & Layouts
安全边界与布局
- Flat layout (default): contains all keys. Server graph runs full validation at boot; client graph receives inlined public literals while access to private server keys throws a runtime error.
src/env.ts - Optional two-module recipe: When secret names/types must stay off the client type graph, use two modules (client + server) with two imports and optional . Next can use
extends: [clientEnv]+import "server-only"for the server module. Nuxt: never import the server module from client code. Not a CLI@arkenv/coreflag or package--strict/clientsurface./server
- 扁平布局(默认):包含所有键。服务端图会在启动时执行完整验证;客户端图会获得内联的公共字面量,而访问私有服务端密钥时将抛出运行时错误。
src/env.ts - 可选的双模块方案:当必须避免秘密名称或类型出现在客户端类型图中时,使用两个模块(客户端 + 服务端)、两次导入以及可选的 。Next 可以在服务端模块中使用
extends: [clientEnv]+import "server-only"。Nuxt:绝不要从客户端代码导入服务端模块。这不是 CLI@arkenv/core标志,也不是包的--strict、/client导出接口。/server
Best Practices & Rules
最佳实践与规则
- Always use : Never use
import { env } from "./env"orimport.meta.envdirectly for application environment variables in v1.process.env - Never create ambient augmentations:
.d.tsandImportMetaEnvAugmentedare legacy v0 patterns dropped in v1.ProcessEnvAugmented - Keep secrets on the server: Never prefix server secrets (,
DATABASE_URL) with client prefixes (API_SECRET_KEY,VITE_,NEXT_PUBLIC_,BUN_PUBLIC_).NUXT_PUBLIC_
- 始终使用 :在 v1 中,绝不要直接使用
import { env } from "./env"或import.meta.env获取应用环境变量。process.env - 绝不创建 ambient 增强声明:
.d.ts和ImportMetaEnvAugmented是已在 v1 中移除的旧版 v0 模式。ProcessEnvAugmented - 将密钥保留在服务端:绝不要使用客户端前缀(、
VITE_、NEXT_PUBLIC_、BUN_PUBLIC_)标记服务端密钥(NUXT_PUBLIC_、DATABASE_URL)。API_SECRET_KEY