Open format · v0.1
A root-level file that defines what production means for your app. AI tools and platforms can read it and deploy accordingly. Your production intent, in version control.
Production intent for this app
Runtime: Node.js 22
Start command: node server.js
Build command: npm run build
Build output: dist
Required environment variables:
- DATABASE_URL
- STRIPE_SECRET_KEY
Health endpoint: /healthz
Scale: min 1, max 10, memory 512mb
Notes:
Write plain language first. Keep it explicit and actionable.
The problem
Tools like Lovable, Replit, Bolt, and v0 make shipping easier than ever. But production is still shaped by the platform's model: runtime, scaling, env handling, networking, and deploy rules. Move platforms and you often start over.
deploy.checks and health keep rollback policy in the repo, not only in platform dashboards.
Engineers and AI agents can read prod.md and understand production from the repo. Less tribal knowledge, less dashboard dependence.
The prose section gives AI deploy agents the why behind deployment decisions. Clear labels define what to do; notes explain constraints and tradeoffs.
Specification · v0.1
prod.md is free text, not a YAML schema.
Use clear section labels for each concern and write intent in plain language.
Platforms map that intent to their capabilities; omitted details should fall back to sensible defaults.
runtime: engine: node # node | bun | deno | python | go | static version: "22" command: bun start
build: command: bun run build output: dist cache: - node_modules - .next/cache
env: required: - DATABASE_URL - STRIPE_SECRET_KEY optional: - LOG_LEVEL public: - NEXT_PUBLIC_API_URL
regions: primary: eu-west-1 replicas: - us-east-1 edge: true
scale: min: 1 max: 10 concurrency: 100 timeout: 30s memory: 512mb
health: path: /health interval: 10s timeout: 5s unhealthy_threshold: 3
domains: - host: myapp.com redirect_www: true - host: staging.myapp.com env: staging
persistence: databases: - id: main engine: postgres migrations: bun run db:migrate cache: - id: sessions type: redis
jobs: - id: send-digests command: bun run jobs/digest.ts schedule: "0 9 * * 1" - id: process-queue command: bun run worker trigger: queue
observability: logs: level: info format: json metrics: true traces: true errors: provider: sentry
deploy: strategy: blue-green # rolling | blue-green | canary preview: true auto_promote: false checks: - bun test - bun run typecheck
Full example
A complete file for a Next.js app with Postgres, Redis, and a queue worker, plus prose notes that explain critical operational constraints.
Production intent for app: web
Runtime
- Bun 1
- Start command: bun start
Build
- Command: bun run build
- Output directory: .next
- Cache paths: node_modules, .next/cache
Environment variables
- Required: DATABASE_URL, RESEND_API_KEY
- Optional: LOG_LEVEL
- Public: NEXT_PUBLIC_APP_URL
Regions and scaling
- Primary region: eu-west-1
- Edge routing enabled
- Scale: min 1, max 20, concurrency 50, timeout 30s, memory 1gb
State and jobs
- Database: Postgres 16 (run migrations with: bun run db:migrate)
- Cache: Redis for sessions
- Worker: bun run worker (queue-triggered)
Deploy and health
- Strategy: blue-green
- Preview deploys: enabled
- Auto promote: disabled
- Pre-deploy checks: bun test, bun run typecheck
- Health endpoint: /api/health every 15s
Production notes
This app serves EU customers. Keep primary region in eu-west-1.
The worker must not be scaled below 1; the queue will back up.
Blue-green deploys are required; we cannot afford cold-start latency on rollout.
For platforms
Free-text sections express user intent. Platforms can implement them according to their own capabilities while keeping behavior explicit. This enables zero-config starts, clearer rollbacks, and better AI-assisted deployment decisions.
A platform that reads prod.md can configure deployment on first push. That creates a true zero-config path for users who provide intent.
When deploy checks and health expectations are declared, rollback behavior follows stated user intent in the repo.
AI-assisted deploy agents can use prose for the reasoning behind technical choices. Section labels provide the what; prose provides the why.
Implementation conventions
Parse plain-language sections first in the deploy pipeline. Treat statements as intent and, where an intent cannot be honoured, fall back gracefully with a clear log message.
Use sensible defaults for omitted details. Never fail because a section or label is absent.
Warn, never silently ignore, when a declared intent is not supported. Surface this in deploy logs.
Extend via provider sections instead of hidden conventions. Use an explicit label such as Platform notes (Vercel): ... for proprietary extensions.
Defer to Dockerfile when one is present. prod.md is not a container spec; treat runtime notes as advisory when a Dockerfile exists.
Read the prose sections. Freeform notes carry intent rigid schemas cannot express. AI-assisted deploy pipelines should use this context when making decisions.
Publish your supported conventions. Document which section labels and intent patterns you implement, so users know what to expect on your platform.
Open source
PROD.md is an open, portable specification. Anyone can use it, implement it, and improve it in public. The goal is shared production intent without platform lock-in.
The specification text and examples are released under CC0 1.0.
Propose field updates, semantics, and implementation guidance in GitHub discussions and pull requests.
Maintained with community input, including prodwise.com.