A Dart code generator for OpenAPI 3.0 and 3.1 specifications.
Generate type-safe API client packages for Dart and Flutter. Tonik produces idiomatic code with sealed classes for oneOf, exhaustive pattern matching for responses, and full OpenAPI encoding support.
Most OpenAPI generators pick a single "success" type and a single "error" type per operation, silently discarding the response schemas for all other status codes. If your endpoint returns a Pet for 200, a ValidationError for 400, and a NotFoundError for 404, you only get the 200 type — the rest are lost or reduced to untyped error strings.
Tonik generates a distinct type for every response defined in your spec. Each status code and content type combination becomes its own strongly-typed class, and the compiler enforces exhaustive handling:
final response = await petApi.updatePet(body: pet);
switch (response) {
case TonikSuccess(:final value):
switch (value) {
case UpdatePetResponse200(:final body):
print('Updated: ${body.name}');
case UpdatePetResponse400(:final body):
print('Validation: ${body.message}');
case UpdatePetResponse404(:final body):
print('Not found: ${body.detail}');
}
case TonikError(:final error):
print('Network error: $error');
}Every response body is deserialized into the correct type for its status code — no casting, no type checks, no lost information. Add a new response to your spec, regenerate, and the compiler tells you every call site that needs updating.
oneOf, anyOf, and allOf generate idiomatic Dart code:
oneOf- Sealed class with one subclass per variantanyOf- Class with nullable fields for each alternativeallOf- Class with a field for each member schema
See Composite Data Types for usage examples.
Use Error, Response, List, or any Dart built-in as schema names. Tonik uses scoped code emission to properly qualify all type references - no naming collisions with dart:core or Dio.
Both work out of the box, with optional unknown-value handling for forward compatibility:
status:
type: integer
enum: [0, 1, 2]
x-dart-enum: [pending, active, closed]Path, query, and header parameters support all OpenAPI styles: simple, label, matrix, form, spaceDelimited, pipeDelimited, and deepObject.
Install with dart pub global activate tonik and run. No JVM, no Docker, no external dependencies.
Generated packages are pure Dart with no platform dependencies. Use them in Flutter apps targeting iOS, Android, web, desktop, or in server-side Dart - the same generated code works everywhere.
- Features Overview – Complete feature reference
- Configuration –
tonik.yamloptions, name overrides, filtering - Data Types – OpenAPI to Dart type mappings
- Composite Data Types –
oneOf,anyOf,allOfusage - Authentication – Interceptor patterns for auth
- Additional Properties –
additionalPropertiessupport and pure maps - URI Encoding Limitations – Dart URI class constraints
dart pub global activate toniktonik --package-name=my_api --spec=openapi.yamlAdd the generated package to your project:
dart pub add my_api:{'path':'./my_api'}Then import and use:
import 'package:my_api/my_api.dart';
final api = PetApi(CustomServer(baseUrl: 'https://api.example.com'));
final response = await api.getPetById(petId: 1);
switch (response) {
case TonikSuccess(:final value):
print('Pet: ${value.body.name}');
case TonikError(:final error):
print('Failed: $error');
}See the petstore integration tests for more examples.
| Category | What's Supported |
|---|---|
| Responses | Multiple status codes, multiple content types, response headers, default and range codes (2XX) |
| Composition | oneOf (sealed classes), anyOf, allOf, discriminators, nested composition |
| Types | Integer/string enums, date, date-time with timezone, decimal/BigDecimal, uri, binary |
| Parameters | Path, query, header; all encoding styles (form, simple, label, matrix, deepObject, etc.) |
| Request Bodies | application/json, application/x-www-form-urlencoded, application/octet-stream, text/plain |
| Multipart | multipart/form-data with primitive, file, JSON, and array parts; per-part encoding and content types |
| Schema | readOnly/writeOnly enforcement, nullable, required, deprecated, boolean schemas, additionalProperties |
| Configuration | Name overrides, filtering by tag/operation/schema, deprecation handling, content-type mapping |
| OAS 3.1 | $ref with siblings, $defs local definitions, boolean schemas, nullable type arrays, contentEncoding/contentMediaType |
Special thanks to felixwoestmann, without whom this project would not exist.
