import Link from "next/link"; /* ------------------------------------------------------------------ */ /* SVG Icons (inline to avoid extra deps) */ /* ------------------------------------------------------------------ */ const ShieldIcon = () => ( ); const TerminalIcon = () => ( ); const BoltIcon = () => ( ); const ClockIcon = () => ( ); const UsersIcon = () => ( ); const EyeSlashIcon = () => ( ); const DiffIcon = () => ( ); const ServerIcon = () => ( ); /* ------------------------------------------------------------------ */ /* Reusable tiny components */ /* ------------------------------------------------------------------ */ function Badge({ children }: { children: React.ReactNode }) { return ( {children} ); } function SectionHeading({ badge, title, subtitle }: { badge: string; title: string; subtitle: string }) { return (
{badge}

{title}

{subtitle}

); } /* ------------------------------------------------------------------ */ /* Feature cards data */ /* ------------------------------------------------------------------ */ const features = [ { icon: , title: "CLI-first workflow", desc: "envsync push, pull, diff — feels like git for your .env files. Integrates into any CI/CD pipeline.", }, { icon: , title: "End-to-end encryption", desc: "Secrets encrypted client-side with libsodium before ever hitting the server. Zero-knowledge by design.", }, { icon: , title: "Real-time notifications", desc: "Teammates get notified instantly via Redis pub/sub the moment environment variables change.", }, { icon: , title: ".env diff viewer", desc: "Visual diff in the web dashboard showing exactly what changed between vault versions.", }, { icon: , title: "Org & project management", desc: "Multi-team support with role-based access control — Admin, Editor, and Viewer roles.", }, { icon: , title: "Audit log & versioning", desc: "Full history of who changed what, when, and from where. Rollback to any previous version.", }, { icon: , title: "Zero-knowledge security", desc: "Server only stores ciphertext. Argon2 key derivation + XChaCha20-Poly1305 encryption.", }, { icon: , title: "100% self-hosted", desc: "Docker Compose one-liner. PostgreSQL, Redis, MinIO, Keycloak, NGINX — all on your infra.", }, ]; /* ------------------------------------------------------------------ */ /* Tech stack data */ /* ------------------------------------------------------------------ */ const techStack = [ { layer: "Frontend", tech: "Next.js 15", detail: "App Router" }, { layer: "Backend", tech: "Spring Boot 3", detail: "Java 21" }, { layer: "Database", tech: "PostgreSQL 16", detail: "Vaults & Audit" }, { layer: "Cache", tech: "Redis 7", detail: "Pub/Sub" }, { layer: "Storage", tech: "MinIO", detail: "S3-compatible" }, { layer: "Auth", tech: "Keycloak", detail: "OIDC / SSO" }, { layer: "Proxy", tech: "NGINX", detail: "TLS termination" }, { layer: "Encryption", tech: "libsodium", detail: "Client-side" }, ]; /* ------------------------------------------------------------------ */ /* CLI lines for the terminal animation */ /* ------------------------------------------------------------------ */ const cliLines = [ { prompt: true, text: "envsync login" }, { prompt: false, text: "✓ Authenticated via Keycloak (SSO)" }, { prompt: true, text: "envsync init --project my-app --env development" }, { prompt: false, text: "✓ Vault initialized for my-app/development" }, { prompt: true, text: "envsync push" }, { prompt: false, text: "✓ Encrypted & pushed 12 variables to vault" }, { prompt: true, text: "envsync diff" }, { prompt: false, text: " + STRIPE_WEBHOOK_SECRET = ●●●●●●●●" }, { prompt: false, text: " ~ DATABASE_URL (modified)" }, { prompt: false, text: " - OLD_API_KEY (removed)" }, { prompt: true, text: "envsync pull" }, { prompt: false, text: "✓ Pulled latest vault → .env (3 changes)" }, ]; /* ------------------------------------------------------------------ */ /* Architecture nodes */ /* ------------------------------------------------------------------ */ const archNodes = [ { label: "CLI Tool", sub: "push / pull / diff", color: "border-emerald-500/40 bg-emerald-500/5" }, { label: "NGINX", sub: "Reverse Proxy · TLS", color: "border-zinc-600 bg-zinc-800/50" }, { label: "Spring Boot API", sub: "Auth · Vault · Audit", color: "border-emerald-500/30 bg-emerald-500/5" }, { label: "PostgreSQL", sub: "Vaults & Logs", color: "border-blue-500/30 bg-blue-500/5" }, { label: "Redis", sub: "Pub/Sub Notifications", color: "border-red-500/30 bg-red-500/5" }, { label: "MinIO", sub: "Encrypted Backups", color: "border-yellow-500/30 bg-yellow-500/5" }, { label: "Keycloak", sub: "SSO · OIDC · MFA", color: "border-purple-500/30 bg-purple-500/5" }, { label: "Next.js Dashboard", sub: "Web UI · Diff Viewer", color: "border-emerald-500/40 bg-emerald-500/5" }, ]; /* ================================================================== */ /* PAGE */ /* ================================================================== */ export default function LandingPage() { return (
{/* ───── Ambient glow blobs ───── */}
{/* ═══════════════════════════════════════════════════════════ */} {/* NAV */} {/* ═══════════════════════════════════════════════════════════ */} {/* ═══════════════════════════════════════════════════════════ */} {/* HERO */} {/* ═══════════════════════════════════════════════════════════ */}
🚧 Under Development

Git for your .env files

Stop sending secrets over Slack. EnvSync gives your team a single{" "} encrypted source of truth for environment variables — with diffing, versioning, and real-time notifications.{" "} 100% self-hosted.

Star on GitHub $ npm install -g envsync-cli
{/* Hero terminal preview */}
Terminal — envsync
{cliLines.map((line, i) => line.prompt ? (
❯ {line.text}
) : (
{line.text}
), )}
❯ ▊
{/* ═══════════════════════════════════════════════════════════ */} {/* PROBLEM */} {/* ═══════════════════════════════════════════════════════════ */}

The Problem

Every dev team has this conversation

@alice:{" "} Hey did you add the new STRIPE_WEBHOOK_SECRET to your .env?

@bob:{" "} Wait there's a new one? Since when?

Environment variable drift causes bugs that are impossible to reproduce, broken local setups, and secrets leaking through Slack DMs.{" "} EnvSync fixes this — and keeps everything on your own infrastructure.

{/* ═══════════════════════════════════════════════════════════ */} {/* FEATURES */} {/* ═══════════════════════════════════════════════════════════ */}
{features.map((f, i) => (
{f.icon}

{f.title}

{f.desc}

))}
{/* ═══════════════════════════════════════════════════════════ */} {/* CLI */} {/* ═══════════════════════════════════════════════════════════ */}
{/* Left – command list */}
{[ { cmd: "envsync init --project my-app --env dev", desc: "Initialize a vault for your project" }, { cmd: "envsync push", desc: "Encrypt & push local .env to the vault" }, { cmd: "envsync pull", desc: "Pull latest secrets from the vault" }, { cmd: "envsync diff", desc: "See what changed between local & remote" }, { cmd: "envsync log", desc: "View full audit log for the vault" }, { cmd: "envsync rollback --version 12", desc: "Restore a previous vault version" }, { cmd: "envsync set KEY \"value\"", desc: "Set a single variable remotely" }, { cmd: "envsync envs", desc: "List all environments" }, ].map((item, i) => (
{item.cmd} {item.desc}
))}
{/* Right – tall terminal */}
zsh — envsync diff

❯ envsync diff

Comparing local .env ↔ vault (v14)

+ STRIPE_WEBHOOK_SECRET=whsec_●●●●●●●●

+ FEATURE_FLAG_V2=true

~ DATABASE_URL=postgres://...→...prod

- DEPRECATED_API_KEY

NEXT_PUBLIC_URL=https://app.example.com

REDIS_URL=redis://cache:6379

3 added · 1 modified · 1 removed · 2 unchanged

❯ envsync pull

✓ Pulled vault v14 → .env (4 changes applied)

❯ ▊
{/* ═══════════════════════════════════════════════════════════ */} {/* ARCHITECTURE */} {/* ═══════════════════════════════════════════════════════════ */}
{archNodes.map((node, i) => (

{node.label}

{node.sub}

))}
{/* Connection hint */}
All services connected via Docker internal network · TLS terminated at NGINX
{/* ═══════════════════════════════════════════════════════════ */} {/* TECH STACK */} {/* ═══════════════════════════════════════════════════════════ */}
{techStack.map((row, i) => ( ))}
Layer Technology Detail
{row.layer} {row.tech} {row.detail}
{/* ═══════════════════════════════════════════════════════════ */} {/* SECURITY */} {/* ═══════════════════════════════════════════════════════════ */}
{[ { step: "01", title: "Key derivation", desc: "Password → secret key via Argon2id (memory-hard KDF)" }, { step: "02", title: "Client-side encrypt", desc: "XChaCha20-Poly1305 encrypts your .env before upload" }, { step: "03", title: "Server stores ciphertext", desc: "PostgreSQL only ever sees encrypted blobs — zero knowledge" }, { step: "04", title: "Team sharing", desc: "Vault key wrapped with each member's public key (asymmetric)" }, ].map((s, i) => (
{s.step}

{s.title}

{s.desc}

))}
{/* ═══════════════════════════════════════════════════════════ */} {/* GETTING STARTED CTA */} {/* ═══════════════════════════════════════════════════════════ */}

Ready to stop the .env chaos?

Get up and running in under 5 minutes. Clone the repo, run Docker Compose, and your whole team has a single encrypted source of truth.

$ git clone https://github.com/yourusername/envsync.git

$ cd envsync && docker compose up -d

# PostgreSQL, Redis, MinIO, Keycloak, NGINX — all running ✓

View on GitHub Try the Dashboard
{/* ═══════════════════════════════════════════════════════════ */} {/* FOOTER */} {/* ═══════════════════════════════════════════════════════════ */}
); }