What is JSON to ReScript Type Generator?
ReScript is a strongly typed language that compiles to readable JavaScript, designed for building robust web applications with a sound type system that catches errors at compile time. Unlike TypeScript, ReScript types are guaranteed to be correct — no runtime surprises from type mismatches. This generator takes your JSON data and produces ReScript type definitions that accurately model the shape of your data. It supports two output modes: record types, which define structured data with named fields (the most common pattern for JSON modeling), and abstract types, which encapsulate the internal structure behind a type name for better module boundaries. Null values in JSON are automatically mapped to ReScript option types, ensuring that nullable fields are explicitly handled in your code rather than silently causing runtime errors.
How to Use
- Choose between Record or Abstract type output mode using the toggle buttons
- Enter a root type name in the input field — this becomes the name of the top-level type definition
- Paste your JSON data into the input area on the left
- Click "Generate" to produce the ReScript type definitions
- Copy the output and add it to your .res file, then pair it with a JSON decoder library for runtime parsing
Why Use This Tool?
Tips & Best Practices
- Provide JSON with representative values — the type of each field is inferred from the actual data, so empty strings and zeros may lead to less precise types
- Record types are the idiomatic choice for modeling JSON responses in ReScript; use abstract types only when you need to hide internal structure
- Option types (option<T>) represent values that may be absent — pattern match on Some(value) and None to handle both cases safely
- Combine the generated types with @glennsl/rescript-json-combinators to build decoders that validate JSON at runtime
- Field names are converted to camelCase to match ReScript naming conventions
Frequently Asked Questions
How are JSON types mapped to ReScript types?
JSON strings become string, integers become int, decimal numbers become float, booleans become bool, null values become option<T> where T defaults to string, arrays become array<T> with the element type inferred, and nested objects become separate record type definitions with PascalCase names.
When should I NOT use this generator?
Skip this tool if your JSON has union types (e.g., a field that can be either a string or a number) — ReScript requires explicit variant types for those, which cannot be inferred from a single sample value. Also, if your API returns dynamically keyed objects, a simple record type will not capture that shape.
What is the difference between record and abstract types?
Record types define the structure with named fields (type t = {name: string, age: int}), which is the standard way to model JSON data. Abstract types define a type without exposing its structure (type t), useful for encapsulation and module boundaries where you want to control how values are created and accessed.
How are null values handled?
JSON null values are mapped to ReScript option types. For example, a nullable string field becomes option<string>, which can be Some("value") or None. This forces you to explicitly handle the absence of a value through pattern matching, eliminating null pointer errors at compile time.
Can I use these types with JSON decoding?
Yes, the generated types work with JSON decoding libraries. Use @glennsl/rescript-json-combinators to build decoders that match these type definitions, or use the built-in Js.Json module for simpler cases. The type definitions serve as the compile-time contract, while decoders handle runtime validation.
Is my data sent to any external server?
No. All processing happens entirely inside your browser. Your JSON data never leaves your device, and no network requests are made during the conversion.
Real-world Examples
Modeling an API response for a user profile
Convert a JSON API response into ReScript record types for type-safe frontend consumption.
{
"id": 42,
"displayName": "Jane Doe",
"email": "[email protected]",
"avatarUrl": null,
"role": "admin",
"permissions": ["read", "write"]
}type User = {
id: int,
displayName: string,
email: string,
avatarUrl: option<string>,
role: string,
permissions: array<string>,
}Nested product catalog with separate type definitions
A product with nested category and pricing objects generates multiple ReScript types with proper references.
{
"name": "Widget Pro",
"category": {
"slug": "electronics",
"label": "Electronics"
},
"price": {
"amount": 49.99,
"currency": "USD"
}
}type Category = {
slug: string,
label: string,
}
type Price = {
amount: float,
currency: string,
}
type Product = {
name: string,
category: Category,
price: Price,
}