The moment your database schema and your application types drift apart, bugs start quietly. A column declared VARCHAR(255) NULL that your code types as string will throw the day a real null arrives. This converter reads a CREATE TABLE statement — column types, nullability, ENUM values, inline comments — and turns it into TypeScript interfaces, Zod schemas, Pydantic models or JSON Schema.
It handles the DDL dialects you actually encounter: MySQL backticks, PostgreSQL double quotes, SQL Server brackets, schema-qualified table names, multi-word types like DOUBLE PRECISION and TIMESTAMP WITH TIME ZONE, PostgreSQL array columns (TEXT[]), and table-level PRIMARY KEY (id) constraints. Everything runs in your browser, so pasting a production schema never sends it anywhere.
How to use
- Paste your DDL — Drop one or more
CREATE TABLEstatements into the left pane. Line comments, block comments and index definitions likeUNIQUE KEYare filtered out automatically. The detected tables and their column counts appear below the input. - Pick an output format — Choose TypeScript interfaces, Zod (runtime validation), Pydantic (FastAPI and Python backends), JSON Schema (OpenAPI docs) or a JSON sample (mock data and API examples). Switching formats keeps your input intact.
- Tune naming and nullability — Turn on camelCase to convert
snake_casecolumns to front-end conventions. Decide whether nullable columns becomefield?: stringorfield: string | nullwith the optional-marker toggle — the former suits form payloads, the latter matches what an API actually returns. - Copy or download — Use the copy button for the clipboard or download a
.ts,.pyor.jsonfile named after the first table in your schema.
Frequently asked questions
Does it understand both MySQL and PostgreSQL DDL?
Yes. Backtick-quoted MySQL identifiers, double-quoted PostgreSQL identifiers and bracketed SQL Server identifiers are all parsed.
Type mapping is dialect-aware too. MySQL's TINYINT(1) is conventionally a boolean, so it maps to boolean, and ENUM('a','b') becomes the literal union "a" | "b". PostgreSQL's SERIAL and BIGSERIAL are treated as NOT NULL because they auto-populate, TEXT[] becomes string[], and JSONB becomes Record<string, unknown>.
My DATE columns become Date, but I want strings.
TypeScript output maps temporal columns to Date because that is what ORMs such as Prisma and TypeORM hand back.
If you are typing a JSON API response instead, string is correct. Use the JSON Schema output, which emits { "type": "string", "format": "date-time" }, or the Zod output, whose z.coerce.date() accepts an ISO string and converts it — safe to use directly against JSON payloads.
Is my schema uploaded anywhere?
No. Parsing and code generation happen entirely in the JavaScript running on this page.
The site is deployed as static files with no backend that could receive input. Open your browser's network tab while converting and you will see that no request is made. Pasting an internal production schema is safe.
Can I use the generated types in production as-is?
They are a solid starting point, but read them once before committing.
DECIMAL and NUMERIC columns map to number in TypeScript, and JavaScript's double-precision floats lose accuracy on monetary values. For those columns, receiving a string and computing with a decimal library is safer. The Pydantic output already maps them to Decimal.
Concepts worth knowing
Where SQL types and language types diverge
SQL encodes length in the type (VARCHAR(80)); TypeScript's string has no length. Conversely, a TypeScript union can only be approximated in SQL by an ENUM.
Because of that gap, generated types are compile-time hints, not runtime guarantees. If you need real validation, use the Zod output and call schema.parse(data) at your API boundary — length constraints (z.string().max(80)) and integer checks (z.number().int()) come along for free.
NULL, undefined and optional are three different things
SQL's NULL means 'no value'. TypeScript has two candidates for that idea, and they behave differently. field?: string means the key may be absent; field: string | null means the key is present with a null value.
Serialization makes the difference concrete: JSON.stringify drops undefined properties entirely but preserves null. For a row returned straight from the database, | null matches reality. For the body of a PATCH request, ? is the better fit.
Treating the schema as the single source of truth
Hand-maintained types drift as migrations accumulate. The healthier pattern is to treat the database schema as the source of truth and derive types from it.
At scale, wire up Prisma, Drizzle, sqlc or SQLAlchemy in CI so generation is automatic. But before that pipeline exists — or when another team hands you nothing but a DDL file, or you need to bolt on one legacy table today — pasting and getting an answer in two seconds is simply faster.