dotenv の使い方 — Node.js で環境変数を .env ファイルから読み込む
一言でいうと
dotenv は、.env ファイルに定義した環境変数を process.env に読み込む、依存ゼロの軽量モジュールです。The Twelve-Factor App の方法論に基づき、設定をコードから分離するために広く使われています。
どんな時に使う?
- ローカル開発でAPIキーやDB接続文字列を管理したい —
.envファイルにまとめ、コードにハードコードせずに済む - 環境ごとに設定を切り替えたい — 開発・ステージング・本番で異なる値を
.envファイルで管理 - チーム開発でシークレット情報を安全に扱いたい —
.envを.gitignoreに追加し、.env.exampleだけをリポジトリに含める運用
インストール
# npm
npm install dotenv
# yarn
yarn add dotenv
# pnpm
pnpm add dotenv
基本的な使い方
プロジェクトルートに .env ファイルを作成します。
# .env
DATABASE_URL="postgres://user:password@localhost:5432/mydb"
API_KEY="your-api-key-here"
PORT=3000
アプリケーションのエントリポイントで、できるだけ早い段階で読み込みます。
// src/index.ts
// 方法1: import するだけ(設定不要な場合はこれが最もシンプル)
import 'dotenv/config';
// 方法2: 細かいオプションを指定したい場合
import dotenv from 'dotenv';
dotenv.config({ path: '.env' });
// 読み込まれた環境変数を使用
const port = process.env.PORT ?? '3000';
const dbUrl = process.env.DATABASE_URL;
console.log(`Server starting on port ${port}`);
console.log(`Database: ${dbUrl}`);
$ npx ts-node src/index.ts
◇ injected env (3) from .env
Server starting on port 3000
Database: postgres://user:password@localhost:5432/mydb
これだけで .env の内容が process.env に反映されます。
よく使う API
1. dotenv.config() — 基本の読み込み
最も頻繁に使うメソッドです。.env ファイルを読み込み、process.env にセットします。
import dotenv from 'dotenv';
const result = dotenv.config();
if (result.error) {
console.error('Failed to load .env file:', result.error);
process.exit(1);
}
// result.parsed には読み込まれたキーと値のオブジェクトが入る
console.log(result.parsed);
// { DATABASE_URL: 'postgres://...', API_KEY: 'your-api-key-here', PORT: '3000' }
2. config({ path }) — カスタムパスの指定
デフォルトではプロセスのカレントディレクトリの .env を読みますが、パスを変更できます。
import dotenv from 'dotenv';
import path from 'path';
// 単一ファイル
dotenv.config({ path: path.resolve(__dirname, '../.env.local') });
// 複数ファイルを配列で指定(先に指定したファイルが優先)
dotenv.config({
path: [
path.resolve(__dirname, '../.env.local'),
path.resolve(__dirname, '../.env'),
],
});
3. config({ override }) — 既存の環境変数を上書き
デフォルトでは、すでに process.env に存在する変数は上書きしません。override: true で強制上書きできます。
import dotenv from 'dotenv';
// すでに process.env.PORT が設定されていても .env の値で上書きする
dotenv.config({ override: true });
4. dotenv.parse() — 文字列/Bufferのパース
process.env にセットせず、.env 形式の文字列をオブジェクトとしてパースするだけの用途に使えます。
import dotenv from 'dotenv';
import fs from 'fs';
const envContent = fs.readFileSync('.env.production', 'utf-8');
const parsed = dotenv.parse(envContent);
console.log(parsed);
// { DATABASE_URL: 'postgres://...', SECRET_KEY: '...' }
// process.env には影響しない
5. dotenv.populate() — 任意のオブジェクトに環境変数をセット
process.env 以外のオブジェクトに値をセットしたい場合に使います。
import dotenv from 'dotenv';
const myEnv: Record<string, string> = {};
const parsed = { DB_HOST: 'localhost', DB_PORT: '5432' };
dotenv.populate(myEnv, parsed);
console.log(myEnv);
// { DB_HOST: 'localhost', DB_PORT: '5432' }
補足: プリロード(コード変更不要)
-r フラグを使えば、アプリケーションコードに dotenv の import を書かずに済みます。
# JavaScript
node -r dotenv/config dist/index.js
# オプション付き
node -r dotenv/config dist/index.js dotenv_config_path=.env.production dotenv_config_debug=true
類似パッケージとの比較
| 特徴 | dotenv | dotenvx | env-cmd | cross-env |
|---|---|---|---|---|
.env ファイル読み込み | ✅ | ✅ | ✅ | ❌ |
| 依存パッケージ数 | 0 | 少数 | 少数 | 少数 |
変数展開 (${VAR}) | ❌(別途 dotenvx が必要) | ✅ | ❌ | ❌ |
| 暗号化 | ❌ | ✅ | ❌ | ❌ |
| 複数環境の管理 | 手動で対応 | ✅(-f フラグ) | ✅ | ❌ |
| コマンド置換 | ❌ | ✅ | ❌ | ❌ |
| 言語非依存 | ❌(Node.js専用) | ✅(任意の言語) | ❌ | ❌ |
| 用途 | .env の基本読み込み | dotenv の上位互換 | コマンド経由で env 注入 | クロスプラットフォームで env セット |
補足: dotenv の作者自身が、より高機能な dotenvx への移行を推奨しています。変数展開・暗号化・複数環境管理が必要な場合は dotenvx を検討してください。
注意点・Tips
1. .env は必ず .gitignore に追加する
# .gitignore
.env
.env.local
.env.production
.env*.local
代わりに .env.example をリポジトリに含め、必要なキーの一覧を共有しましょう。
# .env.example
DATABASE_URL=
API_KEY=
PORT=3000
2. process.env の値はすべて string | undefined
// ❌ 型が合わない
const port: number = process.env.PORT; // Type 'string | undefined' is not assignable to type 'number'
// ✅ 明示的に変換する
const port: number = parseInt(process.env.PORT ?? '3000', 10);
const debug: boolean = process.env.DEBUG === 'true';
型安全に環境変数を扱いたい場合は、zod などでバリデーションスキーマを定義するのがベストプラクティスです。
import { z } from 'zod';
import 'dotenv/config';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
API_KEY: z.string().min(1),
PORT: z.coerce.number().default(3000),
});
export const env = envSchema.parse(process.env);
// env.PORT は number 型として安全に使える
3. 既存の環境変数は上書きされない(デフォルト)
CI/CD やコンテナ環境で設定済みの環境変数がある場合、.env の値では上書きされません。これは意図的な設計です。上書きしたい場合は override: true を指定してください。
4. 値に # を含む場合はクォートが必須
# ❌ # 以降がコメントとして扱われる
SECRET=abc#123
# ✅ ダブルクォートで囲む
SECRET="abc#123"
これは v15.0.0 以降の破壊的変更です。
5. 複数行の値はダブルクォートで囲む
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"
v15.0.0 以降で対応しています。
6. モノレポでの配置場所
.env ファイルは、node プロセスを実行するディレクトリ(process.cwd())に配置します。
my-monorepo/
├── apps/
│ ├── backend/
│ │ ├── .env ← backend の .env はここ
│ │ └── src/index.ts
│ └── frontend/
│ ├── .env ← frontend の .env はここ
│ └── src/main.ts
└── package.json
まとめ
dotenv は、.env ファイルから環境変数を process.env に読み込むための、シンプルかつ実績のあるパッケージです。依存ゼロで導入コストが極めて低く、Node.js プロジェクトにおける環境変数管理のデファクトスタンダードとなっています。変数展開や暗号化といった高度な機能が必要になった場合は、同作者の dotenvx への移行を検討するとよいでしょう。