quicktype 26.0.0
quicktype 26 modernizes the default generated code across most target languages: current serialization frameworks, current language standards, and safer types. Because versions 24, 25, and 26 shipped in quick succession, many users will upgrade directly from 23.x — so this document calls out every breaking change since 23.2.6, not just changes since 25.1.0. Nearly every changed generated-code default has a flag to restore the previous output (see the table below).
Am I affected?
- CLI users: check the generated-code defaults table for your target languages, and note the stricter date-time/integer inference. Add the listed flags to keep your previous output.
quicktype-coreembedders: additionally note the Node.js ≥ 20.19 requirement, the newexportsmap (deep imports only viaquicktype-core/dist/*), typedrendererOptionskeys, and the stricterlanguageNamed().
Breaking changes since 23.2.6
Runtime and packaging (introduced in 24.x)
- Node.js 20.19 or newer is required. The published packages are built and tested on Node.js 20, 22, and 24.
- Native
fetchreplaces bundled fetch polyfills. If your application supplied a fetch polyfill only for quicktype, you can remove it. quicktype-coreships a dual CJS/ESM build with anexportsmap.requireresolves the CommonJS build,importresolves the ESM build. Deep imports must go throughquicktype-core/dist/*; other undeclared paths no longer resolve.languageNamed()accepts only canonical language names. Display names and file extensions (e.g."C++","kt") are no longer accepted; unknown strings returnundefinedinstead of throwing. UseisLanguageName()to validate arbitrary strings.
Core API (introduced in 25.0.0)
rendererOptionskeys are type-checked in thequicktype-coreAPI. TypeScript consumers passing unknown option keys now get compile errors.
Type inference (introduced in 25.0.0)
- Date-times are inferred only for strict RFC 3339 strings. Loosely formatted date strings stay plain strings.
- Whole numbers outside the target's integer range are inferred as floating point. For example,
9007199254740991now becomesFloat64in Crystal instead of an overflowingInt32.
Generated-code defaults (new in 26.0.0)
These change what the generated code looks like and which dependencies it needs. Each has a flag to restore the previous output.
| Language | New default | Previous default | Restore old behavior |
|---|---|---|---|
| C# | System.Text.Json ([JsonPropertyName], #nullable enable), C# 8
| Newtonsoft.Json, C# 6 | --framework NewtonSoft --csharp-version 6
|
| Kotlin | Jackson | Klaxon | --framework klaxon
|
| C++ | C++17 std::variant / std::optional, no Boost dependency
| boost::variant / boost::optional
| --boost
|
| Java | List<T>
| T[] arrays
| --array-type array
|
| Python | @dataclass + PEP 585 generics (list[...]) — generated code now targets Python 3.9+
| explicit __init__, typing.List
| --python-version 3.7
|
| Scala 3 | circe Encoder/Decoder derivation
| plain case classes | --just-types
|
| Swift | explicit CodingKeys enums
| implicit coding keys | --no-coding-keys
|
| Dart | final fields (immutable)
| mutable fields | --no-final-props
|
| TypeScript / Flow | string-literal unions instead of enums; unknown instead of any
| enums; any
| --no-prefer-unions --no-prefer-unknown
|
| Elm | Elm 0.19, native List
| Elm 0.18, Array
| --array-type array (0.18 no longer supported)
|
| Haskell | native lists | Vector
| (no restore flag) |
| Rust | #[derive(Debug, Clone, Serialize, Deserialize)], pub fields
| Serialize/Deserialize only, private fields
| --no-derive-debug --no-derive-clone --visibility private
|
Also in TypeScript, JSON Schema arrays with minItems/maxItems (and 2020-12 prefixItems) now generate tuple types.
Output for the remaining targets is unchanged: in our JSON-input comparison against 23.2.6, C (cJSON), Elixir, Flow, Go, JavaScript, JavaScript PropTypes, JSON Schema, Objective-C, Pike, Ruby, Smithy, TypeScript, TypeScript Effect Schema, and TypeScript Zod produced byte-identical output. (TypeScript and Flow appear in both lists because their new defaults only alter output where enums, any, or tuple-typed arrays occur — typically with JSON Schema input.)
Highlights since 23.2.6 (non-breaking)
- C#: C# version 8 support with nullable reference types and
[JsonRequired]; option to suppressDateOnly/TimeOnlyconverters. - Kotlin: kotlinx-serialization fixture coverage; date/datetime support from JSON Schema.
- Python: Python 3.9/3.10 type-hint syntax support.
- Rust:
--integer-typeoption with conservativei32inference. - Swift:
--final-classesoption;JSONNullhash(into:)emitted by default. - Scala 3: improved enum generation.
- TypeScript/Flow: new
--prefer-unknownoption; TypeScript input now supportsDateandMap. - C (cJSON): option to generate source/header pairs.
- JSON Schema:
unevaluatedPropertiessupport; JSON Schema 2020-12prefixItemstuples; Windows absolute schema paths (drive-letter and UNC) work correctly. - PHP: non-nullable unions; fixed crash on inferred dates.
- Performance: optimized Markov-chain representation and hot paths in the canonical pipeline.
- Reliability:
--just-typesnow works in every language (previously crashed the option parser for C# and Kotlin); clear error for emptyaddSourcesamples; correct--helprendering for boolean flags; fixed nested intersections in union flattening; Kotlin/Klaxon map deserialization fix.
Contributors
Huge thanks to everyone who contributed since 23.2.6:
@ankrgyl, @artursvonda, @AysajanE, @basdl, @cconverse711, @coyaSONG, @Flern, @h3ndrk, @HavardNJ-Laerdal, @haya14busa, @jessicamrbr, @jonashao, @k-vasily, @Leonard013, @liosha, @matthew-c-lee, @mikecrowe-otp, @mohamedelhabib, @nikhilunni, @PssbleTrngle, @Quafadas, @schani, @thives, @tolbon, @uuf6429, @vexdev, @w830207 — and dependabot for keeping dependencies current.
Full changelog: v25.1.0...v26.0.0 (see the v24.0.0, v25.0.0, and v25.1.0 releases for the full history since 23.2.6, which predates release tags.)