Skip to Content

Setup & Quick Start

Status: This SDK is in alpha and is subject to change between releases.

The Dart/Flutter SDK is kalam_link (pub package name: kalam_link). It is a thin Dart layer over a Rust core bridged via Flutter Rust Bridge.

If you need Topic consumers / ACK worker APIs, those are currently documented in the TypeScript SDK. The Dart SDK currently focuses on app-client query + subscription flows.

Install

Add to pubspec.yaml:

dependencies: kalam_link: ^0.1.2

Then fetch dependencies:

flutter pub get # or dart pub get

Supported platforms (per plugin configuration): Android, iOS, macOS, Windows, Linux.

If you’re evaluating web builds: check the current package release notes first. Flutter FFI plugins may require additional setup for web/WASM targets.

Required initialization

You must call KalamClient.init() exactly once at app startup, before any other SDK call.

Flutter:

import 'package:flutter/widgets.dart'; import 'package:kalam_link/kalam_link.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await KalamClient.init(); // runApp(const MyApp()); }

Pure Dart (non-Flutter):

import 'package:kalam_link/kalam_link.dart'; Future<void> main() async { await KalamClient.init(); }

Create a client

KalamClient.connect(...) constructs a client handle. Prefer authProvider for expiring tokens.

import 'package:kalam_link/kalam_link.dart'; final client = await KalamClient.connect( url: 'http://localhost:8080', authProvider: () async => Auth.jwt(await getJwtFromSecureStorage()), );

If you don’t have auth enabled (for example on a local server in bypass mode), you can omit auth entirely:

final client = await KalamClient.connect(url: 'http://localhost:8080');

First query

final result = await client.query('SELECT CURRENT_USER()'); if (!result.success) { throw StateError('Query failed: ${result.error}'); } print(result.toMaps().first);

QueryResponse also includes timing metadata (tookMs) and can contain multiple result sets when you send multiple statements.

First live subscription

subscribe(...) returns a Stream<ChangeEvent>.

final stream = client.subscribe('SELECT * FROM app.messages ORDER BY created_at DESC LIMIT 50'); final sub = stream.listen((event) { switch (event) { case AckEvent(:final subscriptionId): print('Subscribed: $subscriptionId'); case InsertEvent(:final row): print('New row: $row'); case SubscriptionError(:final code, :final message): print('Error [$code]: $message'); default: break; } }); // Later await sub.cancel();

Cleanup

await client.dispose();

Next

Last updated on