Quickstart guide
In this guide we’re going to get you up and running with ElectricSQL.
You can choose two paths. The default path (that we recommend) is to start with a local-only app and walk through the steps to electrify it, so it becomes local-first. Alternatively, you can take the shortcut path to fire up an existing ElectricSQL example app.
In both cases, we demonstrate realtime cloud sync and active-active replication between Postgres in the cloud and SQLite in the browser.
You don't need to run any backend services but you do need to use the command line, clone a git repo and have Node.js installed. You also need to sign up and create an account.
Clone the examples repo, and navigate to the quickstart
project, a minimalist, local-only React + SQL.js web application:
git clone https://github.com/electric-sql/examples
cd examples/quickstart
Install the dependencies:
yarn
Build and run:
yarn start
This should open localhost:3001 in your web browser. You should be able to add and clear items. Note that if you refresh the page, your items are lost (because this example is configured initially to store items in an in-memory SQLite database; there’s no local or cloud persistence – yet).
Electrification
We’re now going to walk through the steps of electrifying your app so it becomes local-first with durability, realtime cloud sync and active-active replication between Postgres in the cloud and SQLite in the browser.
Install dependencies
Install the electric-sql
client library:
yarn add electric-sql
Because we’re electrifying a web application you also need to install absurd-sql for local persistence [note that we support both absurd-sql
and wa-sqlite
– see the Web drivers docs for more info]:
yarn add @aphro/absurd-sql@0.0.53
absurd-sql needs to run in a Web Worker, so whilst you’re at it, also uncomment the source of src/worker.js
to start up the messaging interface between your code and the worker:
import { ElectricWorker } from 'electric-sql/browser'
ElectricWorker.start(self);
Great! That’s the dependencies sorted. Now let’s get your cloud sync service setup.
Setup cloud sync
If you haven’t done so already, now’s the time to sign up to ElectricSQL. Follow the instructions to create a new app. After the system provisions the infrastructure, you’ll be able to view the connection details for your sync service and Postgres database:
Copy these somewhere safe (like a password manager). You’re now in position to define your database schema.
Define your database schema
With ElectricSQL, you define your database schema by writing migrations and then apply the same migrations to your local app and cloud Postgres. This ensures that they both use the same database schema. You do this using our command line interface (CLI) tool, which provides commands to generate migrations, bundle them into your app and upload them to your cloud service.
Install the CLI. For example using Homebrew, or see the install guide for more options:
brew install electric-sql/tap/electric
Login on the command line (using the email and password you signed up with, replacing EMAIL
with your email address):
electric auth login EMAIL
Make sure you’re in the examples/quickstart
folder and run (replacing APP
with the app
identifier from your sync service connection details you copied earlier):
electric init APP
This creates an ./electric.json
config file and initialises a ./migrations
folder.
Create a migration:
electric migrations new "create items"
This generates a subfolder at ./migrations/*_create_items/
containing a migration.sql
file. Open this file in your text editor and paste in:
CREATE TABLE IF NOT EXISTS items (
value TEXT PRIMARY KEY NOT NULL
) WITHOUT ROWID;
This is a very simple migration creating the
items
table used by your app. For more complex schemas, you can write multiple DDL statements in the samemigration.sql
file and you can generate multiple migrations. See the migrations guide for more details and for the current limitations on schema design.
Build your migrations:
electric build
Upload to your cloud service:
electric sync
Check if the migrations were applied successfully:
electric migrations list
------ Electric SQL Migrations ------
20221228_192139_608_init default: applied
20221228_192910_066_create_items default: applied
You can also check the schema of your cloud Postgres directly using the PSQL connection string you copied from the console earlier, e.g.:
psql "postgresql://..."
...
electric=> \d
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | items | table | postgres
(1 row)
Congratulations! You’ve setup your sync service and database migrations. You’re now ready to electrify your app!
Electrify your app
Open src/Example.tsx
. Start by uncommenting the electric-sql
imports:
import { ElectrifiedDatabase, initElectricSqlJs } from 'electric-sql/browser'
import { ElectricProvider, useElectric, useElectricQuery } from 'electric-sql/react'
Import your application config and your bundled migrations:
import config from '../.electric/@config'
Enable the absurd-sql web worker:
const worker = new Worker('./worker.js', { type: 'module' });
In the Example
component, edit the init
function inside useEffect
to instantiate and assign an electrified database connection:
useEffect(() => {
const init = async () => {
const SQL = await initElectricSqlJs(worker, locateOpts)
const electrified = await SQL.openDatabase('example.db', config)
setDb(electrified)
}
init()
}, [])
Wrap the component hierarchy in an ElectricProvider
context provider:
return (
<ElectricProvider db={db}>
<ExampleComponent />
</ElectricProvider>
)
Your components can now:
- use the
useElectric
hook to get the electrified database connection and use it to make arbitrary reads and writes; and - use the
useElectricQuery
hook to bind the results of a live, reactive query to state variables
Update ExampleComponent
to use these hooks. The result should look like this:
const ExampleComponent = () => {
const db = useElectric() as ElectrifiedDatabase
const { results } = useElectricQuery('SELECT value FROM items', [])
const addItem = () => {
db.run('INSERT INTO items VALUES(?)', [crypto.randomUUID()])
}
const clearItems = () => {
db.run('DELETE FROM items where true')
}
return (
// ... markup here is unchanged
)
}
That’s it! Your local-only app is now local-first, with built-in reactive, realtime cloud sync and both local and durable cloud persistence.
Clone the examples repo, and navigate to the web
project, an existing ElectricSQL example web application using React and SQL.js:
git clone https://github.com/electric-sql/examples
cd examples/web
Install the dependencies:
yarn
Testing the sync
The simplest way to test the sync is to open two different browsers side by side (different browsers so they use a different local SQLite database). Make sure the app is running:
yarn start
Open localhost:3001 in both browser windows. Data changes in one window will be automatically detected in the other. If you refresh the page, your items will still be there.
You can also monitor the changes in your cloud Postgres, using the PSQL connection string you copied from your ElectricSQL console into your password manager earlier e.g.:
psql "postgresql://..."
...
electric=> select * from items; \watch 1.0
Open another terminal window and insert items directly in Postgres and watch them appear in both of your browser windows and the watched query, e.g.:
psql "postgresql://..."
...
electric=> insert into items values (gen_random_uuid()) returning value;
You should see something like this. The apps are running locally. Changes made using the buttons are written to the local, embedded SQLite first. They’re then replicated in the background via the cloud to other devices and the cloud Postgres. Changes to the Postgres are replicated to all devices:
For bonus points, use a tool like Ngrok to expose your local service on a public URL and then open the Forwarding
address (that starts with https://
) in your mobile/cell phone browser:
ngrok http 3001 --bind-tls true
Note that Ngrok can be quite laggy, depending mainly on your Internet connection. Test your app more realistically by publishing it to a free hosting service like Render.
For even more bonus points, fire up one of the Expo or React Native examples, using the same app
ID. Watch changes sync in realtime with transactional causal+ consistency across multiple web browsers, a native mobile app and cloud Postgres.
Next steps
Continue with more detailed guides on:
See the example applications on GitHub.