Quickstart
Let's dive in and start developing with ElectricSQL. First, we'll get the stack setup, then we'll show you the basics of using the system.
If you'd prefer to understand a bit more about the system before jumping into code, start with the Introduction instead.
Setup
Get setup quickly using the create-electric-app
starter app. Or install, run and integrate the components yourself.
- Use the starter
- Install yourself
Make sure you have Docker and Node.js (>=16.11) and then:
npx create-electric-app@latest my-app
Change directory into my-app
and start the backend services. This will use Docker Compose to run Postgres and the Electric sync service:
cd my-app
yarn backend:start
Open another terminal tab, navigate back to the my-app
directory and create the database schema (defined in ./db/migrations
):
yarn db:migrate
Generate your type-safe database client:
yarn client:generate
Start your app:
yarn start
Open localhost:3001 in your web browser. That's it, you're up and running :)
You need to have a Postgres database, run the Electric sync service and develop using the Typescript client.
Postgres database
ElectricSQL works with any Postgres that has logical replication enabled. Crunchy Data provides a good hosted Postgres service (with a free tier and logical replication enabled by default). Or run it yourself, e.g.: using Docker:
docker run \
-e "POSTGRES_PASSWORD=..." \
-c "wal_level=logical" \
-p 5432:5432 \
postgres
See Usage -> Installation -> Postgres for more info.
Electric sync service
Run the Electric sync service using Docker, for example:
docker pull electricsql/electric:latest
docker run \
-e "DATABASE_URL=postgresql://..." \
-e "LOGICAL_PUBLISHER_HOST=..." \
-e "PG_PROXY_PASSWORD=..." \
-e "AUTH_MODE=insecure" \
-p 5133:5133 \
-p 5433:5433 \
-p 65432:65432 \
electricsql/electric
See Usage -> Installation -> Sync service for more info.
Typescript client
Add the electric-sql
library to your web or mobile app, along with an SQLite driver:
yarn add electric-sql
Add a prebuild script to your package.json
to generate a type-safe database client:
"scripts": {
"prebuild": "npx electric-sql generate"
}
See Usage -> Installation -> Typescript client and Integrations -> Drivers for more information.
Usage
The next section goes over the basics of using ElectricSQL. It's a quick summary of the information you'll find in more detail in the Usage guide.
Define your schema
ElectricSQL works on top of a standard Postgres data model.
The generator has set you up with a simple data model defined in ./db/migrations
. To evolve the schema you can add additional files and run yarn db:migrate
again, e.g.:
echo '
CREATE TABLE accounts (
id UUID PRIMARY KEY,
email TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ NOT NULL
);
ALTER TABLE accounts ENABLE ELECTRIC;
' > db/migrations/02-create_foo_table.sql
yarn db:migrate
See Usage -> Data modelling -> Migrations and Integrations -> Backend for more information.
ElectricSQL works on top of a standard Postgres data model.
If you have an existing Postgres-backed application, you can use the data model from that. If you need to create or evolve a data model, you can use raw SQL or any Postgres-compatible migrations tooling.
See Usage -> Data modelling -> Migrations for more information.
Expose data
Expose data using DDLX rules. First, electrify each table you'd like to sync:
ALTER TABLE items
ENABLE ELECTRIC;
Then assign roles and access permissions:
ELECTRIC GRANT ALL
ON items
TO ANYONE;
Authenticate
Authenticate the local app with the replication protocol using a JSON Web Token:
const config = {
auth: {
token: '<your JWT>'
}
}
Instantiate
Wrap your SQLite driver with a type-safe, schema-aware database Client:
import { electrify, ElectricDatabase } from 'electric-sql/wa-sqlite'
import { schema } from './generated/client'
const conn = await ElectricDatabase.init('my.db', '')
const { db } = await electrify(conn, schema, config)
Sync data
Sync data into the local database using Shapes:
const shape = await db.items.sync({
where: {
// ... clauses
},
include: {
// ... relations
}
})
Read data
Bind live data to your components using Live queries:
const { results } = useLiveQuery(
db.items.liveMany({
where: {
// ... filter
},
select: {
// ... columns
},
orderBy: {
// ... sort
},
take: 20
})
)
Either using the Prisma-inspired client or if you prefer just raw SQL:
const { results } = useLiveQuery(
db.liveRaw({
sql: 'SELECT * FROM items where foo = ?',
args: ['bar']
})
)
Write data
Write data directly to the local database using Local writes:
const item = await db.items.create({
data: {
// ... item data
}
})
Writes automatically cause any relevant live queries to update. For example, if you take the following component:
import { genUUID } from 'electric-sql/util'
const MyComponent = () => {
const { db } = useElectric()!
const { results } = useLiveQuery(
db.items.liveMany()
)
const add = async () => (
await db.items.create({
data: {
value: genUUID()
}
})
)
return <List items={results} add={add} />
}
Calling add
will insert a new item into the local database. ElectricSQL will automatically detect and replicate the write. The replication process emits a notification, causing the live query to re-run. This updates the value of the results
state variable, which triggers the component to re-render.
This automatic reactivity works no matter where the write is made — locally, on another device, by another user, or directly into Postgres.
Next steps
Take a look at the Examples, see the Usage and Integrations guides and the API docs.
You can also join the Discord community and star us on GitHub.