100% local — your data never leaves your browser

JSON to Python — Pydantic, dataclass or TypedDict

Turn a JSON sample into Python classes. Pick the style your project already uses and paste the result straight into models.py.

Instant Private Zero cookies
Style

JSON input

Python output

What this tool does

A JSON sample becomes Python classes, one per object.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
from pydantic import BaseModel, Field


class Address(BaseModel):
    city: str


class Root(BaseModel):
    id: int
    first_name: str = Field(alias="firstName")
    address: Address

Children are declared first: a class has to exist before another annotates a field with it. The output targets modern Python — list[str] and int | str are written directly, which needs 3.10 or later.

Three styles, three different costs

stylewhat it gives youwhat it costs
Pydanticvalidation at the boundary, aliases for renamed keysa dependency, and objects that are not plain
dataclassa plain container, standard library onlyno validation, and no alias for a renamed key
TypedDictannotations for the dicts you already havenothing at runtime — and no runtime check either

The structure is identical in all three; what changes is how much the type does for you.

Reserved words no longer break the file

{"class": 1} used to produce:

class Root(BaseModel):
    class: int

which is not Python — the file does not even parse. Reserved words now take an underscore, and the Pydantic alias keeps the key:

    class_: int = Field(alias="class")

That was a real defect, found while writing this page and fixed. TypedDict sidesteps it differently: a key that cannot be an attribute name switches the whole definition to the functional syntax, Root = TypedDict('Root', {"class": int}), where keys are strings and anything goes.

What one sample cannot tell you

Nothing is | None and nothing has a default: every field is required, because the sample had it. A null gives the type None, which accepts nothing else — if the field is “a string, sometimes null”, str | None is the edit, and = None if it can be absent.

Two keys that both become the same snake_case name — fooBar and foo_bar — are kept apart by a numbered suffix rather than merged, and the alias records which was which.

Private by design

Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.

Frequently asked questions

Which of the three styles should I pick?
Pydantic if the data comes from outside and you want it validated at the boundary. `dataclass` if it is already trusted and you want a plain container. `TypedDict` if you are annotating dictionaries you already have, without changing any runtime code. The structure inferred is the same; only what it costs you differs.
Why is my key renamed, and where did it go?
Python attributes are snake_case, so `firstName` becomes `first_name`. In the Pydantic style the original key is kept by `Field(alias="firstName")`, so parsing still works. `dataclass` has no alias to offer — the name alone is kept — and `TypedDict` keeps the raw key, switching to its functional syntax when a key is not a usable name.
What happens to a key called `class` or `def`?
It gets an underscore: `class_`, `def_`, with `Field(alias="class")` under Pydantic. Emitting `class: int` produced a file Python cannot even parse — that was a real defect, found while writing this page and fixed. `TypedDict` avoids the question entirely by writing `TypedDict('Root', {"class": int})`.

Related converters