# REP — Runtime Environment Protocol | Secure Runtime Env Vars for Frontend Apps
> Inject environment variables into browser apps at container runtime — not build time. AES-256 encryption, secret detection, hot reload. Build once, deploy anywhere.
Source: https://rep-protocol.dev/
Same frontend image, different environment, dynamic variables — no rebuild, no redeploy.
## The Problem
Every frontend framework resolves environment variables at **build time** — `process.env.API_URL` becomes a hardcoded string in your JavaScript bundle. This creates problems that compound in production:
**One build per environment**
Your staging bundle can't be promoted to production. You rebuild for every environment, breaking the container promise of "build once, run anywhere."
**No security model**
All variables are treated equally. API keys, analytics tokens, and public URLs all end up as plaintext strings in your bundle — visible to anyone who opens View Source.
**Config changes require redeployment**
Need to rotate an API key or flip a feature flag? Rebuild, re-test, redeploy. Even if your backend can hot-swap config, your frontend can't.
**Secrets leak into build logs**
CI/CD pipelines pass secrets as build args. They appear in Docker layer history, build logs, and cached artifacts — creating supply chain risk.
## What REP Does
REP is an open protocol and reference implementation that **decouples environment variables from the build process entirely**. A lightweight gateway reads variables at startup, classifies them by security tier, encrypts sensitive values, and injects them into HTML responses — whether you're running containers, static builds, or local development.
**Three Security Tiers**
**PUBLIC** — plaintext, synchronous access. **SENSITIVE** — AES-256-GCM encrypted, decrypted on demand. **SERVER** — never sent to the browser. Classification by naming convention eliminates ambiguity.
**Encryption + Integrity**
Sensitive variables are encrypted with ephemeral keys generated at startup. Every payload carries an HMAC-SHA256 integrity token and SRI hash to detect tampering in transit.
**Secret Detection Guardrails**
Entropy analysis and known-format matching (AWS keys, JWTs, Stripe keys, GitHub tokens) catch misclassified secrets before they reach the browser. Strict mode makes warnings into hard failures.
**Hot Reload via SSE**
Config changes push to every connected browser via Server-Sent Events. No page reload, no redeployment. Edit an env file or rotate a ConfigMap — the UI updates live.
## Works Everywhere
REP operates at the **infrastructure layer** in production — no build-tool plugin required, no framework coupling. It works with any frontend stack that produces HTML. Optional dev-time plugins exist purely for local DX (see below).
**Containers**
Reverse proxy mode sits in front of nginx, caddy, or any upstream. Embedded mode serves static files directly from a `FROM scratch` image.
**Static Builds**
Build your app once with `npm run build`. The gateway injects config into the static HTML at serve time — same artifact for every environment.
**Local Development**
Install the [Vite](/reference/plugins/vite/) or [Next.js](/reference/plugins/next/) plugin for zero-config `dev` support, or the CLI wraps the gateway to proxy any dev server with hot reload.
**Any Framework**
First-party adapters for React, Vue, and Svelte. A zero-dependency TypeScript SDK works with anything — Angular, vanilla JS, or your custom setup.
## Compared to Existing Solutions
| Approach | Security Tiers | Encrypted Vars | Integrity Check | Hot Reload | Standalone Binary |
|---|:---:|:---:|:---:|:---:|:---:|
| `envsubst` / `sed` on bundles | -- | -- | -- | -- | -- |
| Fetch `/config.json` at runtime | -- | -- | -- | -- | -- |
| `window.__ENV__` via shell script | -- | -- | -- | -- | -- |
| Build-tool plugins (dotenv, etc.) | -- | -- | -- | -- | -- |
| **REP** | **3-tier** | **AES-256-GCM** | **HMAC + SRI** | **SSE** | **~7MB Go** |
## Quick Example
**SDK Usage**
```typescript
import { rep } from '@rep-protocol/sdk';
// Synchronous — no loading state needed
const apiUrl = rep.get('API_URL');
const flags = rep.get('FEATURE_FLAGS');
// Encrypted — decrypted on demand via session key
const key = await rep.getSecure('ANALYTICS_KEY');
// Hot reload — react to config changes live
rep.onChange('FEATURE_FLAGS', (newValue) => {
console.log('Flags updated:', newValue);
});
```
**Docker Compose**
```yaml
# Same image, different config — true build-once, deploy-anywhere
services:
frontend-staging:
image: myapp:latest
environment:
REP_PUBLIC_API_URL: "https://api.staging.example.com"
REP_SENSITIVE_ANALYTICS_KEY: "UA-XXXXX-staging"
REP_SERVER_INTERNAL_SECRET: "never-reaches-browser"
frontend-prod:
image: myapp:latest # SAME IMAGE
environment:
REP_PUBLIC_API_URL: "https://api.example.com"
REP_SENSITIVE_ANALYTICS_KEY: "UA-XXXXX-prod"
REP_SERVER_INTERNAL_SECRET: "also-never-reaches-browser"
```
**Variable Tiers**
```bash
# PUBLIC — plaintext in page source, rep.get()
REP_PUBLIC_API_URL=https://api.example.com
# SENSITIVE — AES-256-GCM encrypted, await rep.getSecure()
REP_SENSITIVE_ANALYTICS_KEY=UA-12345-1
# SERVER — never leaves the gateway process
REP_SERVER_DB_PASSWORD=never-reaches-browser
```
## Project Components
**Gateway**
Go binary (~7MB). Zero dependencies. `FROM scratch` compatible. Proxy or embedded mode.
**SDK**
TypeScript. Zero runtime deps. ~1.5KB gzipped. Synchronous `get()`, async `getSecure()`.
**CLI**
`rep validate`, `rep typegen`, `rep lint`, `rep dev`. Full development workflow.
**Adapters**
First-party React, Vue, and Svelte adapters with hot-reload-aware hooks and stores.
**Build-Tool Plugins**
Vite (`repPlugin()`) and Next.js (`RepScript`) plugins inject the same payload during `npm run dev` — no gateway needed locally.
**Codemod**
`npx @rep-protocol/codemod` automates migration from Vite, CRA, or Next.js `process.env`/`import.meta.env` reads to `rep.get()`.
## Specification Status
| Document | Status |
|---|---|
| [REP-RFC-0001](/spec/rfc-0001/) | Active |
| [Security Model](/spec/security-model/) | Active |
| [Conformance](/spec/conformance/) | Active |
Current versions and the versioning policy are on the [specification overview](/spec/).
Specification documents are licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Code is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).