This post explains how quicktype works internally. Understanding quicktype's architecture will help you contribute to the project and extend it with new features.
The Three Stages
quicktype processes JSON in three main stages:
1. Read
In the Read stage, quicktype parses input JSON and infers an initial type graph. Each unique structure in the JSON becomes a type node in the graph. For example, an array of objects will create an array type containing a class type.
2. Simplify
The Simplify stage optimizes the type graph through several transformations:
- Union Types: When the same position in JSON can contain different types, quicktype creates a union type.
- Type Unification: Equivalent types with different names are merged into a single type.
- Map Detection: Objects with many similarly-typed properties are converted to map/dictionary types.
3. Render
Finally, the Render stage converts the simplified type graph into source code for the target language. Each language has its own renderer that handles language-specific details like:
- Naming conventions (camelCase, snake_case, PascalCase)
- Serialization/deserialization code
- Type syntax and annotations
- Import statements and dependencies
Core Data Structures
quicktype's internal representation centers around a few key data structures:
- Type: The base class for all types (primitives, classes, arrays, maps, unions, enums)
- TypeGraph: A directed graph of types that represents the complete schema
- TypeBuilder: A builder pattern for constructing type graphs
This architecture makes it easy to add new target languages—you only need to implement a new Renderer.