Happy Birthday, quicktype!
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 keysfav number
is legalized asfav_number
, automatically translated to-and-from JSON, and stringified numbers are detected and parsedhas friends
is inferred as a sometimes-stringified boolean, and is automatically translated fromstring
tobool
class
is reserved in Python, so it's legalized asperson_class
and automatically translatedborn
is inferred to be a date and automatically parsed as adatetime
nickname
is inferred as optional, and expressed asOptional[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. 😊