/electric_dart

A Dart implementation for Electric (electric-sql.com).

Primary LanguageDartApache License 2.0Apache-2.0

Tests E2E

pub package pub package pub package

Electric Dart

🛠️ WORK IN PROGRESS 🛠️

Electric is currently in public alpha phase, and the Dart client is currently being developed introducing the new features from the official client as they come out. For development updates make sure to check out the official ElectricSQL Discord server, as well as the official Javascript client


Unofficial Dart client implementation for Electric.

Client based on the Typescript client from the clients/typescript subfolder from electric git repository

Reference implementation:

  • NPM package.
  • Version v0.9.1
  • Commit: d5510e9acd6fed77a1ae35cebccbb34ccd2d8f2b

What's Electric?

ElectricSQL is a local-first software platform. Use it to build super fast, collaborative, offline-capable cross-platform apps directly on Postgres. Introduction & Live Demos

Run the Todos example

This is a simple Todos app which can sync across all the platforms supported by Flutter (iOS, Android, Web, Windows, macOS and Linux).

Instructions

Electric Flutter

Quickstart

Quickstart to integrate Electric into your own Flutter app.

Usage

Instantiate

You can electrify a drift database or a sqlite3 database.

import 'package:electricsql/electricsql.dart';
import 'package:electricsql_flutter/drivers/drift.dart'; // or sqlite3.dart

// This would be the Drift database
AppDatabase db;

final electric = await electrify<AppDatabase>(
    dbName: '<db_name>',
    db: db,
    // Bundled migrations. This variable is autogenerated using 
    // `dart run electricsql_cli generate`
    migrations: kElectricMigrations,
    config: ElectricConfig(
        // Electric service URL
        url: 'http://<ip>:5133',
        auth: AuthConfig(
            // https://electric-sql.com/docs/usage/auth
            // You can use the functions `insecureAuthToken` or `secureAuthToken` to generate one
            token: '<your JWT>',
        ),
        // logger: LoggerConfig(
        //     level: Level.debug, // in production you can use Logger.off
        // ),
    ),
);

Sync data

Sync data into the local database. This only needs to be called once. Shapes

final shape = await electric.syncTables([
    'todos',
])

Read data

Bind live data to the widgets. This can be possible when using drift + its Stream queries.

AppDatabase db;
// Since we've electrified it, we can now use the original database instance normally.
final Stream<List<Todo>> todosStream = db.select(db.todos).watch();

// Stateful Widget + initState
todosStream.listen((liveTodos) {
    setState(() => todos = liveTodos.toList());
});

// StreamBuilder
StreamBuilder<List<Todo>>(
    stream: todosStream,
    builder: (context, snapshot) {
        ...
    },
);

Write data

You can use the original database instance normally so you don't need to change your database code at all. The data will be synced automatically, even raw SQL statements.

AppDatabase db;
await db.into(db.todos).insert(TodosCompanion(
    title: Value('My todo'),
    completed: Value(false),
));

// Or raw SQL
await db.customInsert(
    'INSERT INTO todos (title, completed) VALUES (?, ?)', 
    variables: [Variable('My todo'), Variable(false)],
    updates: {db.todos}, // This will notify stream queries to rebuild the widget
);

This automatic reactivity works no matter where the write is made — locally, on another device, by another user, or directly into Postgres.

More about ElectricSQL

Check out the official docs from ElectricSQL here to look at live demos, API docs and integrations.


Development instructions for maintainers and contributors

Dart 3.x and Melos required

dart pub global activate melos

Bootstrap the workspace

melos bs

Generate the Protobuf code

Install the protoc_plugin Dart package.

dart pub global activate protoc_plugin

To generate the code

melos generate_proto

Run the tests

melos test:all