End-to-end guide for adding a new synced feature with Electric and TanStack DB. Covers the full journey: design Postgres schema, set REPLICA IDENTITY FULL, define shape, create proxy route, set up TanStack DB collection with electricCollectionOptions, implement optimistic mutations with txid handshake (pg_current_xact_id, awaitTxId), and build live queries with useLiveQuery. Also covers migration from old ElectricSQL (electrify/db pattern does not exist), current API patterns (table as query param not path, handle not shape_id). Load when building a new feature from scratch.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
End-to-end guide for adding a new synced feature with Electric and TanStack DB. Covers the full journey: design Postgres schema, set REPLICA IDENTITY FULL, define shape, create proxy route, set up TanStack DB collection with electricCollectionOptions, implement optimistic mutations with txid handshake (pg_current_xact_id, awaitTxId), and build live queries with useLiveQuery. Also covers migration from old ElectricSQL (electrify/db pattern does not exist), current API patterns (table as query param not path, handle not shape_id). Load when building a new feature from scratch.
This skill builds on electric-shapes, electric-proxy-auth, and electric-schema-shapes. Read those first.
Electric — New Feature End-to-End
Setup
0. Start Electric locally
# docker-compose.ymlservices:postgres:image:postgres:17-alpineenvironment:POSTGRES_DB:electricPOSTGRES_USER:postgresPOSTGRES_PASSWORD:passwordports:-'54321:5432'tmpfs:-/tmpcommand:--c-listen_addresses=*--c-wal_level=logicalelectric:image:electricsql/electric:latestenvironment:DATABASE_URL:postgresql://postgres:password@postgres:5432/electric?sslmode=disableELECTRIC_INSECURE:true# Dev only — use ELECTRIC_SECRET in productionports:-'3000:3000'depends_on:-postgres
docker compose up -d
1. Create Postgres table
CREATE TABLE todos (
id UUID PRIMARY KEY gen_random_uuid(),
user_id UUID ,
text TEXT ,
completed ,
created_at TIMESTAMPTZ now()
);
todos REPLICA ;
DEFAULT
NOT NULL
NOT NULL
BOOLEAN
DEFAULT
false
DEFAULT
ALTER TABLE
IDENTITY
FULL
2. Create proxy route
The proxy forwards Electric protocol params and injects server-side secrets. Use your framework's server route pattern (TanStack Start, Next.js API route, Express, etc.).
If using Drizzle, generate schemas from your table definitions with createSelectSchema(todosTable) from drizzle-zod.
4. Create mutation endpoint
Implement your write endpoint using your framework's server function or API route. The endpoint must return { txid } from the same transaction as the mutation.
// Example: server function that inserts and returns txidasyncfunctioncreateTodo(todo: { text: string; user_id: string }) {
const client = await pool.connect()
try {
await client.query('BEGIN')
const result = await client.query(
'INSERT INTO todos (text, user_id) VALUES ($1, $2) RETURNING id',
[todo.text, todo.user_id]
)
const txResult = await client.query(
'SELECT pg_current_xact_id()::xid::text AS txid'
)
await client.query('COMMIT')
return { id: result.rows[0].id, txid: Number(txResult.rows[0].txid) }
} finally {
client.release()
}
}
HIGH Removing parsers because the TanStack DB schema handles types
Wrong:
// "My Zod schema has z.coerce.date() so I don't need a parser"electricCollectionOptions({
schema: z.object({ created_at: z.coerce.date() }),
shapeOptions: { url: '/api/todos' }, // No parser!
})
Electric's sync path delivers data directly into the collection store, bypassing the TanStack DB schema. The parser in shapeOptions handles type coercion on the sync path; the schema handles the mutation path. You need both. Without the parser, timestamptz arrives as a string and getTime() or other Date methods will fail at runtime.
CRITICAL Using old electrify() bidirectional sync API
Old ElectricSQL (v0.x) had bidirectional SQLite sync. Current Electric is read-only. Writes go through your API endpoint and are reconciled via txid handshake.
See also: electric-orm/SKILL.md — Getting txid from ORM transactions.
See also: electric-proxy-auth/SKILL.md — E2E feature journey includes setting up proxy routes.