Make .env secure again. Commit to GitHub without fear.
secenv encrypts your environment variables so you can safely commit them to version control. It's .env you can actually share—without the security headaches.
- Zero wrapper needed — Import and use secrets directly in your code
- Lightning fast — Cold start <50ms, cached access <1ms
- Battle-tested encryption — AEAD encryption via age
- CI/CD ready — Works seamlessly with GitHub Actions and other pipelines
- Defense-first — Private fields prevent memory-scanning attacks
# Install
npm install secenv
# Initialize (one-time setup)
npx secenv init
# Add a secret
npx secenv set API_KEY "your-secret-key"
# Use in code
import { env } from 'secenv';
const apiKey = await env.API_KEY;secenv init # Initialize identity and project
secenv set KEY VALUE # Set a secret (encrypted)
secenv get KEY # Get a secret (decrypted)
secenv list # List all keys
secenv rotate KEY # Rotate a secret
secenv delete KEY # Delete a secret
secenv doctor # Verify setup and encryption
secenv key export # Export private key for CIimport { env } from 'secenv';
const dbUrl = await env.DATABASE_URL;
const apiKey = await env.API_KEY;The SDK checks process.env first, then falls back to your .secenv file:
// In production, set DATABASE_URL in your deployment platform
// Locally, use .secenv
const dbUrl = await env.DATABASE_URL;import { env, SecretNotFoundError } from 'secenv';
try {
const key = await env.MISSING_KEY;
} catch (e) {
if (e instanceof SecretNotFoundError) {
console.error('Secret not found in .secenv');
}
}import { createSecenv } from 'secenv';
const sdk = await createSecenv();
await sdk.set('API_KEY', 'secret-value');
const value = await sdk.get('API_KEY');Store secrets in .secenv in your project root:
# Encrypted values (auto-decrypted)
API_KEY=enc:age:AGE-SECRET-KEY-1XYZ...
# Plaintext values (non-sensitive config)
PORT=3000
NODE_ENV=developmentUse --base64 flag for binary values like certificates:
secenv set TLS_CERT --base64 < server.crtsecenv key exportAdd the output as SECENV_ENCODED_IDENTITY in your CI provider (GitHub Secrets, etc.).
# GitHub Actions example
- name: Run app
env:
SECENV_ENCODED_IDENTITY: ${{ secrets.SECENV_ENCODED_IDENTITY }}
run: npm run start- AEAD encryption — Each secret is encrypted separately with age
- Private fields — JavaScript private class fields protect against memory-scanning
- Constant-time lookups — Prevents timing attacks
- Symlink protection — Blocks symlink attacks
For full security details, see SECURITY.md.
- Node.js 18+
- No external dependencies (age encryption bundled)
MIT