Today quicktype is one year old. After generating one billion lines of code, here's a look back on quicktype's first year.

How quicktype started

A year ago, I was writing some Swift to parse and represent JSON when I was struck by how mind-numbingly tedious the process was (especially before Codable was introduced in Swift 4). I had seen some simple JSON-to-code translators, but they were always buggy, had terrible UX, and were hard-coded for a single programming language.

"Mark, I need your big brain," I said to my big-brained friend Mark, before explaining the problem and what I thought a good solution would be like: paste JSON on the left, instantly get lovely code in any language on the right, with functions for marshaling to-and-from JSON strings. The goal would be to generate the same code that a person would write by hand, so the style had to be impeccable and we'd have to infer intuitive names for types and properties.

Mark agreed it would be a fun project, so we started hacking, and within a day or two, the world got its first look at a crude prototype:

quicktype was implemented as 700 lines of purely-functional PureScript, generating C# and Go from an intermediate representation. Here's the code that rendered C# classes:

renderCSharpClass :: IRClassData -> Doc Unit renderCSharpClass (IRClassData { names, properties }) = do line $ words ["class", csNameStyle $ combineNames names] lines "{" indent do for_ (Map.toUnfoldable properties :: Array _) \(Tuple.Tuple pname ptype) -> do line do string "[JsonProperty(\"" string pname string "\")]" line do string "public " graph <- getGraph string $ renderTypeToCSharp graph ptype words ["", csNameStyle pname, "{ get; set; }"] blank -- TODO don't rely on 'TopLevel' when (names == Set.singleton "TopLevel") do lines """// Loading helpers public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json); public static TopLevel FromUrl(string url) => FromJson(new WebClient().DownloadString(url));""" lines "}"

Then we continuously deployed updates and new features for a year.

quicktype today

quicktype has come a long way in that time. quicktype now has:

Generated over 1.2 billion lines of code, by rough estimate. In San Francisco, you'd have to hire 76 developers at a cost of $7.9 million to write this code, assuming no sick days and all programmers type 40 WPM for 6 hours per day!

30k lines of TypeScript in core libraries

13k lines of TypeScript in the web app

Support for C#, Go, Rust, C++, Objective-C, Java, TypeScript, JavaScript, Flow, Swift, Kotlin, Elm, JSON Schema, Ruby, and now Python

Support for GraphQL, JSON Schema, and TypeScript as input, so you can more formally specify desired output types

Many language-specific options, like typesafe HTTP request handlers in Swift or runtime type checking in JavaScript

Integer, enum, and map inference

Stringified number, boolean, date, and UUID inference with automatic parsing in C# and Python

Extensions for Xcode, VSCode, and Visual Studio

We recently released 'continuous mode' for the VSCode extension, which generates code from JSON, schema, and TypeScript as you type:

Python is our latest language, with support for Python 2.7 through 3.7, including data classes and typing:



If you look carefully at the Python above*, you'll notice some subtle sophistications:

people is inferred to be a map using a Markov chain that discerns class property names from arbitrary keys

is inferred to be a map using a Markov chain that discerns class property names from arbitrary keys fav number is legalized as fav_number , automatically translated to-and-from JSON, and stringified numbers are detected and parsed

is legalized as , automatically translated to-and-from JSON, and stringified numbers are detected and parsed has friends is inferred as a sometimes-stringified boolean, and is automatically translated from string to bool

is inferred as a sometimes-stringified boolean, and is automatically translated from to class is reserved in Python, so it's legalized as person_class and automatically translated

is reserved in Python, so it's legalized as and automatically translated born is inferred to be a date and automatically parsed as a datetime

is inferred to be a date and automatically parsed as a nickname is inferred as optional, and expressed as Optional[str]

* quicktype generates additional code to implement the automatic translations, omitted from the screenshot

As you can see, quicktype has evolved into something quite powerful from its simple beginnings.

Thank you!

Thank you for using quicktype and giving us feedback! Nothing motivates us more than interacting with you on Twitter, GitHub, Intercom, or Slack. If you'd like to support our work, please blog, screencast, tweet, or demo quicktype to your friends. 😊