ElectricSQL
Audited from github.com/electric-sql/electric
ElectricSQL is a Postgres sync engine, built on an Elixir/OTP sync service plus TypeScript clients, that now also hosts Electric Agents, an agent platform reusing the same sync foundation across desktop, mobile, and MCP.
- Language
- TypeScript
- Database
- PostgreSQL
- Hosting
- Docker
- License
- Apache-2.0
- Running for
- 2 years
- Team
- 6-20 People
Why this architecture
Postgres logical replication and shape-based HTTP sync live in a dedicated Elixir OTP service so any TypeScript, React, or Elixir client can subscribe to partial replicas without each client re-implementing replication.
Tech stack by layer
5 technologies · audited Sep 17, 2026- ElixirImplements the Postgres sync engine (shape log, HTTP API, logical replication client) as an OTP release.
- PhoenixProvides an optional, env-var-gated LiveDashboard for real-time monitoring of the running sync service.
- RustImplements the standalone Durable Streams server, a storage primitive underlying the Electric Agents runtime.
- PostgreSQLSource-of-truth database Electric replicates from via logical replication; local dev runs it through docker-compose.
- DockerThe sync service, Durable Streams server, and Agents server each ship a production Dockerfile; docker-compose drives local Postgres.
- GitHub ActionsRuns the polyglot CI matrix: Elixir tests, Rust tests, TypeScript checks, and multi-arch Docker/mobile/desktop builds.
- Model Context ProtocolThe agents-mcp package implements MCP registry, transports, and OAuth bridges so agents can call external MCP tools.
- TanStack DBClient apps (agents-mobile) treat synced Postgres shapes as local reactive collections via @tanstack/electric-db-collection.
- ElectronPackages the Electric Agents desktop app, built and signed with electron-builder.
- ExpoBuilds the Electric Agents mobile app for iOS, Android, and web from one React Native codebase.
ElectricSQL architecture diagram
Open SVGDiagram as text
- Client apps (@electric-sql/react · TanStack) → Sync service (Elixir · OTP): HTTP shapes
- Electric Agents (desktop · mobile · MCP) → Durable Streams (Rust): streams
- Electric Agents (desktop · mobile · MCP) → Sync service (Elixir · OTP): shapes
- PostgreSQL (source of truth) → Sync service (Elixir · OTP): WAL replication
- Sync service (Elixir · OTP) → Shape log (per-shape storage): append
- Sync service (Elixir · OTP) → LiveDashboard (Phoenix (opt-in)): metrics
Key architectural decisions
6 decisions- 01
A polyglot core: Elixir sync engine plus a separate Rust streams server
packages/sync-service/mix.exs defines the Elixir/OTP application (app: :electric) that implements Postgres logical replication and the shape-based HTTP sync API, while packages/durable-streams-rust/Cargo.toml is an unrelated Rust binary (durable-streams-server) providing a Durable Streams storage primitive for the newer Electric Agents layer.
- 02
Phoenix LiveDashboard is opt-in and unauthenticated by design
README.md documents an optional Phoenix LiveDashboard enabled only when ELECTRIC_LIVE_DASHBOARD_PORT is set, with an explicit warning that the endpoint is completely unauthenticated and must be restricted at the network layer in production rather than through application-level auth.
- 03
Documentation is a workspace member, not a separate repo
pnpm-workspace.yaml includes website alongside packages/* and examples/*, and website/package.json (@electric-sql/docs) builds a VitePress site with a custom OpenAPI doc generator (api:build_docs, redocly build-docs against website/electric-api.yaml) that stays versioned with the code it documents.
- 04
Electric Agents reuses the sync client across desktop, mobile, and MCP
packages/agents-desktop (Electron, via electron-builder), packages/agents-mobile (Expo/React Native), and packages/agents-mcp (Model Context Protocol registry and OAuth bridges) all depend on @electric-sql/client and @electric-ax/agents-runtime as workspace packages, so the same Postgres-sync foundation backs every agent surface.
- 05
The desktop app does local vector search instead of calling a server
packages/agents-desktop/package.json depends on better-sqlite3 and sqlite-vec together, giving the Electron app an embedded SQLite database with vector search built in, rather than routing embedding queries to a hosted vector database.
- 06
TypeScript client and elixir-client both track the wire-compatible shape protocol
packages/typescript-client/package.json (@electric-sql/client) and packages/elixir-client/mix.exs (electric_client, an optional dependency on :electric) are maintained as parallel implementations of the same HTTP shape protocol, so both Node/browser and Elixir/Phoenix consumers can subscribe to Postgres shapes without a shared runtime.
How ElectricSQL is built
How ElectricSQL is structured
The repository is a pnpm workspace (pnpm-workspace.yaml: packages/*, examples/*, website) sitting on top of an Elixir application inside packages/sync-service. The core sync engine — packages/sync-service (Elixir, mix.exs app name :electric) — implements Postgres logical replication and the shape-based HTTP sync protocol described in website/electric-api.yaml. Around that core sit several TypeScript client packages (packages/typescript-client, packages/react-hooks, packages/y-electric for Yjs, packages/elixir-client as the Elixir-native equivalent) and, more recently, a full "Electric Agents" product line: packages/agents, packages/agents-runtime, packages/agents-server, packages/agents-desktop, packages/agents-mobile, packages/agents-mcp, and the electric-ax CLI (packages/electric-ax). A separate Rust crate, packages/durable-streams-rust, implements a Durable Streams server used as a storage primitive by the agents layer. CLAUDE.md and AGENTS.md at the repo root, along with per-area docs like docs/agents-development.md, document this split for contributors.
Frontend
The @electric-sql/react package (packages/react-hooks) wraps the TypeScript client in a useShape hook backed by use-sync-external-store, letting React components subscribe to Postgres shapes reactively. The Electric Agents desktop and mobile UIs share packages/agents-server-ui, consumed as a workspace dependency by both packages/agents-desktop (Electron) and packages/agents-mobile (Expo). Separately, the public documentation site (website/) is a VitePress app — website/package.json names the package @electric-sql/docs and runs vitepress build plus a custom OpenAPI doc pipeline (redocly build-docs against website/electric-api.yaml) to keep the HTTP API reference in sync with the spec.
Backend & APIs
packages/sync-service is the sync engine: an OTP release (releases: [electric: [...]] in mix.exs) that connects to Postgres, streams the logical replication feed, and serves the shape HTTP API. It optionally exposes a Phoenix LiveDashboard for VM and process metrics when ELECTRIC_LIVE_DASHBOARD_PORT is set — the README explicitly warns this endpoint ships with no authentication and must be firewalled in production. packages/durable-streams-rust is an unrelated Rust binary (durable-streams-server, Cargo.toml crate durable-streams) built on Tokio that provides append-only durable streams, used by packages/agents-server (a Node/TypeScript service, @electric-ax/agents-server) as a storage layer for agent entity state. packages/agents-mcp (@electric-ax/agents-mcp) implements Model Context Protocol registries, transports, and OAuth bridges via @modelcontextprotocol/sdk, letting Electric Agents call out to external MCP tools.
Data & persistence
Postgres is the source of truth for the sync engine: .support/docker-compose.yml and .support/postgres.conf define the local Postgres instance the sync service replicates from, with logical replication as the required configuration. On the client side, the Electron desktop app (packages/agents-desktop) keeps its own local store using better-sqlite3 together with sqlite-vec, giving it embedded vector search without a hosted vector database. Mobile and web agent clients use @tanstack/db, @tanstack/electric-db-collection, and @tanstack/react-db (declared in packages/agents-mobile/package.json) to project synced Postgres shapes into local, reactive TanStack DB collections.
Build, test & deploy
CI runs through GitHub Actions workflows under .github/workflows, split by component: elixir_client_tests.yml and sync_service_tests.yml for the Elixir side, server_rust_tests.yml for the Durable Streams server, ts_check_formatting.yml and integration_tests.yml for the TypeScript packages, plus platform-specific pipelines (agents_desktop_build.yml, agents_desktop_canary.yml, agents_mobile_build.yml, agents_mobile_ios_simulator.yml). Each deployable component ships its own Dockerfile: packages/sync-service/Dockerfile builds a multi-stage Elixir release image (Elixir 1.20.2 on Erlang/OTP 29.0.2, Debian bookworm base), packages/agents-server/Dockerfile builds the Node agents server with pnpm workspace filtering (pnpm install --filter @electric-ax/agents-server...), and packages/durable-streams-rust/Dockerfile builds the Rust binary. Release publishing is managed by Changesets (.changeset/, changesets_release.yml), publishing both npm packages and the electric and electric_client Hex packages via ci:publish:hex-electric / ci:publish:hex-electric-client scripts in the root package.json.
Self-hosting notes
Running Electric requires a Postgres instance with logical replication enabled and Electric pointed at it via DATABASE_URL, per the README's Getting Started section; docker compose -f .support/docker-compose.yml up starts a compatible local Postgres. Production LiveDashboard access must be restricted at the network layer, since the README states the dashboard endpoint is unauthenticated by design when enabled.
What to copy (and what not to)
Keeping the replication-heavy, operationally sensitive core (Postgres logical replication, shape computation) in a single Elixir/OTP service — separate from the many client SDKs and the newer agents product surfaces — is a reasonable way to isolate the hardest part of the system from its consumers. Shipping parallel TypeScript and Elixir clients for the same wire protocol (packages/typescript-client, packages/elixir-client) is worth studying if you need to support consumers on both stacks without forcing either through the other's runtime. The breadth of the Electric Agents surface — a Rust streams server, an Electron desktop app, an Expo mobile app, and an MCP bridge, all in one monorepo — reflects a specific, recent product pivot documented in docs/agents-development.md and AGENTS_DESKTOP_PLAN.md; teams that only need Postgres sync (not a full agent platform) can adopt packages/sync-service and packages/typescript-client without the rest.
Sources & repo audit
- Audited
- Sep 17, 2026
- Commit
- bb39742
- License
- Apache-2.0
- packages/sync-service/mix.exs (Elixir sync engine)
- packages/durable-streams-rust/Cargo.toml
- packages/agents-desktop/package.json (Electron)
- packages/agents-mcp/package.json (Model Context Protocol)
- pnpm-workspace.yaml
- README.md (Phoenix LiveDashboard, quickstart)
Independent analysis of repository at github.com/electric-sql/electric. Spotted an inaccuracy? Use the claim form to request a correction.
Show this stack on your README or website
[](https://stackitfast.com/project/electric-sql)Paste it into your README. It shows your current stack and links to this page.
Scaffold it with your agent
Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with ElectricSQL's architecture.
- 1Copy the promptThe full markdown spec, with every layer and decision.
- 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
- 3Paste and scaffoldUse it as the first instruction; review before you ship.
# MISSION: Scaffold "ElectricSQL" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **ElectricSQL**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: ElectricSQL
- **What It Does**: ElectricSQL is a Postgres sync engine, built on an Elixir/OTP sync service plus TypeScript clients, that now also hosts Electric Agents, an agent platform reusing the same sync foundation across desktop, mobile, and MCP.
- **Domain & Category**: Local-First Sync Engine
- **Production Scale**: 6-20 People
- **Development Mode**: CLASSIC
- **Architectural Rationale**: Postgres logical replication and shape-based HTTP sync live in a dedicated Elixir OTP service so any TypeScript, React, or Elixir client can subscribe to partial replicas without each client re-implementing replication.
- **Live Website Reference**: https://electric-sql.com
- **Source Repository**: https://github.com/electric-sql/electric
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: TypeScript, Elixir, PostgreSQL, Rust, Model Context Protocol
- **Primary Language(s)**: TypeScript, Elixir, Vue, Rust
- **License of the reference repo**: Apache-2.0
- **Frontend**: React — Powers the agents-server-ui dashboard and ships as the @electric-sql/react hooks package for shape subscriptions.; Vue — The electric-sql.com documentation site is built with VitePress, a Vue-based static site generator.
- **Backend & APIs**: Elixir — Implements the Postgres sync engine (shape log, HTTP API, logical replication client) as an OTP release.; Phoenix — Provides an optional, env-var-gated LiveDashboard for real-time monitoring of the running sync service.; Rust — Implements the standalone Durable Streams server, a storage primitive underlying the Electric Agents runtime.
- **Data & persistence**: PostgreSQL — Source-of-truth database Electric replicates from via logical replication; local dev runs it through docker-compose.
- **Infrastructure & deploy**: Docker — The sync service, Durable Streams server, and Agents server each ship a production Dockerfile; docker-compose drives local Postgres.; GitHub Actions — Runs the polyglot CI matrix: Elixir tests, Rust tests, TypeScript checks, and multi-arch Docker/mobile/desktop builds.
- **Tooling, testing & ops**: Model Context Protocol — The agents-mcp package implements MCP registry, transports, and OAuth bridges so agents can call external MCP tools.; TanStack DB — Client apps (agents-mobile) treat synced Postgres shapes as local reactive collections via @tanstack/electric-db-collection.; Electron — Packages the Electric Agents desktop app, built and signed with electron-builder.; Expo — Builds the Electric Agents mobile app for iOS, Android, and web from one React Native codebase.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/electric-sql/electric @ bb39742)
1. **A polyglot core: Elixir sync engine plus a separate Rust streams server**: packages/sync-service/mix.exs defines the Elixir/OTP application (app: :electric) that implements Postgres logical replication and the shape-based HTTP sync API, while packages/durable-streams-rust/Cargo.toml is an unrelated Rust binary (durable-streams-server) providing a Durable Streams storage primitive for the newer Electric Agents layer.
2. **Phoenix LiveDashboard is opt-in and unauthenticated by design**: README.md documents an optional Phoenix LiveDashboard enabled only when ELECTRIC_LIVE_DASHBOARD_PORT is set, with an explicit warning that the endpoint is completely unauthenticated and must be restricted at the network layer in production rather than through application-level auth.
3. **Documentation is a workspace member, not a separate repo**: pnpm-workspace.yaml includes website alongside packages/* and examples/*, and website/package.json (@electric-sql/docs) builds a VitePress site with a custom OpenAPI doc generator (api:build_docs, redocly build-docs against website/electric-api.yaml) that stays versioned with the code it documents.
4. **Electric Agents reuses the sync client across desktop, mobile, and MCP**: packages/agents-desktop (Electron, via electron-builder), packages/agents-mobile (Expo/React Native), and packages/agents-mcp (Model Context Protocol registry and OAuth bridges) all depend on @electric-sql/client and @electric-ax/agents-runtime as workspace packages, so the same Postgres-sync foundation backs every agent surface.
5. **The desktop app does local vector search instead of calling a server**: packages/agents-desktop/package.json depends on better-sqlite3 and sqlite-vec together, giving the Electron app an embedded SQLite database with vector search built in, rather than routing embedding queries to a hosted vector database.
6. **TypeScript client and elixir-client both track the wire-compatible shape protocol**: packages/typescript-client/package.json (@electric-sql/client) and packages/elixir-client/mix.exs (electric_client, an optional dependency on :electric) are maintained as parallel implementations of the same HTTP shape protocol, so both Node/browser and Elixir/Phoenix consumers can subscribe to Postgres shapes without a shared runtime.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
- Structure as a Turborepo monorepo with strict package boundaries:
- `apps/web`: Application UI, routing, layouts, and server endpoints.
- `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
- `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
- `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
- Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
- Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
- Isolate interactive UI state to leaf components. Keep core pages lightweight and performant.
4. **Design System & Aesthetics**:
- Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
- Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
- Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
- Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (PostgreSQL): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.Frequently asked about ElectricSQL
What is ElectricSQL built with?
The core sync engine is an Elixir/OTP application (packages/sync-service) that replicates from Postgres over logical replication; the TypeScript client, React hooks, and the newer Electric Agents desktop/mobile/MCP surfaces are built in TypeScript on top of it.
Does Electric require a special Postgres extension?
No custom extension is declared in the audited manifests; the sync service connects to a standard Postgres instance with logical replication enabled, as shown by .support/docker-compose.yml and .support/postgres.conf used for local development.
What is Electric Agents and how does it relate to the sync engine?
Electric Agents (packages/agents, agents-runtime, agents-server, agents-desktop, agents-mobile, agents-mcp) is an agent platform built on top of the same Postgres shape-sync foundation and a separate Rust Durable Streams server, packaged for CLI, Electron desktop, Expo mobile, and MCP tool integrations.
Can I monitor a running Electric sync service?
Yes, via an optional Phoenix LiveDashboard enabled by setting ELECTRIC_LIVE_DASHBOARD_PORT; README.md warns the dashboard endpoint is unauthenticated and must be restricted with firewall or network-level controls in production.
Is there both an Elixir and a TypeScript client?
Yes. packages/typescript-client (@electric-sql/client) and packages/elixir-client (electric_client, per its mix.exs) are separately maintained clients for the same HTTP shape-sync protocol, alongside framework integrations like @electric-sql/react and @electric-sql/y-electric for Yjs.
One email a month: new deep dives and stack trends
New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.
Similar architectures
- QuestDBClassicTime-Series SQL Database · 20+ PeopleShares Rust · PostgreSQL
- HasuraClassicInstant GraphQL Engine & Unified Data Access · 20+ peopleShares TypeScript · Rust · PostgreSQL
- PostGraphileClassicAutomated GraphQL API Engine · 2-5 PeopleShares TypeScript · PostgreSQL
- SurrealDBClassicMulti-Model Real-Time Database · 20+ PeopleShares Rust
- PenpotClassicDesign & Prototyping Platform · 20+ peopleShares Rust · TypeScript · PostgreSQL
- InfisicalHybridSecret Management · 6-20 peopleShares TypeScript · PostgreSQL · Rust