arkenv について
ArkEnvは、JavaScriptとTypeScript向けの型安全な環境変数検証ライブラリです。複数の検証エンジンとフレームワーク連携に加え、初期設定や検査に使えるCLIを備えています。
主な機能
- 01ArkTypeとStandard Schemaによる検証
- 02自動型変換とデフォルト値
- 03Vite、Bun、Next.js、Nuxtとの連携
- 04CLIによる初期設定と環境検査
- 05クライアントとサーバーの秘密情報分離
活用シーン
- 01アプリ起動時に必要な変数の検証
- 02フロントエンドビルド時の公開変数の埋め込み
- 03クライアントからサーバー秘密情報へのアクセス防止
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ onmax/ nuxt-skills --skill arkenvインストール後、Claude Code で/arkenvを入力して読み込まれたか確認します。
詳細
ArkEnv
ArkEnv は、モダンな JavaScript および TypeScript フレームワーク向けの、型安全な環境変数バリデーションライブラリです。すべてのフレームワークで共通の単一インターフェース、import { env } from "./env" を提供します。
v1 では、ArkEnv は2つの主要なバリデーションエンジンを提供します。
@arkenv/core:高性能なスキーマ定義と自動型変換を実現する、組み込みの ArkType DSL エンジンです。@arkenv/standard:準拠するあらゆるバリデーター(Zod、Valibot など)をサポートする Standard Schema エンジンです。
機能
基本的な使い方
@arkenv/coreの ArkType DSL 文字列、または Zod/Valibot と組み合わせた@arkenv/standardを使って、型安全なスキーマを定義できます。- 自動型変換(
string.numeric、number.port、ブール値、JSON オブジェクト、配列)とデフォルト値("boolean = true")に対応します。 - フロントエンドとバックエンドのコードで
envを直接インポートできる、統一された開発者エクスペリエンスを提供します。
フレームワークとの統合
- Vite(
@arkenv/vite-plugin):プラグインは変換モードで動作し、クライアントグラフ内のenv.tsからのインポートを、インラインの公開VITE_*リテラルに書き換え、プライベートなサーバーキーを実行時に例外をスローするガードに置き換えます。 - Bun(
@arkenv/bun-plugin):プラグインはBun.build/Bun.serveでのenv.tsのインポートを横取りし、公開BUN_PUBLIC_*値をインライン化する一方、サーバーシークレットをガードします。 - Next.js(
@arkenv/nextjs):クライアントとサーバーを自動で分離するプロキシを備え、ビルド時と実行時のバリデーションに対応します。 - Nuxt(
@arkenv/nuxt):Nitro の起動時バリデーションと実行時プロキシガードを備えた Nuxt モジュールです。 - Node.js:
@arkenv/coreまたは@arkenv/standardによる、起動時の直接バリデーションに対応します。
CLI(セットアップと DevOps)
pnpm dlx arkenv init(またはnpx arkenv init)を使って、新規または既存のプロジェクトに ArkEnv を初期化します。- フレームワーク(
Next.js、Nuxt、Vite、Bunなど)を自動検出し、env.tsのひな形を作成します。 - 初期化時にホスティングプロバイダーのプリセットを選択できます(
--preset, -P <provider>)。 - 必要に応じて
tsconfig.jsonを自動設定します。CLI コマンドでのスキーマ検出には--schemaまたはフラットな規約パス(env.ts、src/env.ts)を使用します。package.jsonの"arkenv"フィールドや、env/server.tsのような分割レイアウトの古いファイル名は使用しません。
ホスティングプリセット
ArkEnv はコードファーストです。プロジェクトの初期セットアップ時にホスティングプロバイダーのプリセット(--preset vercel、netlify、cloudflare、railway、render、fly)を選択するか、ドキュメント(/docs/core-concepts/hosting-presets)にあるプロバイダーのフィールドを ./env.ts にコピーして貼り付けることができます。機械によって管理されるコメントブロックや、CLI による変更コマンドはありません。
エージェントのセットアップ(機械可読)
AI エージェントは、一貫性と信頼性を確保するため、プロジェクトの初期化には必ず CLI を使用してください。完全に自動化された機械可読の操作には、--agent フラグを使用します。
- コマンド:
pnpm dlx arkenv init --agent - 動作:
--agentフラグを指定すると、次の動作が自動的に有効になります。--yes:すべての対話形式のプロンプトをスキップし、推奨されるデフォルト値を使用します。--quiet:スピナーと ANSI 形式の出力を抑制し、ターミナルログを見やすくします。--json:完了時に構造化された JSON サマリーをstdoutに出力します(それ以外の出力はstderrに送られます)。
- 成功の確認:
stdout上の JSON セトルメントエンベロープを解析します。成功時はok: trueおよびcommandId: "init"となり、詳細(例:ひな形が作成されたパス)はresultの下にあります。
拒否の処理 (ok: false)
--agent は 決して --force を暗黙的に含みません。安全チェックに引っかかると、CLI は拒否し、エラー状態の settlement envelope を stdout に出力します:
{
"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.INTERNAL_ERRORは CLI が_拒否_したのではなく_壊れた_ことを意味します — フラグを付けて再試行しても解決しません。nextActions: 修復手順です。--forceを含むrun-commandアクションは、その拒否が回避可能であることを意味します。nextActionsが空の場合は回避できません。
エスカレーションパターン: まず必ず --force なしで init --agent を実行してください。ok: false が返った場合は、error.code と nextActions を確認します。その拒否を回避しても安全だと意図的に判断した場合にのみ、--force (または run-command アクションのコマンド) を付けて再実行してください — 先回りして --force を追加しないでください。
CLI コマンド
init
プロジェクトに ArkEnv をセットアップします。フレームワークを検出し、適切なプラグインとスキーマを構成します。
pnpm dlx arkenv init [options]
オプション:
--preset, -P <preset>: ホスティングプロバイダーのプリセットを指定します (none、vercel、netlify、cloudflare、railway、render、fly)。--no-codegen: Next.js の codegen 構成セットアップを無効にします。--force, -f: クリーンな git ワーキングツリーの安全チェックをバイパスします。
check
スキーマファイルに対して環境を検証します。
pnpm arkenv check [options]
オプション:
--schema, -s <path>: スキーマモジュールへの明示的なパス (規約による検出を上書きします)。--verify-example [file]: 宣言されたすべてのスキーマキーが.env.example(またはカスタムのサンプルファイルパス) に存在することを、ファイルを変更せずに検証します。--env-file <path>: 読み込むカスタム環境ファイルを 1 つ以上指定します。--json: 構造化された JSON 診断を stdout に出力します。
スキーマの定義と env のインポート
@arkenv/core (ArkType DSL)
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)
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-schema もインストールしてください):
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()),
});
アプリケーションコードでの env の利用
常に正規の env オブジェクトからプロパティを直接インポートして読み取ってください:
import { env } from "./env";
export default function App() {
const apiUrl = env.VITE_API_URL; // string
return <div>API URL: {apiUrl}</div>;
}
フレームワークセットアップパターン
1. Vite (@arkenv/vite-plugin)
スキーマ引数なしで vite.config.ts にプラグインを登録します:
import { defineConfig } from "vite";
import arkenvPlugin from "@arkenv/vite-plugin";
export default defineConfig({
plugins: [arkenvPlugin()],
});
vite.config.ts 自体の中で環境変数が必要な場合 (例: server.port)、loadEnv で検証します:
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)
bunfig.toml 内:
[serve.static]
plugins = ["@arkenv/bun-plugin"]
Bun.build 内:
import arkenvPlugin from "@arkenv/bun-plugin";
await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./dist",
plugins: [arkenvPlugin],
});
セキュリティ境界とレイアウト
- フラットレイアウト (デフォルト):
src/env.tsにすべてのキーが含まれます。サーバーグラフは起動時に完全な検証を実行します。クライアントグラフはインライン化されたパブリックリテラルを受け取りますが、プライベートなサーバーキーへのアクセスは実行時エラーをスローします。 - オプションの 2 モジュールレシピ: シークレットの名前や型をクライアントの型グラフに残してはならない場合、2 つのモジュール (クライアント + サーバー) を 2 つのインポートとオプションの
extends: [clientEnv]で使用します。Next ではサーバーモジュールにimport "server-only"+@arkenv/coreを使用できます。Nuxt: クライアントコードからサーバーモジュールを決してインポートしないでください。CLI の--strictフラグやパッケージの/client/serverサーフェスではありません。
ベストプラクティスとルール
- 常に
import { env } from "./env"を使用する: v1 では、アプリケーションの環境変数にimport.meta.envやprocess.envを直接使用しないでください。 - アンビエントな
.d.ts拡張を決して作成しない:ImportMetaEnvAugmentedとProcessEnvAugmentedは v1 で削除されたレガシーな v0 パターンです。 - シークレットはサーバーに置く: サーバーシークレット (
DATABASE_URL、API_SECRET_KEY) にクライアントプレフィックス (VITE_、NEXT_PUBLIC_、BUN_PUBLIC_、NUXT_PUBLIC_) を決して付けないでください。