codec library
Type-safe and composable JSON codec abstraction.
Design Goals
- Failures throw CodecException: Codec.decode / Codec.encode
return values directly and throw this package's independent
CodecException hierarchy (DecodeException / EncodeException) on
failure. Messages include PathSegment paths and DecodeErrorKind
descriptions. Internally, failures stay value-based as DecodeOutcome so
they can be accumulated, then convert to exceptions only at public exits.
Use Codec.withFormatExceptions on the top-level codec for compatibility
with existing
on FormatExceptioncatch blocks. - Codecs are first-class values:
Codec.string,Codec.object(...), and other factories return passable, composable Codec instances. Chainable combinators such as.list(),.nullable(),.refine(), and.bimap()cover common transforms. - Automatic path tracking: nested field, list element, and
discriminated-branch errors include paths like
$.user.contacts[2].phone. - Advanced shapes are first-class: sealed unions use Codec.discriminated, recursive structures use Codec.lazy, and multi-version field compatibility uses Codec.firstOf.
- No third-party runtime dependencies: only the Dart SDK is required.
Package Structure
The implementation is split into responsibility-focused part files. Private
_xxx types stay library-local; consumers access behavior through Codec
factories and exported public types:
src/decode_error.dart— paths, error model, and accumulation strategysrc/decode_context.dart— decode context and decode-result algebrasrc/codec_base.dart— Codec base class, public API, and factoriessrc/primitives.dart— primitive const singleton codecssrc/combinators.dart— codec combinatorssrc/object_codec.dart— Object/Discriminated + FieldsReader DSL
Quick Start
final class UserModel {
final String name;
final String? avatar;
final int age;
const UserModel({required this.name, this.avatar, required this.age});
static final Codec<UserModel> codec = Codec.object<UserModel>(
(b) => UserModel(
name: b.required('name', Codec.string),
avatar: b.optional('avatar', Codec.string),
age: b.optionalOr('age', Codec.integer, 0),
),
encode: (u) => {
'name': u.name,
'avatar': u.avatar,
'age': u.age,
}.omitNulls,
);
factory UserModel.fromJson(Object? json) =>
codec.decode(json, typeHint: 'UserModel');
Object? toJson() => codec.encode(this);
}
Classes
- BadFormat
- Codable
-
Marks a class for codec_gen and emits a top-level
_$xxxCodecfield. -
Codec<
T> - Base class for codecs.
- CodecEnum
-
Marks an enum for codec_gen and emits a top-level
_$xxxCodecfield. - CodecField
- Field-level configuration.
- CodecIgnore
- Shorthand marker that makes codec_gen skip this field entirely.
- CodecUnion
-
Marks a sealed/base union for codec_gen to emit
Codec.discriminated. - CodecUnionCase
- Marks the discriminator value for a union branch.
- CodecValue
- JSON mapping for one enum value.
- CustomKind
- DecodeContext
- Runtime decode context: current value, path stack, and error mode.
- DecodeError
- Single field-level decode error.
- DecodeErrorKind
- Decode error category.
-
DecodeFail<
T> -
DecodeOk<
T> -
DecodeOutcome<
T> - Internal decode-result algebra converted to CodecException by Codec.decode.
- FailedRefinement
- FieldsReader
- Field reader passed to object decode builders.
- IsNullField
- MissingField
- PathField
- PathIndex
- PathSegment
-
Immutable JSON path segment chain starting at the root (
$). - UnexpectedError
- Unexpected bare exception caught by the top-level decode guard.
- UnknownTag
- WrongType
Enums
- DateTimeEpochUnit
- Unit for numeric epoch values.
- DateTimeMode
-
DateTime codec mode used by
@CodecField(...). - ErrorMode
- Error accumulation strategy.
- FieldRename
- Field rename strategy.
Extensions
-
MapOmitNulls
on Map<
String, V?> -
Returns a new map without entries whose value is
null.
Exceptions / Errors
- CodecException
- Root codec exception type.
- DecodeException
- Decode failure caused by JSON that does not match the model contract.
- EncodeException
- Encode failure caused by the Dart object or codec implementation.