freshcrate

tonik

Pure Dart OpenAPI 3.0/3.1 code generator. Creates type-safe API client packages for Dart and Flutter with sealed classes, pattern matching, and full encoding support.

Description

Pure Dart OpenAPI 3.0/3.1 code generator. Creates type-safe API client packages for Dart and Flutter with sealed classes, pattern matching, and full encoding support.

README


tonik logo

MIT License pub version pub likes stars on github tests zread

Tonik

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.

Key Features

Type-Safe Response Handling by Status Code and Content Type

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.

Composition with Sealed Classes

oneOf, anyOf, and allOf generate idiomatic Dart code:

  • oneOf - Sealed class with one subclass per variant
  • anyOf - Class with nullable fields for each alternative
  • allOf - Class with a field for each member schema

See Composite Data Types for usage examples.

No Name Conflicts

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.

Integer and String Enums

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]

All Parameter Encoding Styles

Path, query, and header parameters support all OpenAPI styles: simple, label, matrix, form, spaceDelimited, pipeDelimited, and deepObject.

Pure Dart

Install with dart pub global activate tonik and run. No JVM, no Docker, no external dependencies.

Universal Platform Support

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.

Documentation

Quick Start

Install

dart pub global activate tonik

Generate

tonik --package-name=my_api --spec=openapi.yaml

Use

Add 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.

Feature Summary

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

Acknowledgments

Special thanks to felixwoestmann, without whom this project would not exist.

Links

Release History

