Claude-skill-registry bknd-env-config
Use when configuring environment variables for Bknd projects. Covers .env files, secrets management, env injection in config, platform-specific variables, and production security.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/bknd-env-config" ~/.claude/skills/majiayu000-claude-skill-registry-bknd-env-config && rm -rf "$T"
skills/data/bknd-env-config/SKILL.mdEnvironment Variables Configuration
Configure environment variables for Bknd applications across development and production.
Prerequisites
- Bknd project initialized (
exists)bknd.config.ts - Understanding of your deployment target (local, Cloudflare, Vercel, etc.)
When to Use UI Mode
- Viewing current config via admin panel
- N/A for environment variables - all done via code/files
When to Use Code Mode
- Creating
files.env - Configuring secrets in
bknd.config.ts - Setting up platform-specific env vars
- All environment configuration tasks
Code Approach
Step 1: Create .env File
Create
.env in project root:
# Database DB_URL=file:data.db DB_TOKEN= # Auth JWT_SECRET=your-secret-here-min-32-chars # Server PORT=3000 # Development LOCAL=true
Step 2: Inject Env in Config
Access env vars via the
env parameter in bknd.config.ts:
import type { CliBkndConfig } from "bknd"; export default { app: (env) => ({ connection: { url: env.DB_URL ?? "file:data.db", authToken: env.DB_TOKEN, }, auth: { jwt: { secret: env.JWT_SECRET ?? "dev-secret-change-in-prod", }, }, }), } satisfies CliBkndConfig;
The
env parameter receives all environment variables loaded from .env files and system environment.
Step 3: Use .dev.vars for Dev Overrides (Optional)
Bknd loads env files in order (later takes precedence):
- Base configuration.env
- Development-specific overrides (Cloudflare style).dev.vars
Create
.dev.vars for local dev overrides:
# .dev.vars - Dev-only, overrides .env DB_URL=:memory: JWT_SECRET=dev-only-secret
Common Environment Variables
Database
| Variable | Description | Example |
|---|---|---|
| Database connection URL | , |
| LibSQL/Turso auth token | |
Authentication
| Variable | Description | Example |
|---|---|---|
| JWT signing secret (min 32 chars) | |
| Google OAuth client ID | |
| Google OAuth secret | |
| GitHub OAuth client ID | |
| GitHub OAuth secret | |
Media/Storage
| Variable | Description | Example |
|---|---|---|
| S3/R2 access key | |
| S3/R2 secret key | |
| S3-compatible endpoint | |
| Cloudinary cloud name | |
| Cloudinary API key | |
| Cloudinary API secret | |
Server
| Variable | Description | Default |
|---|---|---|
| Server port | |
| Disable telemetry | - |
/ | Environment mode | |
Complete Configuration Example
import type { CliBkndConfig } from "bknd"; import { em, entity, text } from "bknd"; const schema = em({ posts: entity("posts", { title: text().required() }), }); export default { app: (env) => ({ // Database connection: { url: env.DB_URL ?? "file:data.db", authToken: env.DB_TOKEN, }, // Production flag isProduction: env.NODE_ENV === "production", // Pass all secrets to app secrets: env, }), config: { data: schema.toJSON(), // Auth with env-based secrets auth: { enabled: true, jwt: { secret: env.JWT_SECRET, issuer: "my-app", }, strategies: { password: { enabled: true }, google: env.GOOGLE_CLIENT_ID ? { config: { name: "google", type: "oidc", client: { client_id: env.GOOGLE_CLIENT_ID, client_secret: env.GOOGLE_CLIENT_SECRET, }, }, } : undefined, }, }, // Media with env-based adapter config media: { enabled: true, adapter: { type: "s3", config: { access_key: env.S3_ACCESS_KEY, secret_access_key: env.S3_SECRET_KEY, url: env.S3_ENDPOINT, }, }, }, }, } satisfies CliBkndConfig;
Platform-Specific Configuration
Cloudflare Workers/Pages
Use
wrangler.toml for non-secret vars and dashboard for secrets:
# wrangler.toml [vars] ENVIRONMENT = "production"
Set secrets via CLI:
npx wrangler secret put JWT_SECRET npx wrangler secret put DB_TOKEN
Access in config:
import type { CloudflareBkndConfig } from "bknd/adapter/cloudflare"; export default { app: (env) => ({ connection: env.DB, // D1 binding isProduction: env.ENVIRONMENT === "production", secrets: env, }), } satisfies CloudflareBkndConfig;
Vercel
Use Vercel dashboard or CLI for env vars:
vercel env add JWT_SECRET production vercel env add DB_URL production
Or
.env.local for local development (auto-loaded by Next.js):
# .env.local DB_URL=file:data.db JWT_SECRET=dev-secret
Docker
Pass via docker-compose or
-e flag:
# docker-compose.yml services: app: environment: - DB_URL=file:/data/app.db - JWT_SECRET=${JWT_SECRET} env_file: - .env.production
Generate .env Template
Use CLI to generate env template from your config:
# Output required secrets as template npx bknd secrets --template --format env # Save to file npx bknd secrets --template --format env --out .env.example
This creates a template without actual values, safe for version control.
SyncSecrets Option
Auto-generate
.env.example on config changes:
export default { syncSecrets: { enabled: true, outFile: ".env.example", format: "env", // or "json" }, app: (env) => ({ ... }), } satisfies CliBkndConfig;
Environment-Based Feature Flags
Conditionally enable features based on environment:
export default { app: (env) => ({ connection: { url: env.DB_URL ?? "file:data.db" }, }), config: { auth: { enabled: true, // Only enable OAuth in production (requires secrets) strategies: { password: { enabled: true }, google: env.GOOGLE_CLIENT_ID ? { config: { name: "google", type: "oidc", client: { client_id: env.GOOGLE_CLIENT_ID, client_secret: env.GOOGLE_CLIENT_SECRET, }, }, } : undefined, }, }, // Only enable S3 media in production media: env.S3_ACCESS_KEY ? { enabled: true, adapter: { type: "s3", config: { access_key: env.S3_ACCESS_KEY, secret_access_key: env.S3_SECRET_KEY, url: env.S3_ENDPOINT, }, }, } : { enabled: false, }, }, } satisfies CliBkndConfig;
Database Connection Priority
Bknd resolves database connection in order:
CLI argument--db-url- Config file
connection.url
flag (uses--memory
):memory:
environment variableDB_URL- Fallback:
file:data.db
Verification
Check env loading:
# Server logs show connection source npx bknd run # Look for: "Using connection from ..."
Test env injection:
// Temporarily log env in config app: (env) => { console.log("Loaded env:", Object.keys(env)); return { ... }; },
Verify secrets command:
npx bknd secrets --template
Common Pitfalls
.env Not Loading
Problem: Env vars undefined in config
Fix: Check file location and format:
# .env must be in project root (same level as bknd.config.ts) ls -la .env # No quotes around values DB_URL=file:data.db # Correct DB_URL="file:data.db" # May cause issues
JWT_SECRET Too Short
Problem: Auth fails or warning about weak secret
Fix: Use minimum 32 characters:
# Generate secure secret node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" # or openssl rand -hex 32
Secrets in Version Control
Problem: Committed
.env with real secrets
Fix:
# Add to .gitignore echo ".env" >> .gitignore echo ".env.local" >> .gitignore echo ".dev.vars" >> .gitignore # Remove from git history if committed git rm --cached .env
Platform Env Not Available
Problem:
env.VAR is undefined in deployed app
Fix: Platform-specific setup:
- Vercel: Add via dashboard or
vercel env add - Cloudflare: Add via
or dashboardwrangler secret put - Docker: Check
orenvironment:
in composeenv_file:
Wrong Fallback in Production
Problem: Using dev defaults in production
Fix: Fail fast instead of fallback:
app: (env) => { if (!env.JWT_SECRET && env.NODE_ENV === "production") { throw new Error("JWT_SECRET required in production"); } return { auth: { jwt: { secret: env.JWT_SECRET ?? "dev-only" }, }, }; },
DOs and DON'Ts
DO:
- Use
as template (no real values).env.example - Generate JWT_SECRET with crypto-safe randomness
- Use platform-specific secret management in production
- Validate required secrets on app start
- Use
to keepsyncSecrets
updated.env.example
DON'T:
- Commit
with real secrets.env - Use weak or short JWT secrets
- Hardcode secrets in config files
- Use same secrets across environments
- Log env vars containing secrets
Related Skills
- bknd-local-setup - Initial project setup
- bknd-setup-auth - Configure authentication
- bknd-oauth-setup - OAuth provider configuration
- bknd-storage-config - Storage adapter configuration
- bknd-production-config - Production configuration
- bknd-deploy-hosting - Deployment options