GraphQL Formatter

Paste a one-line query from your network tab or a sprawling schema file and get properly nested selection sets, spaced arguments and readable type definitions.

Input

Settings

History

Load from URL

Queries, schemas and why they end up unreadable

GraphQL documents come in two flavours. Executable documents hold the query, mutation and subscription operations plus the fragments a client sends. Schema documents, written in the Schema Definition Language (SDL), declare type, input, enum, interface, union, scalar and directive definitions for servers such as Apollo Server, GraphQL Yoga, Hasura or AWS AppSync. Both get squashed in practice: Apollo and Relay ship queries as single-line strings, request payloads in the browser’s network tab escape everything into one JSON field, and schema dumps are often generated with no blank lines at all. This page turns any of them back into something you can review.

How to format or compress a document

Paste the document, or just the query string pulled out of a request payload. Operation keywords, fragments and type definitions are picked up by the detector. The beautified result appears straight away; press Ctrl/Cmd+Shift+M to flip between the readable layout and the compact one, and Ctrl/Cmd+Shift+C to copy whichever is showing.

Beautifying is done by Prettier’s GraphQL printer, and the compact mode uses stripIgnoredCharacters from graphql-js, the reference implementation. Both are bundled into the page, so internal field names, auth tokens hard-coded into a mutation or an unreleased schema are processed by your browser and nowhere else.

The only layout setting is Indent (2 spaces, 4 spaces or tabs). Prettier wraps at 80 columns, which decides when an argument list moves onto separate lines.

What the beautified output looks like

  • Every field of a selection set goes on its own line, nested one indent deeper than its parent.
  • Arguments and variable definitions get a space after the colon and , between them; a list too long for one line is broken one argument per line.
  • Input object values are written as { field: UPDATED_AT, direction: DESC } with spaces inside the braces.
  • Triple-quoted descriptions on types and fields are placed on their own lines above the definition.
  • Union members, implements A & B lists and directive locations are spaced around | and &.
  • # comments are kept beside the field they annotate. Blank lines you left between definitions survive (several collapse to one), but none are inserted.

What minify removes

In GraphQL, whitespace, line breaks, comments and even commas are “ignored tokens”, meaning the parser treats them as insignificant. The compact mode drops every one of them that is not needed to separate two names, so query Product($slug: String!) becomes query Product($slug:String!) and a whole operation fits on one line. That shrinks persisted-query manifests and URL-encoded GET requests. Comments are gone afterwards, so keep the readable version in source control. A dedicated walk-through of the trade-offs is on the GraphQL minifier page.

Syntax checks, not schema checks

Both modes parse the document first, so a missing brace, an unterminated string or a stray character is reported with its line and column. What the formatter cannot know is your schema: a misspelt field name, a wrong argument type or a fragment spread on the wrong type will format happily. Paste the document into the GraphQL validator for a closer look at structure, and rely on your server or codegen step for schema validation.

Examples

Single-line query with variables and a fragment

The repositories arguments no longer fit on one line, so each gets its own, and the fragment is laid out as a separate block.

Input
query Dashboard($first:Int!,$after:String){viewer{login repositories(first:$first,after:$after,orderBy:{field:UPDATED_AT,direction:DESC}){pageInfo{hasNextPage endCursor}nodes{...RepoCard}}}}fragment RepoCard on Repository{name stargazerCount primaryLanguage{name color}}
Output
query Dashboard($first: Int!, $after: String) {
  viewer {
    login
    repositories(
      first: $first
      after: $after
      orderBy: { field: UPDATED_AT, direction: DESC }
    ) {
      pageInfo {
        hasNextPage
        endCursor
      }
      nodes {
        ...RepoCard
      }
    }
  }
}
fragment RepoCard on Repository {
  name
  stargazerCount
  primaryLanguage {
    name
    color
  }
}
Open this example in the tool

Compressed schema definition

Types, the enum and the input object each become a block, and the description moves above the Order type.

Input
"""A customer order"""type Order{id:ID! status:OrderStatus! items(first:Int=20):[LineItem!]! total:Money}enum OrderStatus{PENDING PAID SHIPPED CANCELLED}input CancelOrderInput{orderId:ID! reason:String}type Mutation{cancelOrder(input:CancelOrderInput!):Order}
Output
"""
A customer order
"""
type Order {
  id: ID!
  status: OrderStatus!
  items(first: Int = 20): [LineItem!]!
  total: Money
}
enum OrderStatus {
  PENDING
  PAID
  SHIPPED
  CANCELLED
}
input CancelOrderInput {
  orderId: ID!
  reason: String
}
type Mutation {
  cancelOrder(input: CancelOrderInput!): Order
}
Open this example in the tool

Query minified for a GET request

The comment, line breaks and optional spaces are stripped, leaving a single line that is safe to URL-encode.

Input
# fetch one product
query Product($slug: String!) {
  product(slug: $slug) {
    title
    price { amount currency }
  }
}
Output
query Product($slug:String!){product(slug:$slug){title price{amount currency}}}
Open this example in the tool

Subscription with a string argument, 4-space indent

The quoted ID is kept exactly and each selected field sits four spaces in.

Input
subscription{orderUpdated(customerId:"c_204"){id status updatedAt}}
Output
subscription {
    orderUpdated(customerId: "c_204") {
        id
        status
        updatedAt
    }
}
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
Syntax Error: Expected Name, found <EOF>.The document ends while a selection set is still open, usually a missing closing brace at the end of a pasted query.Add the missing } characters until every { has a partner.
Syntax Error: Unexpected "}".There is one closing brace too many, or a field and its selection set lost the { between them.Check the braces just before the reported column and remove the extra one.
Syntax Error: Unterminated string.A string argument opens with " but never closes, often because the query was cut out of an escaped JSON payload.Close the string, and unescape any " sequences left over from the JSON body.
Syntax Error: Expected Name, found "{".An argument list is missing its closing parenthesis, as in user(id: 1 { name }.Add the ) before the opening brace of the selection set.
Syntax Error: Unexpected character: U+00A7.A character that is not legal GraphQL syntax, such as a section sign or a smart quote from a document editor, slipped in.Delete the character at the reported column or replace curly quotes with straight ones.

Frequently asked questions

Can I format a query copied from the browser network tab?

Yes. Copy the value of the “query” field from the request payload. If it still contains \n and " escapes, unescape it first, for example by pasting the whole payload into the JSON formatter.

Does the formatter validate my query against a schema?

No. It checks syntax only, because it has no access to your schema. Unknown fields or wrong argument types are reported by your GraphQL server or codegen tooling.

Why were the commas removed when I minified?

Commas are insignificant in GraphQL, exactly like whitespace. graphql-js strips them because the parser does not need them.

Will it format gql template literals inside JavaScript?

Paste only the GraphQL between the backticks, format it here and copy it back. Leave out ${} interpolations or replace them with a fragment spread first, because they are not GraphQL syntax.

Are comments kept?

In the beautified output, yes. Minifying removes them because they are ignored tokens in the GraphQL grammar.

Related tools