Dart Function Dependencies
Declare pub.dev packages your Dart Function needs via pubspec.yaml. Koolbase resolves dependencies at deploy time, caches the result, and runs your Function against the resolved package environment.
Why this exists
Production Dart Functions need access to real cryptography, HTTP clients, JWT libraries, payment SDKs, webhook signature verifiers, and other ecosystem packages. Koolbase supports per-function dependency declaration so you can use any pub.dev package — not just dart:* core libraries.
Each function version locks in its resolved dependency set. Redeploying with a different pubspec.yaml creates a new function version with its own dependency context. Existing versions continue running against the dependencies they were deployed with.
Declaring dependencies
Send a pubspec field alongside your function code at deploy time. The minimum shape requires name and environment.sdk:
name: my_function
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
crypto: ^3.0.0
cryptography: ^2.7.0
http: ^1.0.0Required fields
name— any valid pub.dev package name; doesn't need to match the function nameenvironment.sdk— Dart SDK constraint;'>=3.0.0 <4.0.0'is a good default
Constraints
- Maximum
pubspec.yamlsize: 64KB - Only the Dart runtime supports
pubspec.yaml— sending it with a Deno function returns 400 - Functions with no
pubspec.yamlstill work but can only usedart:*core libraries
The standard profile
Most Functions reach for the same handful of packages. Rather than declare them every time, deploy with the dart-standard runtime and Koolbase merges a curated set into your pubspec:
crypto: 3.0.5 # hashing / HMAC
cryptography: 2.7.0 # encryption / signing / key derivation
http: 1.2.2 # outbound APIs / webhooks
uuid: 4.5.1 # identifiers / idempotency keys
collection: 1.19.0 # general utilitiesYou can still declare your own packages — they merge alongside the profile's. A Function that needs nothing else can omit pubspec.yaml entirely:
koolbase deploy my-fn --file ./my_fn.dart --runtime dart-standardThe profile owns its packages
runtime: dart and manage the full pubspec.Profile versions
Profiles are versioned and immutable. Deploying with dart-standard resolves to the current version and stores that concrete version on your Function — you will see dart-standard-1 in the response and the dashboard, not the bare alias.
That pin is permanent. When a future profile ships with newer packages, existing Functions keep resolving against the version they were built with. Moving to a new profile is an explicit redeploy, never something that happens underneath you.
How resolution works
On deploy, Koolbase runs dart pub get against your pubspec.yaml:
- Resolves the effective pubspec — for
dartthat is exactly what you submitted; fordart-standardit is your pubspec merged with the profile's packages - Computes a SHA-256 hash of the effective pubspec
- If a cached resolution exists for that hash, reuses it instantly (cache hit)
- Otherwise, runs
dart pub get, persists the resolved package set, and generatespubspec.lock(cache miss — first deploy with this pubspec takes 30–90 seconds) - Stores the effective pubspec,
pubspec.lock, the resolution hash, and the pubspec you originally submitted on the function version
Subsequent deploys with the same dependency set are near-instant. The locked pubspec.lock guarantees the same dependency tree every time your function runs.
Failure modes
Dependency errors block deployment. Nothing partial gets persisted — if resolution fails, the function is not created and no disk state is written:
pubspec invalid YAMLMalformed YAML syntax
pubspec missing required field: nameNo `name` field declared
pubspec missing required field: environment.sdkNo SDK constraint declared
pubspec resolution failed: ...A package version conflict, unavailable package, or SDK incompatibility. The exact `dart pub get` error appears in the response body.
pubspec resolution timed out (3 min)Dependency resolution took longer than 3 minutes — usually means deep version conflicts or registry slowness
pubspec exceeds 64KB limitYour pubspec.yaml is too large
Example: SHA-256 hashing
Use package:crypto for SHA-256 digests:
name: hash_function
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
crypto: ^3.0.0import 'dart:convert';
import 'package:crypto/crypto.dart';
Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
final body = ctx['request']['body'] as Map<String, dynamic>;
final input = body['data'] as String;
final digest = sha256.convert(utf8.encode(input));
return {
'algorithm': 'SHA-256',
'hash': digest.toString(),
};
}Example: AES-GCM encryption
Use package:cryptography for authenticated encryption:
name: encrypt_function
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
cryptography: ^2.7.0import 'dart:convert';
import 'package:cryptography/cryptography.dart';
Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
final body = ctx['request']['body'] as Map<String, dynamic>;
final plaintext = body['plaintext'] as String;
final algo = AesGcm.with256bits();
final secretKey = await algo.newSecretKey();
final keyBytes = await secretKey.extractBytes();
final encrypted = await algo.encrypt(
utf8.encode(plaintext),
secretKey: secretKey,
);
return {
'algorithm': 'AES-256-GCM',
'key': base64Encode(keyBytes),
'nonce': base64Encode(encrypted.nonce),
'ciphertext': base64Encode(encrypted.cipherText),
'mac': base64Encode(encrypted.mac.bytes),
};
}Production note
Example: Webhook signature verification
A common pattern: verifying incoming webhooks (Stripe, GitHub, etc.) using HMAC-SHA256:
name: webhook_handler
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
crypto: ^3.0.0import 'dart:convert';
import 'package:crypto/crypto.dart';
export const metadata = {
title: 'Dart Dependencies — Functions',
description: 'Declare pub.dev packages your Dart Function needs via pubspec.yaml. Koolbase resolves dependencies at deploy time, caches the result, and runs your Function ...',
}
Future<Map<String, dynamic>> handler(Map<String, dynamic> ctx) async {
final request = ctx['request'] as Map<String, dynamic>;
final headers = request['headers'] as Map<String, dynamic>;
final body = request['body'] as Map<String, dynamic>;
// Webhook signing secret stored as a function secret
final env = ctx['env'] as Map<String, dynamic>;
final secret = env['WEBHOOK_SIGNING_SECRET'] as String;
// The incoming signature from the provider
final receivedSig = headers['x-webhook-signature'] as String?;
if (receivedSig == null) {
return {'verified': false, 'reason': 'missing signature'};
}
// Compute HMAC of the raw body
final hmac = Hmac(sha256, utf8.encode(secret));
final payload = jsonEncode(body);
final expectedSig = hmac.convert(utf8.encode(payload)).toString();
if (receivedSig != expectedSig) {
return {'verified': false, 'reason': 'signature mismatch'};
}
// ... process webhook event
return {'verified': true, 'event': body};
}Function versions and dependencies
Each function deploy produces a new version with its own locked dependency context:
- Function version 1 with
crypto: ^3.0.0always runs against thecryptoresolved at version 1 deploy time - Deploying version 2 with
crypto: ^3.1.0creates a new resolution; version 1 continues running against the old resolution - Triggered functions, cron functions, and retries all use the dependency context of the function version they were dispatched against
For dart-standard Functions the runtime string itself carries the pin: a Function stored as dart-standard-1 resolves against that profile's packages for its entire life.
A redeploy that breaks a dependency doesn't affect functions already in flight. Existing retries finish against the version they originally fired with.
Deploying via API
The SDK deploy endpoint requires a secret key (sk_*). Publishable keys (pk_*) are restricted to client-side surfaces and cannot deploy code.
curl -X POST https://api.koolbase.com/v1/sdk/functions/deploy \
-H "Content-Type: application/json" \
-H "x-api-key: sk_test_..." \
-d '{
"runtime": "dart",
"name": "my_function",
"code": "Future<Map<String, dynamic>> handler(...) async { ... }",
"pubspec": "name: my_function\nenvironment:\n sdk: \">=3.0.0 <4.0.0\"\ndependencies:\n crypto: ^3.0.0",
"timeout_ms": 10000
}'