Skip to content

GraphQL Formatter: Beautify and Minify Queries, Mutations and Schemas

Free GraphQL formatter — beautify or minify queries, mutations, fragments and SDL schemas with a real parser. Syntax errors located by line and column.

Try it now: GraphQL Formatter Format or minify a GraphQL query, mutation, fragment or SDL schema with a real parser — syntax errors show the exact line and column, nothing invented.

Why GraphQL Queries Get Unreadable Fast

A REST URL is flat — the path and query string are the whole request. A GraphQL query has no such ceiling: selection sets nest inside selection sets, fragments get spread into other fragments, and directives like @include and @skipattach conditions to individual fields. Add variable definitions at the top of the operation and it's easy to end up with a document five or six levels deep before you've queried anything unusual. None of that depth is a problem for the GraphQL engine executing it — it's a problem for the person reading it, especially once the query has been copy-pasted between a client codebase, a GraphiQL tab, and a bug report, each pass losing a little more of its original indentation.

A GraphQL formatter — sometimes searched for as a GraphQL beautifier or GraphQL prettify tool — exists for exactly that reason: it re-indents the document consistently based on its actual nesting, the same service a JSON formatter provides for deeply nested JSON. The underlying principle is identical in both cases — the formatter has to understand the document's structure, not just react to brace and bracket characters in the text.

Four Documents, One Grammar

“GraphQL” isn't one kind of document — a formatter that only handles queries is missing most of what people actually paste in. There are four related but distinct forms, all valid GraphQL syntax that a formatter needs to parse and print correctly:

  • Queries — read operations, the most common case: a named operation with a selection set and, usually, variable definitions.
  • Mutations — write operations. Structurally identical to a query (variables, a selection set, an operation name) but declared with the mutation keyword instead of query.
  • Fragments — a named, reusable selection set declared with fragment and spread into an operation with ...FragmentName. Formatting a document that spreads three or four fragments into a query is where indentation drift shows up fastest, because each fragment was likely pasted in from a different file.
  • SDL — Schema Definition Language. This is the odd one out and worth being precise about: SDL is the syntax used to describe a schema — type, input, enum, interface, and scalar declarations — not to query one. A .graphqlschema file and a query sent from a client share a grammar family but serve opposite purposes: one defines what's queryable, the other queries it. A formatter that only recognizes operations will choke the moment you paste in a schema file, so it needs to parse both grammars.

Formatting a Query That Lost Its Indentation

The most common input in practice isn't hand-typed — it's a query copied out of a Slack thread, a network tab, or a minified bundle, where every newline collapsed into one line somewhere along the way. Reformatting it should recover exactly the structure the query already has, nothing added or reordered:

unindented input
query GetUser($id: ID!, $includeOrders: Boolean = false) { user(id: $id) { id name email orders @include(if: $includeOrders) { id total items { sku quantity } } } }
formatted
query GetUser($id: ID!, $includeOrders: Boolean = false) {
  user(id: $id) {
    id
    name
    email
    orders @include(if: $includeOrders) {
      id
      total
      items {
        sku
        quantity
      }
    }
  }
}

Notice the @include directive stays attached to the field it modifies rather than being pushed to its own line — a formatter that understands the grammar knows a directive is part of the field it decorates, not a standalone token to wrap independently.

A Real Parser Catches Syntax Errors; a Regex Just Hides Them

This is the detail worth being precise about, because it's the difference between a formatter you can trust and one that quietly lies to you. A GraphQL formatter built on a real parser — the same class of tool the reference GraphQL implementations use to validate a document before execution — has to build an actual syntax tree from the input. An unclosed brace, a variable definition missing its type, a dangling comma where the grammar doesn't allow one: all of these fail to parse, and a parser-based tool reports exactly where, with a line and column, the same way a real JSON parser reports a trailing comma.

A string-based reformatter — one that just counts braces and inserts indentation based on nesting depth inferred from characters — has no such check. Feed it a query with a brace missing and it will still produce something that looks tidy: consistent indentation, aligned fields, no visible complaint. It is still invalid GraphQL. It will fail the moment a client or server actually tries to parse it, just later and with a less useful error than the formatter could have given you up front.

invalid input — reported, not silently tidied
query GetUser($id: ID!) {
  user(id: $id) {
    id
    name


→ Syntax Error: Expected Name, found <EOF> (line 6, column 1)

The missing closing brace for both user and the operation itself is a genuine syntax error, and a parser-backed formatter surfaces it instead of guessing at how to indent something that never had valid structure to begin with.

Format vs. Minify: Same Operation, Reversed

Format and minify a GraphQL query are the same transformation run in opposite directions — exactly the relationship between beautifying and minifying JSON. Format a query when a human is going to read it: a teammate reviewing a pull request, you debugging a resolver, or a query sitting in a .graphql file in a codebase where readability matters for the next person who touches it. Minify — strip whitespace, comments, and unnecessary line breaks — when only the bytes matter: a query embedded in a client bundle, sent over the wire, or persisted as an operation string on a server that supports persisted queries.

formatted → minified, same query
query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
  }
}
↓
query GetUser($id: ID!) { user(id: $id) { id name } }

Neither direction changes what the query does. A client sending the minified form and a developer reading the formatted form in an IDE are looking at the same operation — the same guarantee a JSON minifier gives for data, applied here to an executable document instead.

Using the GraphQL Formatter

GenKitLab's GraphQL Formatter formats or minifies a query, mutation, fragment, or SDL schema document using a real GraphQL parser, so a genuine syntax error — an unclosed brace, a malformed variable definition — is reported with the exact line and column it occurs at, rather than papered over with indentation that merely looks correct. It runs entirely client-side: nothing you paste is uploaded anywhere, which matters for a query that includes field names or fragment structure you'd rather not send to a third-party server just to reformat it.

Frequently asked questions

What does a GraphQL formatter actually do?

It parses a GraphQL document — a query, mutation, fragment, or SDL schema — into its actual structure and re-prints it with consistent indentation based on real nesting depth, rather than reacting to brace characters in the text. The operation itself is unchanged; only whitespace and layout differ.

Can a GraphQL formatter handle schema files (SDL), not just queries?

It should. SDL — Schema Definition Language — is the syntax used to define a schema's types, inputs, enums, and interfaces, and it's a different grammar surface from an operation. A formatter that only parses queries and mutations will fail on a .graphql schema file, so a general-purpose one needs to support both.

What's the difference between formatting and minifying a GraphQL query?

They're the same transformation in opposite directions. Formatting adds consistent indentation and line breaks for a human to read — reviewing a PR, debugging in an IDE. Minifying strips whitespace and comments down to the minimum needed to parse, which matters when the query is embedded in a client bundle or sent over the wire.

Will a formatter fix a broken GraphQL query?

No — and a good one shouldn't try. A formatter built on a real parser reports a genuine syntax error, such as an unclosed brace or a malformed variable definition, with a line and column, the same way a JSON parser reports invalid JSON. A string-based reformatter that skips parsing will instead produce tidy-looking output for input that's still invalid GraphQL underneath.

Do directives like @include and @skip affect formatting?

They stay attached to the field or fragment spread they modify rather than being placed on their own line — a directive is part of the element it decorates, not a standalone token, and a parser-based formatter reflects that in how it prints the document.

Is it safe to format a query that contains sensitive field or variable names?

Yes, as long as the formatter runs client-side. GenKitLab's GraphQL Formatter processes the document entirely in your browser — nothing pasted into it is uploaded to a server, which matters for internal schemas or queries you don't want leaving your machine just to reformat them.

Last updated