arkenv について
ArkEnvは、JavaScriptとTypeScript向けの環境変数検証ライブラリです。複数のスキーマエンジン、フレームワーク別の分離機能、プロジェクト設定や検証を行うCLIを備えています。
主な機能
- 01型安全な環境変数スキーマ
- 02ArkTypeとStandard Schemaに対応
- 03自動変換とデフォルト値
- 04Vite、Bun、Next.js、Nuxtに対応
- 05CLIによる設定と検証
活用シーン
- 01アプリ起動時の環境変数検証
- 02クライアントコードからの秘密情報保護
- 03フレームワーク用設定の生成
- 04スキーマに基づく環境ファイル検査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yamcodes/ arkenv --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 settlement envelope を解析します。成功時は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が空の場合は回避できません。従来のretryWithフィールドよりも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 のコード生成設定を無効にします。--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 arkenv from "@arkenv/vite-plugin";
export default defineConfig({
plugins: [arkenv()],
});
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 arkenv from "@arkenv/bun-plugin";
await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./dist",
plugins: [arkenv()],
});
セキュリティ境界とレイアウト
- フラットレイアウト(デフォルト):
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_)を付けないでください。