Skip to content
AndreFrelicotPublic

About

Pure Dart SDK for Convex — real-time sync, type-safe codegen, Flutter widgets, and offline support

Topics

Resources

Code of conduct

Contributing

Stars

14 stars

Watchers

0 watching

Forks

Repository files navigation

Dartvex Logo

Dartvex

Dart packages for Convex — pure-Dart realtime sync, type-safe codegen, Flutter widgets, and offline support.

CI License: MIT Dart packages pub.dev publisher: andrefrelicot.dev

Dartvex Flutter demo — real-time chats running on iOS and macOS


Why Dartvex?

  • Pure-Dart core — the dartvex client has no Rust FFI or Flutter dependency; companion packages add Flutter/native integrations where noted.
  • Type-safe codegen — Generate Dart bindings from your Convex schema. Catch errors at compile time.
  • Flutter widgets — ConvexProvider, ConvexQuery, ConvexMutation and more for reactive UI.
  • Offline capable — SQLite query cache and mutation queue with optimistic updates.
  • Multi-platform — iOS, Android, web, macOS, Linux, Windows.

Web support covers the core realtime client, auth, storage URL resolution, and Flutter query/mutation widgets. Disk-backed file/image cache and offline image fallback are native-only because they rely on dart:io and local filesystem storage.

Quick Start

import 'package:dartvex/dartvex.dart';

void main() async {
  final client = ConvexClient('https://your-deployment.convex.cloud');

  // Subscribe to a query
  final sub = client.subscribe('messages:list', {});
  sub.stream.listen((result) {
    if (result case QuerySuccess(:final value)) {
      print('Messages: $value');
    }
  });

  // Run a mutation
  await client.mutate('messages:send', {'body': 'Hello from Dart!'});
}

Packages

Package Description Version
dartvex Core client — WebSocket sync, subscriptions, auth 0.2.0
dartvex_flutter Flutter widgets — Provider, Query, Mutation 0.2.0
dartvex_codegen CLI code generator — type-safe Dart bindings from schema 0.2.0
dartvex_local Offline support — SQLite cache, mutation queue 0.2.0
dartvex_auth_better Better Auth adapter 0.2.0

Agent Skills

This repo ships Agent Skills that teach AI coding agents (Claude Code, Cursor, Copilot, Codex, …) how to build apps with Dartvex:

npx skills add AndreFrelicot/dartvex
Skill Use it to
dartvex Route any Dartvex task to the right skill
dartvex-quickstart Connect a Dart/Flutter app to Convex
dartvex-generate-bindings Generate a type-safe API with dartvex_codegen
dartvex-setup-auth Better Auth login, session restore, manual JWT auth
dartvex-build-realtime-ui Live queries, optimistic mutations, pagination widgets
dartvex-setup-offline SQLite cache and offline mutation queue
dartvex-upload-files Convex file storage and cached image widgets
dartvex-test-with-fakes Widget tests with FakeConvexClient

They pair with the official get-convex/agent-skills (backend authoring) and flutter/skills (general Flutter UI).

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                                  Your App                                   │
├────────────────────────┬──────────────────────┬─────────────────────────────┤
│ dartvex_flutter        │ dartvex_local        │ dartvex_auth_*              │
│ (widgets)              │ (offline)            │ (better auth adapters)      │
├────────────────────────┴──────────────────────┴─────────────────────────────┤
│                                  dartvex                                    │
│                     (core client + WebSocket sync)                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                              Convex Backend                                 │
└─────────────────────────────────────────────────────────────────────────────┘

                              dartvex_codegen
                   (generates typed bindings from schema)

Installation

1. Add dependencies

# pubspec.yaml
dependencies:
  dartvex: ^0.2.0
  dartvex_flutter: ^0.2.0  # If using Flutter

dev_dependencies:
  dartvex_codegen: ^0.2.0  # For code generation

2. Configure your client

import 'package:dartvex/dartvex.dart';
import 'package:dartvex_flutter/dartvex_flutter.dart';

final client = ConvexClient('https://your-deployment.convex.cloud');
final runtime = ConvexClientRuntime(client);

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ConvexProvider(
      client: runtime,
      child: MaterialApp(home: HomePage()),
    );
  }
}

3. Generate type-safe bindings

dart run dartvex_codegen generate \
  --spec-file path/to/function_spec.json \
  --output lib/convex_api/

4. Use in your widgets

ConvexQuery<List<Message>>(
  query: 'messages:list',
  args: const {},
  decode: (v) => [
    for (final item in v as List) Message.fromJson(item as Map<String, dynamic>),
  ],
  builder: (context, snapshot) {
    if (snapshot.isLoading) return const CircularProgressIndicator();
    if (snapshot.hasError) return Text('Error: ${snapshot.error}');
    final messages = snapshot.data ?? const <Message>[];
    return ListView(children: messages.map(MessageTile.new).toList());
  },
)

Usage Examples

Queries

final sub = client.subscribe('tasks:list', {'projectId': 'abc123'});
sub.stream.listen((result) {
  if (result case QuerySuccess(:final value)) {
    print('Tasks: $value');
  }
});

Mutations

await client.mutate('tasks:create', {
  'title': 'Ship dartvex',
  'projectId': 'abc123',
});

Actions

final result = await client.action('ai:summarize', {
  'documentId': 'doc456',
});

Authentication

final authClient = BetterAuthClient(
  baseUrl: 'https://your-deployment.convex.cloud',
);
final provider = ConvexBetterAuthProvider(client: authClient)
  ..email = 'user@example.com'
  ..password = 'securePassword';

final client = ConvexClient('https://your-deployment.convex.cloud');
final authedClient = client.withAuth(provider);
await authedClient.login();

Offline Support

import 'package:dartvex_local/dartvex_local.dart';

final remoteClient = ConvexClient('https://your-deployment.convex.cloud');
final store = await SqliteLocalStore.open('my_app.sqlite');
final localClient = await ConvexLocalClient.open(
  client: remoteClient,
  config: LocalClientConfig(
    cacheStorage: store,
    queueStorage: store,
    disposeRemoteClient: true,
  ),
);

// Queries served from cache when offline
// Mutations queued and synced when back online

The local-first query cache and mutation queue use SQLite and are intended for native targets. For files on web, resolve signed Convex storage URLs and render them directly; disk-backed file cache/offline image fallback is not supported on web in this release.

Contributing

See CONTRIBUTING.md for guidelines.

License

MIT License - see LICENSE for details.

About

Pure Dart SDK for Convex — real-time sync, type-safe codegen, Flutter widgets, and offline support

Topics

Resources

Code of conduct

Contributing

Stars

14 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages