stacks-env

$npx mdskill add stacksjs/stacks/stacks-env

Manage typed environment variables with auto-coercion and encryption in Stacks.

  • Provides a typed proxy for accessing env vars with auto-coercion.
  • Depends on @stacksjs/env, config/env.ts, and .env files.
  • Detects runtime, platform, and CI provider to load correct env.
  • Supports CLI commands for encrypting, decrypting, and rotating env values.

SKILL.md

.github/skills/stacks-envView on GitHub ↗
---
name: stacks-env
description: Use when working with environment variables in Stacks — the typed env proxy with auto-coercion, .env file loading, AES-256-GCM encryption/decryption of env values, runtime/platform detection, CI provider detection, or the env CLI commands. Covers @stacksjs/env, config/env.ts, and .env files.
license: MIT
compatibility: Bun >= 1.3.0, TypeScript
allowed-tools: Read Edit Write Bash Grep Glob
---

# Stacks Environment

## Key Paths
- Core package: `storage/framework/core/env/src/`
- Environment config: `config/env.ts`
- Environment file: `.env`
- Example: `.env.example`
- Type definitions: `storage/framework/env.d.ts`

## Source Files
```
env/src/
├── index.ts     # main exports
├── utils.ts     # runtime/platform detection, StacksEnv proxy
├── plugin.ts    # Bun plugin for auto .env loading
├── parser.ts    # .env file parser with encryption support
├── cli.ts       # CLI commands (get, set, encrypt, decrypt, rotate)
├── crypto.ts    # AES-256-GCM + secp256k1 encryption
└── types.ts     # StacksEnv interface (100+ typed vars)
```

## Typed Environment Proxy

```typescript
import { env } from '@stacksjs/env'

env.APP_NAME        // string
env.APP_ENV         // 'local' | 'dev' | 'stage' | 'prod'
env.APP_KEY         // string
env.APP_URL         // string
env.DEBUG           // boolean (auto-coerced)
env.PORT            // number (auto-coerced)
env.DB_CONNECTION   // 'sqlite' | 'mysql' | 'postgres' | 'dynamodb'
env.DB_HOST         // string
env.DB_PORT         // number
env.DB_DATABASE     // string
env.DB_USERNAME     // string
env.DB_PASSWORD     // string
env.AWS_ACCESS_KEY_ID    // string
env.STRIPE_SECRET_KEY    // string
env.MAIL_MAILER          // string
env.QUEUE_DRIVER         // string
env.REDIS_HOST           // string
env[key]                 // any custom env var
```

The `env` proxy auto-coerces: `'true'` → `true`, `'123'` → `123`, etc.

## StacksEnv Type (100+ typed variables)
App, Ports, API, Database, AWS, Mail, Services (Stripe, Meilisearch), Frontend, Realtime, Redis, Pusher, Auth, Storage, Queue, plus `[key: string]` catch-all.

## Runtime Detection

```typescript
import { isBun, isNode, runtime, runtimeInfo, platform, isWindows, isMacOS, isLinux, hasTTY, hasWindow, isCI, isDebug, isMinimal, isColorSupported, provider, providerInfo } from '@stacksjs/env'

isBun           // true
isNode          // false
runtime         // 'bun'
platform        // 'darwin'
isWindows       // false
isMacOS         // true
isLinux         // false
hasTTY          // true (terminal)
isCI            // false
isDebug         // boolean
isColorSupported // true
```

## CI Provider Detection

```typescript
provider        // 'github-actions' | 'gitlab-ci' | 'circleci' | 'travis' | 'jenkins' | 'vercel' | 'netlify' | 'heroku' | 'aws' | 'azure' | 'cloudflare' | 'railway' | 'render' | ...
providerInfo    // { name: string, ... }
```

## .env File Loading

```typescript
import { loadEnv, autoLoadEnv, envPlugin } from '@stacksjs/env'

await loadEnv({ path: '.env', override: false })
autoLoadEnv()  // detects .env, .env.local, .env.{APP_ENV}

// Bun plugin (auto-loads .env before app starts)
envPlugin()
```

## .env Parser

```typescript
import { parse } from '@stacksjs/env'

const vars = parse(envContent, {
  encryption: true,       // decrypt encrypted values
  privateKey: '...'       // decryption key
})
```

## Encryption (AES-256-GCM)

