Zero-knowledge environment variable management β encrypted, synced, everywhere.
Features Β· Architecture Β· Getting Started Β· Project Structure Β· Environment Variables Β· Development Β· Deployment Β· Contributing Β· Security Β· License
Envval is a zero-knowledge, end-to-end encrypted environment variable manager that keeps your .env files secure and synced across your entire team and all your devices. The server never sees your plaintext secrets.
It ships as three interconnected surfaces β a web dashboard, a REST API, and a VS Code extension β all orchestrated in a single Turborepo monorepo.
| Feature | Description |
|---|---|
| End-to-End Encryption | AES-256-GCM encryption with PBKDF2 key derivation β secrets are encrypted client-side before leaving your machine |
| Zero-Knowledge Architecture | The server stores only encrypted blobs; it can never read your environment variables |
| Cross-Device Sync | Seamlessly sync .env files between your editor, dashboard, and teammates |
| Device Authorization | OAuth 2.0 Device Flow (RFC 8628) for secure VS Code extension authentication |
| Device Isolation | Each device holds its own RSA-wrapped copy of encryption keys β revoke one without affecting others |
| Web Dashboard | Full-featured React 19 UI for managing repositories, environments, and team settings |
| VS Code Extension | Inline hover previews, one-click sync, tracked environment tree view, and smart monorepo detection |
| Transactional Email | Resend-powered email service with React-based templates and BullMQ background processing |
| Type-Safe API Client | Hono RPC client (hc) for fully typed frontend-backend communication |
Envval follows a client-server model where all cryptographic operations happen on the client. The API server acts as an encrypted blob store with an authentication and authorization layer.
graph TB
subgraph Clients
WEB["Web Dashboard<br/>React 19 + TanStack Router"]
EXT["VS Code Extension<br/>TypeScript + VS Code API"]
CLI["CLI Tool<br/>Planned"]
end
subgraph API["API Server"]
HONO["Hono REST API<br/>Node.js + TypeScript"]
AUTH["Better Auth<br/>OAuth + Sessions + Device Flow"]
QUEUE["BullMQ<br/>Background Jobs"]
end
subgraph Data["Data Layer"]
PG[("PostgreSQL<br/>Drizzle ORM")]
REDIS[("Redis<br/>Queue + Rate Limiting")]
end
subgraph Packages["Shared Packages"]
DB_PKG["@envval/db<br/>Schema + Migrations"]
UI_PKG["@envval/ui<br/>React Components"]
EMAIL_PKG["@envval/email<br/>Templates + Resend"]
QUEUE_PKG["@envval/queue<br/>Job Queue Abstraction"]
end
WEB -->|"HTTPS<br/>Encrypted payload"| HONO
EXT -->|"HTTPS<br/>Encrypted payload"| HONO
CLI -.->|"HTTPS"| HONO
HONO --> AUTH
HONO --> QUEUE
HONO --> PG
QUEUE --> REDIS
WEB --> UI_PKG
HONO --> DB_PKG
HONO --> EMAIL_PKG
HONO --> QUEUE_PKG
graph LR
A["Plaintext .env"] --> B["Derive AES Key<br/>PBKDF2"]
B --> C["Generate Random IV"]
C --> D["AES-256-GCM Encrypt"]
D --> E["ciphertext.authTag:iv"]
E --> F["SHA-256 Hash"]
F --> G["Upload Encrypted Blob"]
| Tool | Version | Purpose |
|---|---|---|
| Node.js | >= 18 | Runtime for the API server and build tooling |
| Bun | >= 1.2.8 | Workspace package manager |
| PostgreSQL | >= 14 | Primary data store |
| Redis | >= 6 | Job queue (BullMQ) and rate limiting (Upstash) |
| VS Code | >= 1.106 | Required only for extension development |
# 1. Clone the repository
git clone https://github.com/Rohit-Singh-Rawat/Env0.git
cd Env0
# 2. Install all dependencies (workspace-aware)
bun install
# 3. Set up environment variables
cp apps/api/.env.example apps/api/.env
# Edit apps/api/.env with your database URL, OAuth credentials, etc.
# 4. Push the database schema
bun run --filter=@envval/db db:push
# 5. Start all services in development mode
bun run devThe web app will be available at http://localhost:3000 and the API at http://localhost:8080.
# Web dashboard only
bunx turbo dev --filter=web
# API server only
bunx turbo dev --filter=@envval/api
# VS Code extension (watch mode)
cd apps/extension && bun run watchThis is a Turborepo monorepo with workspaces under apps/ and packages/.
envval/
βββ apps/
β βββ web/ # React 19 dashboard (Vite + TanStack Router)
β βββ api/ # Hono REST API server
β βββ extension/ # VS Code extension
β βββ email-worker/ # BullMQ email processing worker (Bun)
β
βββ packages/
β βββ db/ # Drizzle ORM schema, migrations, and DB client
β βββ ui/ # Shared React component library
β βββ email/ # Email service + React email templates
β βββ queue/ # BullMQ job queue abstraction (Redis)
β βββ typescript-config/# Shared tsconfig presets
β
βββ turbo.json # Turborepo pipeline configuration
βββ package.json # Root workspace configuration
βββ bun.lock # Bun lockfile
| App | Stack | Description |
|---|---|---|
apps/web |
React 19, Vite 7, TanStack Router/Query, Tailwind CSS 4, Motion, Better Auth | Primary web dashboard for managing repositories, environments, and devices |
apps/api |
Hono, Drizzle ORM, Better Auth, Zod, Upstash | RESTful API with typed RPC client exports for the frontend |
apps/extension |
VS Code API, esbuild, Axios | Editor extension with env hover previews, tree view, and device-flow auth |
apps/email-worker |
BullMQ, Winston, Bun runtime | Background worker that processes the email job queue |
| Package | Stack | Description |
|---|---|---|
@envval/db |
Drizzle ORM, PostgreSQL (pg) |
Database schema definitions, migration tooling, and the shared DB client |
@envval/ui |
React 19 | Shared UI primitives (Button, Card, Code, etc.) used across surfaces |
@envval/email |
Resend, Zod | Email service abstraction with React-based templates |
@envval/queue |
BullMQ, ioredis | Redis-backed job queue for async operations (email dispatch, etc.) |
@envval/typescript-config |
TypeScript 5.9 | Reusable tsconfig presets for apps, libraries, and Next.js projects |
Create an .env file in apps/api/ with the following:
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
KEY_MATERIAL_MASTER_KEY |
Yes | 32-byte hex string for server-side envelope encryption |
GOOGLE_CLIENT_ID |
Yes | Google OAuth 2.0 client ID |
GOOGLE_CLIENT_SECRET |
Yes | Google OAuth 2.0 client secret |
GITHUB_CLIENT_ID |
Yes | GitHub OAuth app client ID |
GITHUB_CLIENT_SECRET |
Yes | GitHub OAuth app client secret |
RESEND_API_KEY |
Yes | Resend API key for transactional email |
UPSTASH_REDIS_REST_URL |
Yes | Upstash Redis URL for rate limiting |
UPSTASH_REDIS_REST_TOKEN |
Yes | Upstash Redis token |
PORT |
No | API server port (default: 8080) |
| Variable | Required | Description |
|---|---|---|
REDIS_URL |
Yes | Redis connection string for BullMQ |
RESEND_API_KEY |
Yes | Resend API key |
| Action | Command | Description |
|---|---|---|
| Dev (all) | bun run dev |
Start all services in watch mode |
| Build (all) | bun run build |
Production build for all workspaces |
| Type check | bun run check-types |
Run tsc --noEmit across all packages |
| Lint | bun run lint |
Lint all workspaces |
| Format | bun run format |
Format all TS/MD files with Prettier |
| DB push | bun run --filter=@envval/db db:push |
Push schema changes to the database |
| DB studio | bun run --filter=@envval/db db:studio |
Open Drizzle Studio GUI |
| DB migrate | bun run --filter=@envval/api db:migrate |
Run database migrations |
- Filters respect the dependency graph β
--filter=web...builds@envval/uifirst if needed. - Caching is enabled for
build,lint, andcheck-types; deliberately disabled fordevto avoid stale hot reloads. - Remote caching β run
bunx turbo login && bunx turbo linkwith your Vercel account to share caches across CI.
| Layer | Technology |
|---|---|
| Language | TypeScript 5.9 (strict mode) |
| Monorepo | Turborepo 2.x + Bun workspaces |
| Frontend | React 19, Vite 7, TanStack Router/Query, Tailwind CSS 4, Motion |
| Backend | Hono 4.x, Drizzle ORM, PostgreSQL, BullMQ, ioredis |
| Auth | Better Auth (OAuth + session + device flow) |
| Encryption | AES-256-GCM, PBKDF2, RSA-OAEP (Web Crypto API) |
| Resend + React Email templates | |
| Extension | VS Code API, esbuild |
| Linting | ESLint 9 + Biome 2.x |
| Formatting | Prettier 3 + Biome |
| Testing | Vitest, @vscode/test-cli |
Deploy the Vite-built SPA to any static host:
bun run build --filter=web
# Output: apps/web/dist/Recommended hosts: Vercel, Netlify, Cloudflare Pages.
bun run build --filter=@envval/api
# Output: apps/api/dist/
# Run: node dist/server.jsRecommended hosts: Railway, Fly.io, Render, Vercel Functions.
Note: Set all required environment variables in your deployment target before deploying.
bun run build --filter=@envval/email-worker
# Output: apps/email-worker/dist/
# Run: bun dist/index.jscd apps/extension
bun run package # Produces a .vsix file
# Publish: vsce publish-
bun run buildsucceeds locally with no errors -
bun run check-typespasses - All required environment variables are configured in the deploy target
- Database migrations are applied (
db:migrateordb:push) - Redis is accessible for queue processing and rate limiting
- Extension version is bumped before marketplace upload
Contributions are welcome. Whether it is a bug fix, feature, or documentation improvement β we appreciate it.
- Fork the repository
- Create a feature branch:
git checkout -b feat/your-feature-name - Install dependencies:
bun install - Make your changes and ensure they pass:
bun run check-types # Type safety bun run lint # Code quality bun run build # Build integrity
- Commit using Conventional Commits:
feat: add environment variable search fix: resolve device auth token refresh docs: update API endpoint reference - Open a Pull Request with:
- A clear description of the change
- Screenshots or screencasts for UI changes
- Sample API responses for endpoint changes
- TypeScript β Use strict typing everywhere. Avoid
any. - Components β Add shared components to
packages/ui; keep app-specific components local. - API routes β Follow the existing
modules/pattern with*.handler.ts,*.service.ts, and*.schema.ts. - Tests β Add tests when touching API routes or UI logic. Use Vitest for web,
@vscode/test-clifor the extension. - Commits β Keep them atomic and well-scoped. One logical change per commit.
Envval takes security seriously. The entire system is built on a zero-knowledge architecture β the server never has access to plaintext secrets.
| Threat | Mitigation |
|---|---|
| Server database breach | Key material is encrypted at rest using envelope encryption |
| Network interception | HTTPS + RSA-OAEP wrapped key material |
| Device compromise | Per-device key wrapping; revoke one device without affecting others |
| Replay attacks | Short-lived JWTs (15 min) + session validation |
| Key material leak | Master key rotation re-encrypts all user key materials |
Please do NOT open a public GitHub issue for security vulnerabilities.
If you discover a security vulnerability, please report it responsibly by emailing security@envval.io (or contacting the maintainer directly). We will acknowledge receipt within 48 hours and work on a fix promptly.
- CLI tool for CI/CD pipeline integration
- Team sharing and role-based access control
- Environment version history and rollback
- Key rotation mechanism
- Self-hosted deployment option (Docker Compose)
- Web app device registration with RSA keypair
- Audit logs for environment access
This project is licensed under the MIT License.
Built by Rohit Singh Rawat
