Dart Functions
Write serverless functions in Dart — the same language as your Flutter app. Deploy and invoke from the dashboard or directly from the SDK.
Available runtimes
denoTypeScript / JavaScript
Default runtime. Full Deno 2 API, npm compatible.
dartDart
Flutter-native runtime. Write functions in the same language as your app.
Writing a Dart function
A Dart function must export an async handler function that accepts a context map and returns a map.
Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
// Access request body
final body = ctx['request']['body'] as Map<String, dynamic>? ?? {};
final name = body['name'] as String? ?? 'World';
// Access database
final db = ctx['db'] as Map<String, dynamic>;
final records = await (db['find'] as Function)('users', {'active': true});
return {
'message': 'Hello, $name!',
'user_count': (records['records'] as List?)?.length ?? 0,
};
}Function signature
handler with the signature Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx).Using pub.dev packages
Dart functions can declare third-party dependencies via a pubspec.yaml file. Koolbase resolves them server-side at deploy time, caches the result, and makes packages available to your function's import 'package:...' statements.
Example: a function that imports package:crypto to compute a SHA-256 hash.
import 'package:crypto/crypto.dart';
import 'dart:convert';
export const metadata = {
title: 'Dart Runtime — Functions',
description: 'Write serverless functions in Dart — the same language as your Flutter app. Deploy and invoke from the dashboard or directly from the SDK.',
}
Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
final input = ctx['request']?['body']?['text'] as String? ?? 'hello';
final digest = sha256.convert(utf8.encode(input));
return {'sha256': digest.toString()};
}name: hash_function
environment:
sdk: ^3.0.0
dependencies:
crypto: ^3.0.5How resolution works
When you deploy a Dart function with a pubspec:
- The pubspec content is hashed (SHA-256).
- If that hash has been resolved before — across any project — the cached resolution is reused. Near-instant.
- If new,
dart pub getruns server-side with a 3-minute timeout. The resolvedpubspec.lockis stored on the function record. - Two simultaneous deploys with the same pubspec serialize through a per-hash mutex — only one resolution runs.
CLI deploy with auto-detection
When deploying via the CLI, if a pubspec.yaml sits next to your source file, it's uploaded automatically:
$ ls
hash.dart pubspec.yaml
$ koolbase deploy hash-fn --file hash.dart --project proj_abc
Found pubspec.yaml — packages will be resolved server-side.
Deploying hash-fn (dart runtime)...
Deployed hash-fn v1
Runtime: dart
Timeout: 10000ms
Project: proj_abc
Pubspec: uploadedDashboard deploy
The deploy modal in the dashboard includes a runtime selector. Choosing Dart reveals an optional pubspec.yaml editor below the code editor. After deploy, the function detail view's Code tab includes a file switcher between index.dart and pubspec.yaml.
Requirements & limits
- Must include
nameandenvironment.sdkfields. - Maximum pubspec size: 64 KB.
- Resolved dependencies on disk must not exceed 500 MB.
- Resolution timeout: 3 minutes for first-time resolution; cache hits are instant.
- Pubspec is opt-in — Dart functions without one continue to run with
dart:*built-ins only.
Not yet supported (v2)
- Multi-line imports in your source file (rare in practice; use single-line form).
- Private or custom pub registries.
- Vulnerability scanning of declared dependencies.
For deeper coverage — failure modes, AES-GCM encryption, HMAC webhook signature verification, function version locking, and deploying via the SDK API — see the Dart Dependencies guide.
Context object
The ctx map contains everything your function needs:
Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
// Request data
final request = ctx['request'] as Map<String, dynamic>;
final body = request['body'] as Map<String, dynamic>? ?? {};
final headers = request['headers'] as Map<String, dynamic>? ?? {};
// Database helpers
final db = ctx['db'] as Map<String, dynamic>;
// Insert a record
final record = await (db['insert'] as Function)('posts', {
'title': 'Hello from Dart',
'published': true,
});
// Query records
final posts = await (db['find'] as Function)('posts', {'published': true}, 10);
// Update a record
await (db['update'] as Function)(record['id'], {'title': 'Updated'});
// Delete a record
await (db['delete'] as Function)(record['id']);
return {'ok': true};
}Deploy from dashboard
Go to your project in app.koolbase.com → Functions → New Function. Select Dart as the runtime, paste your code, and click Deploy.
Deploy from Flutter SDK
Deploy functions programmatically using the Flutter SDK. Requires an authenticated user session.
await Koolbase.functions.deploy(
projectId: 'your-project-id',
name: 'send-welcome-email',
runtime: FunctionRuntime.dart,
timeoutMs: 15000,
code: r'''
Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
final body = ctx['request']['body'] as Map<String, dynamic>? ?? {};
final email = body['email'] as String?;
// Send email logic here
return {'sent': true, 'to': email};
}
''',
);Invoke from Flutter
Invoke any function regardless of runtime — the invoke() API is the same for both Deno and Dart functions.
final result = await Koolbase.functions.invoke(
'send-welcome-email',
body: {
'email': '[email protected]',
'name': 'Kennedy',
},
);
if (result.success) {
print(result.data); // {'sent': true, 'to': '[email protected]'}
}Invoke via REST API
curl -X POST https://api.koolbase.com/v1/sdk/functions/send-welcome-email \
-H "Content-Type: application/json" \
-H "x-api-key: pk_live_your_key" \
-d '{"body": {"email": "[email protected]"}}'