100% local — your data never leaves your browser

JSON to GraphQL — SDL for Your schema File

Turn a JSON sample into GraphQL SDL types. Nested objects become their own types, ready to paste into schema.graphql and query straight away.

Instant Private Zero cookies

JSON input

GraphQL output

What this tool does

A JSON sample becomes GraphQL SDL types, one per object.

{ "id": 1, "name": "Ada", "tags": ["admin"], "address": { "city": "Paris" } }
type Root {
  id: Int!
  name: String!
  tags: [String!]!
  address: Address!
}

type Address {
  city: String!
}

[String!]! reads outside in: the list is never null, and no element is null either. Both halves come from the sample, which had a list and had strings in it.

Types only — this is not yet a schema

There is no Query, no Mutation, no directives. A JSON payload says what the data looks like, not which fields a server exposes or what they are called. Add the entry point yourself:

type Query {
  root: Root!
}

Until then the file describes types that nothing can be asked for.

What SDL cannot express is named, not faked

  • null and unknown values become a custom JSON scalar, declared at the top and left for you to implement. SDL has no “anything” type.
  • A heterogeneous array becomes [JSON]! for the same reason: a list of mixed shapes is not a GraphQL list type.
  • An integer outside 32 bits becomes BigInt, another custom scalar. Int in GraphQL is 32-bit signed, so an eleven-digit identifier is not representable — a server returning it raises at serialization. It used to be typed Int! anyway; that was a real defect, found while writing this page and fixed.
  • An empty object is refused. type A {} is not valid SDL — a type must define at least one field — so the conversion stops and names the type rather than handing you a schema no server will parse. This too was found and fixed here.

Names are repaired, and collisions kept apart

GraphQL names allow letters, digits and _ only, and cannot start with a digit. content-type becomes content_type, 2fa becomes _2fa. When two repaired names collide inside a type, the second is suffixed, so nothing is silently merged.

A scalar at the root — 42, "text" — is refused: SDL describes object types, and there is nothing to describe.

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

Why is there no `Query` type?
Because a sample describes data, not an entry point. The output is the type part of a schema; a server also needs a `Query` (and often `Mutation`) naming the fields it exposes. Add `type Query { root: Root! }` and the schema becomes servable — what goes in it is an API decision, not something a payload states.
My eleven-digit id came out `BigInt`, not `Int`. Why?
Because GraphQL\u2019s `Int` is a 32-bit signed integer, and your value does not fit. It used to be typed `Int!` anyway, which made the schema wrong for the very sample it came from — graphql-js raises at serialization time. Beyond the 32-bit range the field now uses a `BigInt` scalar, declared at the top and implemented by you.
Why is everything followed by `!`?
Because the sample had a value for every field, and `!` is what "there is a value here" looks like in SDL. It is the claim the document supports. Whether a field can be null in general is an API decision: drop the `!` where it can.

Related converters