github glideapps/quicktype v26.0.0
quicktype 26.0.0

17 hours ago

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-core embedders: additionally note the Node.js ≥ 20.19 requirement, the new exports map (deep imports only via quicktype-core/dist/*), typed rendererOptions keys, and the stricter languageNamed().

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 fetch replaces bundled fetch polyfills. If your application supplied a fetch polyfill only for quicktype, you can remove it.
  • quicktype-core ships a dual CJS/ESM build with an exports map. require resolves the CommonJS build, import resolves the ESM build. Deep imports must go through quicktype-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 return undefined instead of throwing. Use isLanguageName() to validate arbitrary strings.

Core API (introduced in 25.0.0)

  • rendererOptions keys are type-checked in the quicktype-core API. 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, 9007199254740991 now becomes Float64 in Crystal instead of an overflowing Int32.

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 suppress DateOnly/TimeOnly converters.
  • Kotlin: kotlinx-serialization fixture coverage; date/datetime support from JSON Schema.
  • Python: Python 3.9/3.10 type-hint syntax support.
  • Rust: --integer-type option with conservative i32 inference.
  • Swift: --final-classes option; JSONNull hash(into:) emitted by default.
  • Scala 3: improved enum generation.
  • TypeScript/Flow: new --prefer-unknown option; TypeScript input now supports Date and Map.
  • C (cJSON): option to generate source/header pairs.
  • JSON Schema: unevaluatedProperties support; JSON Schema 2020-12 prefixItems tuples; 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-types now works in every language (previously crashed the option parser for C# and Kotlin); clear error for empty addSource samples; correct --help rendering 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.)

Don't miss a new quicktype release

NewReleases is sending notifications on new releases.