```typescript
import { aesEncrypt, aesDecrypt, generateKeypair, encryptValue, decryptValue, getPrivateKey } from '@stacksjs/env'

// AES-256-GCM symmetric encryption
const encrypted = aesEncrypt(plaintext, password)
const decrypted = aesDecrypt(encrypted, password)

// Asymmetric encryption (secp256k1 ECIES-style)
const keypair = generateKeypair()
const encrypted = encryptValue(value, keypair.publicKey)
const decrypted = decryptValue(encrypted, keypair.privateKey)
```

## CLI Commands

```bash
buddy env:get APP_NAME                    # get single var
buddy env:get --all --format json         # all vars as JSON
buddy env:set APP_NAME "My App"           # set var
buddy env:encrypt                          # encrypt .env file
buddy env:decrypt                          # decrypt .env file
buddy env:keypair                          # generate encryption keypair
buddy env:rotate                           # rotate encryption keys
buddy env:check                            # validate env configuration
```

## Gotchas
- Bun natively loads `.env` — no dotenv package needed
- The `env` proxy auto-coerces strings to booleans/numbers
- `.env` should never be committed — use `.env.example` as template
- Encryption uses AES-256-GCM for values and secp256k1 for key exchange
- `autoLoadEnv()` loads in order: `.env`, `.env.local`, `.env.{APP_ENV}`
- Runtime detection uses Bun globals and process properties
- CI provider detection checks environment variables specific to each CI system
- The `StacksEnv` type provides autocomplete for 100+ known variables

More from stacksjs/stacks

SkillDescription
stacks-actionsUse when working with Stacks server actions — creating actions in app/Actions/, auto-generated API actions from the useApi model trait, the 80+ default framework actions (auth, dashboard, commerce, content, deployment, jobs), action request/response handling, or action registration. Covers @stacksjs/actions and storage/framework/defaults/actions/.
stacks-aiUse when integrating AI capabilities into a Stacks application — using Anthropic/OpenAI/Ollama/AWS Bedrock drivers, image generation (DALL-E), vision analysis, RAG/vector search, embeddings, MCP (Model Context Protocol) clients, text summarization, sentiment analysis, content classification, personalization, or the buddy AI assistant. Covers @stacksjs/ai and config/ai.ts.
stacks-aliasUse when working with path aliases in a Stacks project — import resolution, module aliasing, or debugging import paths. Covers @stacksjs/alias which defines 260+ path mappings for the entire framework.
stacks-analyticsUse when adding analytics to a Stacks application — configuring Fathom or self-hosted analytics, generating tracking scripts, privacy-friendly analytics setup, or the analytics configuration. Covers @stacksjs/analytics and config/analytics.ts.
stacks-apiUse when building, modifying, or debugging API endpoints in a Stacks application — defining routes, handling requests, API middleware, working with the API server, HTTP client (fetcher), API resources, or OpenAPI generation. Covers both @stacksjs/api utilities and the stacks-api server implementation.
stacks-arraysUse when working with array utilities in Stacks — statistical operations (average, median, mode, standard deviation, z-score, percentile, covariance), array manipulation (unique, flatten, partition, shuffle, sample, move), containment checks, or the Arr facade. Covers @stacksjs/arrays.
stacks-authUse when implementing authentication, authorization, passkeys, TOTP/2FA, RBAC, gates, policies, session auth, token management, email verification, password resets, or rate limiting in a Stacks application. Covers the @stacksjs/auth package, config/auth.ts, app/Gates.ts, and app/Middleware/.
stacks-auto-importsUse when working with the Stacks auto-import system — understanding how browser and server auto-imports work, configuring auto-imported functions/models/composables, the auto-import manifests, type generation, or how globals are injected. Covers the auto-import pipeline at storage/framework/auto-imports/.
stacks-brandkitUse when defining or exploring a brand identity for a Stacks project and you want premium brand-kit REFERENCE IMAGES first - logo directions, palettes, typography specimens, identity boards, and application/mockup decks. Generates IMAGES ONLY, never code. Trained for minimalist, cinematic, editorial, dark-tech, luxury, cultural, security, gaming, developer-tool, and consumer-app brand systems with intentional logo concepting, sparse type, strong symbolic meaning, and disciplined palettes a coding step can build against.
stacks-browseUse for headless browser QA on Stacks applications — navigation, screenshots, responsive testing, console/network monitoring, and accessibility snapshots. Dependency-free: drives a system browser over the Chrome DevTools Protocol using only Bun (no Playwright/Puppeteer). Invoke with /stacks-browse.