Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ElectricSQL + TanStack Store + Phoenix Starter

This starter shows a pragmatic, production-friendly pattern that pairs Electric’s read sync with canonical server writes.

Note: This project uses basic TanStack Store today, not TanStackDB. A future version of the project will adopt TanStackDB.

  • Read path (client): ElectricSQL HTTP Shapes → TanStack Store for a reactive collection.
  • Write path (server): Phoenix 1.8.1 JSON API writes to Postgres. Electric immediately streams the resulting changes to all clients via Shapes (no manual re-fetch).

What’s included

  • server/ — Phoenix API: POST /api/comments (plus optional bulk), Ecto schema + migration for comments.
  • client/ — Vite + React + TypeScript app that subscribes to Electric Shapes and keeps a client store in sync.
  • docker-compose.yml — Postgres (logical replication) + Electric service; optional dev services for server/client.
  • Dockerfiles — server/Dockerfile, client/Dockerfile for dev and prod builds.

Pinned versions

  • Phoenix 1.8.1, Ecto 3.13.2, ecto_sql 3.13.2, postgrex 0.21.1

How it fits together

  • Electric’s HTTP API is designed for Shape sync (initial + live via offsets). Writes go through your backend; Electric fans out changes to clients.
  • TanStack Store gives a simple, reactive in-memory collection with clean update semantics.

Develop with Docker (recommended)

Run all services in containers with hot reload and no local Elixir/Node:

# Start infra (Postgres + Electric)
docker compose up -d postgres electric

# Start app services (dev; code is volume-mounted for live reload)
docker compose up --build server client

Open these in your browser:

Notes

  • DB is created and migrated automatically by the server dev image on startup.
  • CORS is enabled on the server for http://localhost:5173.
  • The client is built with VITE_API_URL=http://localhost:4000 and VITE_ELECTRIC_URL=http://localhost:3000, so it talks to Electric directly for shapes. If you prefer to proxy via the API, set VITE_ELECTRIC_URL to http://localhost:4000 and add a /v1/shape proxy route.

Endpoints

  • POST /api/comments — body { id, post_id, author, body } → inserts row and returns JSON (with created_at).
  • POST /api/comments/bulk — optional batch insert { comments: [ ... ] }.

Local (non-Docker) alternative

If you’d rather run server and client on your host machine:

  1. Start Postgres + Electric (still via Docker):
docker compose up -d postgres electric
  1. Server:
cd server
mix deps.get
mix ecto.create
mix ecto.migrate
mix phx.server
  1. Client:
cd client
cp .env.example .env.local
pnpm i   # or npm i / yarn
pnpm dev

Configuration

  • Client: VITE_ELECTRIC_URL, VITE_API_URL (set in client/.env.local for local runs; compose sets them for container dev).
  • Server: DATABASE_URL env (defaults to postgres://postgres:postgres@localhost:5432/electric_dev in dev). Binds on 0.0.0.0 and respects PORT.

Build images for CI/Prod

Server (release):

docker build -t myorg/server:prod -f server/Dockerfile --target prod server

Client (static):

docker build -t myorg/client:prod -f client/Dockerfile --target prod client

Run the built images:

docker run -p 4000:4000 -e PHX_SERVER=true -e DATABASE_URL=postgres://postgres:postgres@host.docker.internal:5432/electric_dev myorg/server:prod
docker run -p 8080:80 myorg/client:prod

About

A playground where I learn about ElectricSQL, Elixir Phoenix and Tanstack. The idea is to make a great multi tenant starter.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages