DevToys Web Pro iconDevToys Web ProBlog
Bewerten Sie uns:
Browser-Erweiterung ausprobieren:
← Back to Blog

GraphQL Formatter Guide: Pretty-Print Queries and Schemas the Right Way

8 min read

GraphQL has a strict grammar but a forgiving one: whitespace, line breaks, and indentation are almost entirely insignificant. A query you copy out of a network tab arrives as a single dense line, and a hand-edited schema drifts into inconsistent indentation within a week. A GraphQL formatter takes any syntactically valid document and re-prints it in a single canonical style. Paste a messy query or schema into the GraphQL formatter and follow along with this guide.

What a GraphQL Formatter Actually Does

A real formatter is not a regex that inserts newlines. It parses the document into an Abstract Syntax Tree (AST) — the same structure a GraphQL server builds when it validates a request — and then prints that tree back out using fixed rules for indentation, spacing, and line breaks. This round-trip through the AST is what makes formatting safe: if the input does not parse, you get a precise syntax error instead of mangled output, and if it does parse, the formatter cannot change what the document means — only how it looks.

Because the output is derived from structure rather than from the original text, two developers who write the same query in two different styles will get byte-identical output after formatting. That determinism is the entire point, and it is what ends whitespace debates in code review the same way an opinionated JavaScript formatter does.

Operations vs SDL: Two Things to Format

"GraphQL" actually refers to two related languages, and a good formatter handles both:

  • Executable documents — the query, mutation, and subscription operations clients send, along with fragment definitions and variable declarations.
  • Schema Definition Language (SDL) — the type, input, enum, interface, union, and directive definitions that describe the API itself.

They share a grammar, so the same formatter normalizes both. The examples below cover each in turn.

Indentation and Field Selection

The most common input is a query pasted as one line — exactly what you get from a browser network tab or a log line. Formatting expands the selection set onto its own indentation level:

query GetUser($id:ID!){user(id:$id){id name email posts(first:5){title publishedAt}}}

Becomes:

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
    posts(first: 5) {
      title
      publishedAt
    }
  }
}

Note the normalization beyond just line breaks: a single space after each colon in the variable definition ($id: ID!) and in arguments (first: 5), one field per line, and two-space indentation per nesting level. Every field selection lands on its own line, which is what makes the next change show up as a clean one-line diff.

Arguments, Variables, and Directives

Short argument lists stay inline. The interesting decisions happen with longer ones and with directives. A formatter keeps arguments on one line when they fit and applies consistent spacing around @ directives and their arguments:

query SearchProducts($q: String!, $limit: Int = 20) {
  search(query: $q, limit: $limit, sort: RELEVANCE) {
    edges {
      node {
        id
        name @uppercase
        price @include(if: $showPrices)
      }
    }
  }
}

Default values ($limit: Int = 20) get spaces around the =, directive arguments mirror field-argument spacing, and the comma-and-space separator between arguments is normalized regardless of how the input was spaced. If you also need to inspect the variables payload that accompanies an operation, format it with the JSON formatter — variables travel as a separate JSON object, not as part of the GraphQL document.

Formatting the Schema (SDL)

Schemas drift faster than queries because they are edited by many hands over a long time. Formatting an SDL document aligns field definitions, normalizes spacing around colons and argument lists, and preserves descriptions (the triple-quoted strings that become docs):

"""A registered user of the platform."""
type User implements Node {
  id: ID!
  name: String!
  email: String @deprecated(reason: "Use contactEmail")
  posts(first: Int = 10, after: String): PostConnection!
}

enum Role {
  ADMIN
  EDITOR
  VIEWER
}

A formatter does not reorder your fields or sort your enum values — that would change semantics for tools that care about declaration order, and it would create noisy diffs. It only normalizes the whitespace and punctuation, leaving the meaningful structure exactly where you put it.

Why Consistent Formatting Keeps PR Diffs Clean

The strongest practical argument for formatting GraphQL is the same one that justifies Prettier for JavaScript or gofmt for Go: a canonical layout makes version control diffs reflect intent rather than style. When every document in the repository is already in the formatter's output shape, adding one field to a query produces a single added line. Without formatting, the same change can re-flow an entire selection set, burying the real edit in whitespace noise and forcing reviewers to read the diff character by character.

Run the formatter as a pre-commit step (or as a CI check) and every contributor's editor settings become irrelevant — the committed form is deterministic. This is the same payoff described in the JavaScript formatter guide, applied to your .graphql files.

Formatter vs Linter vs Codegen

Three categories of GraphQL tooling are easy to confuse. They are complementary, not interchangeable:

Tool typeJobChanges meaning?Examples
FormatterNormalize whitespace and layoutNoPrettier (graphql parser), this tool
LinterFlag style and correctness issues (naming, unused fragments, deprecations)No (reports only)graphql-eslint, graphql-schema-linter
CodegenGenerate types/hooks from a schema and operationsProduces new filesGraphQL Code Generator, gql.tada

A formatter only touches presentation, so it is safe to run on every save. A linter has opinions about substance and may demand changes that alter behavior. Codegen consumes the formatted, lint-clean documents and emits derived artifacts (often TypeScript types). The usual pipeline is format → lint → codegen, with formatting first so the downstream tools see stable input.

When to Reach for a Formatter

Use the formatter whenever you need a query or schema to be readable or comparable: cleaning up an operation copied from network logs, normalizing a schema before committing it, preparing a snippet for documentation, or producing a stable baseline before a diff. Because formatting runs entirely on the parsed AST in your browser, nothing about your schema or queries leaves your machine.

Paste any query, mutation, fragment, or SDL document into the GraphQL formatter to pretty-print it instantly, and use the JSON formatter for the accompanying variables and responses.


Format GraphQL operations and schemas directly in your browser — no installation, no server, no data leaving your machine — with the GraphQL formatter.