Skip to content
potluckdb

Flutter

Electron · Tauri · Qt · Flutter · React Native · Capacitor and Ionic · .NET MAUI

Flutter applications use the Dart package on supported desktop and mobile targets. Its build hook downloads the requested target’s C SDK archive and verifies its digest. It registers the prebuilt runtime and storage libraries as bundled dynamic code assets. It never compiles or relinks them.

The Dart installation page applies. This page adds phone-specific information.

Flutter 3.44.9 or newer.

ApplicationPlatforms
DesktopmacOS, Linux or Windows
MobileiOS 15 or newer, Android 13 (API level 33) or newer

Build mobile applications from a host with the platform toolchain that Flutter requires.

The Flutter column of the compatibility matrix, packaged for Flutter. Each release runs the quickstart on the platforms in this table. Other platforms have no verification for this integration.

PlatformTargetsPackage
macOSmacos-arm64, macos-x86_64potluckdb
Linuxlinux-x86_64-gnu, linux-arm64-gnupotluckdb
Windowswindows-x86_64, windows-arm64potluckdb
iOS and iPadOSapple-mobile-device-arm64, apple-mobile-simulator-arm64, apple-mobile-simulator-x86_64potluckdb
Androidandroid-arm64-v8a, android-x86_64potluckdb

Create the notes application. Its Android package is com.example.notes.

Terminal window
flutter create notes
cd notes
flutter pub add potluckdb path_provider

The package registers native code with Flutter’s build. On Android, replace android/app/src/main/kotlin/com/example/notes/MainActivity.kt with MainActivity.kt from the Quickstart section. It names the configuration directory before the engine starts. In android/app/build.gradle.kts, replace minSdk = flutter.minSdkVersion with minSdk = 33, as the Android page explains.

potluckdb 0.1.0 supplies Android libraries only for arm64-v8a and x86_64. Flutter names these targets android-arm64 and android-x64. Build an APK for those targets with this command.

Terminal window
flutter build apk --target-platform android-arm64,android-x64

flutter run builds only the connected device’s target.

path_provider supplies the application support directory where the quickstart writes.

Replace lib/main.dart with main.dart below. The application opens the database under its application support directory, inserts a note and lists the table in a widget. Run flutter run on any connected device. It prints quickstart: ok to the log once the database opens.

On Android, the activity below sets the configuration directory under the application’s files directory before the engine starts, because Android sets no home directory.

main.dart
// potluckdb in a Flutter application: one database under the application support directory,
// on the desktop, on iOS and on Android from the same file.
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:potluckdb/potluckdb.dart';
void main() => runApp(const NotesApp());
class NotesApp extends StatelessWidget {
const NotesApp({super.key});
@override
Widget build(BuildContext context) => const MaterialApp(home: NotesPage());
}
class NotesPage extends StatefulWidget {
const NotesPage({super.key});
@override
State<NotesPage> createState() => _NotesPageState();
}
class _NotesPageState extends State<NotesPage> {
Remote? _remote;
Database? _db;
List<Map<String, Object?>> _notes = const [];
@override
void initState() {
super.initState();
_open(); // once, for the lifetime of the page; a rebuild never reopens the database
}
Future<void> _open() async {
final support = await getApplicationSupportDirectory();
final remote = Remote.fromDirectory('${support.path}/remote'); // a bucket replaces this in production; see the Dart installation page
final db = open('${support.path}/notes.potluckdb', remote: remote);
db.execute('CREATE TABLE IF NOT EXISTS note(id INTEGER PRIMARY KEY, body TEXT NOT NULL)');
db.execute('INSERT INTO note(body) VALUES(?)', Bindings.positional(['buy milk']));
debugPrint('quickstart: ok');
if (!mounted) {
db.close();
remote.close();
return;
}
setState(() {
_remote = remote;
_db = db;
_notes = [
for (final row in db.query('SELECT id, body FROM note ORDER BY id')) {'id': row['id'], 'body': row['body']},
];
});
}
@override
void dispose() {
_db?.close();
_remote?.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Notes')),
body: _db == null
? const Center(child: CircularProgressIndicator())
: ListView(
children: [for (final note in _notes) ListTile(title: Text('${note['id']}: ${note['body']}'))],
),
);
}
}
MainActivity.kt
package com.example.notes
import android.os.Bundle
import android.system.Os
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Android sets no home directory, so the licensing policy has
// nowhere to keep the trial anchor unless the application names its
// configuration directory. Before super.onCreate, because the engine
// starts there and the first open can follow at once. `false` keeps
// a value the application already set.
Os.setenv("POTLUCKDB_CONFIG_DIR", "$filesDir/configuration", false)
super.onCreate(savedInstanceState)
}
}

Each release runs this application on the listed desktop platforms, the iOS simulator, and the Android emulator to verify stored notes.