VersionChangesUrgencyDate
tonik-v0.7.0## What's Changed * feat: support for addtional properties by @t-unit in https://github.com/t-unit/tonik/pull/83 * chore(deps): bump codecov/codecov-action from 5 to 6 in the github-actions group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/84 * fix: address correctness and safety issues from comprehensive audit by @t-unit in https://github.com/t-unit/tonik/pull/85 * fix: better escape strings containing ‘ or “ by @t-unit in https://github.com/t-unit/tonik/pull/86 * Better esHigh4/20/2026
tonik-v0.6.0## What's Changed * Support for Multipart Requests by @t-unit in https://github.com/t-unit/tonik/pull/81 * Expanded integration tests by @t-unit in https://github.com/t-unit/tonik/pull/82 **Full Changelog**: https://github.com/t-unit/tonik/compare/tonik-v0.5.0...tonik-v0.6.0Low3/17/2026
tonik-v0.5.0## What's Changed * Nested discriminator support (allOf) by @t-unit in https://github.com/t-unit/tonik/pull/75 * Cookies by @t-unit in https://github.com/t-unit/tonik/pull/76 * Ci speed by @t-unit in https://github.com/t-unit/tonik/pull/77 * chore(deps): bump actions/cache from 4 to 5 in the github-actions group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/78 * Support read/write only by @t-unit in https://github.com/t-unit/tonik/pull/80 * chore(deps): bump big_decimal from Low2/8/2026
tonik-v0.4.1## What's Changed * chore(deps): bump timezone from 0.10.1 to 0.11.0 in the root-pub group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/68 * Clarify test comment about contentEncoding and bidirectional conversion by @Copilot in https://github.com/t-unit/tonik/pull/70 * Better handle contentEncoding by @t-unit in https://github.com/t-unit/tonik/pull/69 * coverage by @t-unit in https://github.com/t-unit/tonik/pull/72 * Normalize allOf with single model to aliases by @t-unit in Low1/25/2026
tonik-v0.4.0## What's Changed * Improved OpenAPI 3.1 Support by @t-unit in https://github.com/t-unit/tonik/pull/64 * Compile cli for faster code generation by @t-unit in https://github.com/t-unit/tonik/pull/65 * feat: improved encoding detection with OAS 3.1 by @t-unit in https://github.com/t-unit/tonik/pull/66 * Server templating by @t-unit in https://github.com/t-unit/tonik/pull/67 **Full Changelog**: https://github.com/t-unit/tonik/compare/tonik-v0.3.0...tonik-v0.4.0Low1/11/2026
tonik-v0.3.0## What's Changed * Urlencoded bodies by @t-unit in https://github.com/t-unit/tonik/pull/60 * Better support for nullable schemas by @t-unit in https://github.com/t-unit/tonik/pull/62 * remove lints as dependency by @t-unit in https://github.com/t-unit/tonik/pull/63 **Full Changelog**: https://github.com/t-unit/tonik/compare/tonik-v0.2.1...tonik-v0.3.0Low12/23/2025
tonik-v0.2.1## What's Changed * Fix generated tonik version by @t-unit in https://github.com/t-unit/tonik/pull/61 ## New Contributors **Full Changelog**: https://github.com/t-unit/tonik/compare/tonik-v0.2.0...tonik-v0.2.1Low12/21/2025
tonik-v0.2.0## What's Changed * Release 0.0.8 by @t-unit in https://github.com/t-unit/tonik/pull/36 * chore(deps): bump actions/checkout from 4 to 5 in the github-actions group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/37 * chore(deps): bump very_good_analysis from 9.0.0 to 10.0.0 in the root-pub group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/38 * Update dart by @t-unit in https://github.com/t-unit/tonik/pull/39 * Additional fields by @t-unit in https://github.com/tLow12/20/2025
tonik-v0.1.0## What's Changed * Release 0.0.8 by @t-unit in https://github.com/t-unit/tonik/pull/36 * chore(deps): bump actions/checkout from 4 to 5 in the github-actions group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/37 * chore(deps): bump very_good_analysis from 9.0.0 to 10.0.0 in the root-pub group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/38 * Update dart by @t-unit in https://github.com/t-unit/tonik/pull/39 * Additional fields by @t-unit in https://github.com/tLow12/6/2025
tonik-v0.0.9## What's Changed * Release 0.0.8 by @t-unit in https://github.com/t-unit/tonik/pull/36 * chore(deps): bump actions/checkout from 4 to 5 in the github-actions group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/37 * chore(deps): bump very_good_analysis from 9.0.0 to 10.0.0 in the root-pub group by @dependabot[bot] in https://github.com/t-unit/tonik/pull/38 * Update dart by @t-unit in https://github.com/t-unit/tonik/pull/39 * Additional fields by @t-unit in https://github.com/tLow11/9/2025
tonik-v0.0.8## What's Changed * Util release by @t-unit in https://github.com/t-unit/tonik/pull/29 * Location agnostic time zone parsing by @t-unit in https://github.com/t-unit/tonik/pull/30 * Simple encoding by @t-unit in https://github.com/t-unit/tonik/pull/32 * Any of by @t-unit in https://github.com/t-unit/tonik/pull/33 * remove unused code and format all files by @t-unit in https://github.com/t-unit/tonik/pull/34 * improve readme and documentation by @t-unit in https://github.com/t-unit/tonik/pulLow8/11/2025
tonik_util-v0.0.7## What's Changed * Fix date property types by @t-unit in https://github.com/t-unit/tonik/pull/22 * Declare platform support by @t-unit in https://github.com/t-unit/tonik/pull/23 * Improved server class names by @t-unit in https://github.com/t-unit/tonik/pull/24 * Decimal Parsing Improvements by @t-unit in https://github.com/t-unit/tonik/pull/25 * De- and encoding for none-utc date time objects by @t-unit in https://github.com/t-unit/tonik/pull/26 * Uri property encoding and decoding by @tLow8/11/2025
tonik-v0.0.6## What's Changed * Update to melos 7 by @t-unit in https://github.com/t-unit/tonik/pull/16 * Proper hash code for classes with >20 properties by @t-unit in https://github.com/t-unit/tonik/pull/17 * Fix or ignore linter issues in generated code by @t-unit in https://github.com/t-unit/tonik/pull/18 * e2e tests: get an album by @t-unit in https://github.com/t-unit/tonik/pull/20 * chore: update very_good_analysis by @t-unit in https://github.com/t-unit/tonik/pull/21 **Full Changelog**: htLow6/15/2025
tonik-v0.0.5## What's Changed * chore(deps): bump very_good_analysis from 6.0.0 to 7.0.0 in the root-pub group by @dependabot in https://github.com/t-unit/tonik/pull/1 * chore(deps): bump lints from 5.1.1 to 6.0.0 in /packages/tonik in the packages-tonik-pub group by @dependabot in https://github.com/t-unit/tonik/pull/4 * Quick Start Guide by @t-unit in https://github.com/t-unit/tonik/pull/11 * AllOf generation by @t-unit in https://github.com/t-unit/tonik/pull/12 * chore(release): publish packages by Low6/2/2025
tonik-v0.0.4## What's Changed * chore(deps): bump very_good_analysis from 6.0.0 to 7.0.0 in the root-pub group by @dependabot in https://github.com/t-unit/tonik/pull/1 * chore(deps): bump lints from 5.1.1 to 6.0.0 in /packages/tonik in the packages-tonik-pub group by @dependabot in https://github.com/t-unit/tonik/pull/4 * Quick Start Guide by @t-unit in https://github.com/t-unit/tonik/pull/11 * AllOf generation by @t-unit in https://github.com/t-unit/tonik/pull/12 ## New Contributors * @dependabot mLow6/2/2025

Dependencies & License Audit

Loading dependencies...

Similar Packages

revisium-endpointAuto-generated GraphQL + REST APIs from Revisium schemasv2.5.1
graphlinkType-safe code generator for GraphQL schemas — produces clients and server interfaces for Dart, Flutter, Java, and Spring Boot. Features built-in caching with TTL/tag-based invalidation, JSOv4.5.1
swaggieTool for generating TypeScript client code for given Swagger API endpointsv2.1.1
aideaAn APP that integrates mainstream large language models and image generation models, built with Flutter, with fully open-source code.2.0.0
opsgenie-sdkPython SDK for Opsgenie REST API2.1.5