ModernCalcs

GraphQL Query Formatter

Paste a minified or messy GraphQL query, mutation, or fragment and get it cleanly indented.

query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
    posts(first: 5) {
      edges {
        node {
          title
          createdAt
        }
      }
    }
    ...UserFields
  }
}
fragment UserFields on User {
  avatarUrl
  bio
}

GraphQL Query Formatter: Readable Queries, Instantly

A GraphQL query copied from a network tab or a minified bundle is usually one unbroken line — every field, argument, and nested selection crammed together. This tool re-indents it into the readable, one-field-per-line style most teams use, tracking brace and parenthesis depth so arguments stay inline while selection sets break out properly.

Formula
source → tokenize (strings, comments, braces, parens) → one field per line inside selection sets, arguments inline

A field boundary is detected as whitespace between two field-like tokens at brace depth > 0 and paren depth 0 — directives stay attached to their field.

Why Brace Depth Drives Line Breaks

Every field inside a `{ ... }` selection set is its own line in conventional GraphQL style, but arguments inside a field's `(...)` stay on one line. The formatter tracks both depths independently — braces control indentation and line breaks, parentheses just get spaced, never broken across lines.

Keeping Directives Attached

A directive like `@include(if: $condition)` modifies the field that precedes it, not a new field — the formatter recognizes '@' as a continuation rather than a new field start, so `name @include(if: $x)` stays on one line instead of splitting into two.

Structural Validation Before Formatting

Before attempting to format, the tool checks that every brace, parenthesis, and bracket is balanced and every string/block-string is properly closed — a genuinely malformed query is reported clearly rather than producing garbled output.

Practical Examples

Formatting a Copied Network Request

Pasting a minified query copied from browser dev tools.

  • 1.Paste the one-line query
  • 2.Get a fully indented, readable version
  • 3.Copy for documentation or code review

What Gets Formatted

  • Queries, mutations, and subscriptions
  • Fragment definitions and spreads
  • Nested selection sets at any depth
  • Arguments, variables, and directives

Good Use Cases

  • Making a minified query readable for code review
  • Documenting API queries for a team wiki
  • Debugging a deeply nested selection set
  • Cleaning up a query before committing it to source control

Frequently Asked Questions

How does the formatter decide where to break lines?

It tracks brace depth (selection sets) and treats whitespace between two field-like tokens at the top of a selection set as a field separator, putting each field on its own line — while keeping argument lists and variable definitions inside parentheses on a single line, matching how most GraphQL style guides format queries.

Does it handle directives correctly?

Yes — a directive like @include(if: $x) immediately following a field stays attached to that field on the same line, since it modifies the field rather than starting a new one.

Does it validate my query is syntactically correct GraphQL?

It checks that braces, parentheses, brackets, and string/block-string literals are balanced — genuine structural problems (an unclosed brace, a stray closing paren) are caught before formatting is attempted. It doesn't perform full GraphQL grammar validation or schema-aware type checking.

Can it format mutations and fragments too?

Yes — operations (query/mutation/subscription), fragment definitions, and multiple operations in one document are all formatted the same way.

Is my query sent anywhere?

No, formatting happens entirely in your browser.