GraphQL Fragments: Organizing Reusable Query Building Blocks
AI generated
{ }
type
GraphQL · React · Apollo Client · Query Organization
GraphQL Fragments: Organizing Reusable Query Building Blocks
From a 300-line query to colocated, maintainable building blocks

A page query that lists every field for ten components in one block turns into a merge conflict magnet with every change. GraphQL fragments break queries into named, reusable building blocks that live right next to the component consuming them, solving maintainability problems that become unavoidable as an application grows.

18 min read Fragment Colocation · Spreads · Codegen · Fragment Masking Apollo Client · GraphQL Codegen · React

1. Why large queries become unmaintainable without fragments

A typical page query in a growing React application collects fields for every component rendered on the page, header, product card, cart widget, footer. Without GraphQL fragments, all these fields end up in a single, monolithic query at the page's entry point, often hundreds of lines long. Every change to a single component requires a change to this central query, regardless of how deeply the component is nested in the tree.

The result is merge conflicts between team members working on different components of the same page, and a query that no one fully understands anymore. GraphQL fragments solve this problem structurally: each component declares exactly the fields it needs itself, in its own named fragment. The parent query merely combines these fragments, without needing to know each individual component's field list.

2. Fragment syntax: fragment Name on Type

The basic syntax of a GraphQL fragment is refreshingly simple: fragment FragmentName on TypeName { fields }. The type name after on defines which GraphQL type the fragment applies to, the field list inside the curly braces follows exactly the same syntax as in a normal query. A fragment can then be included in any query or any other fragment expecting the same or a compatible type, using the spread syntax ...FragmentName.


fragment ProductCardFields on Product {
  id
  name
  sku
  price
  thumbnailUrl
}

query ProductListPage {
  products(first: 20) {
    edges {
      node {
        ...ProductCardFields
      }
    }
  }
}

The benefit shows up immediately on reuse: ProductCardFields can be included in any query that renders a product card, whether it's a product list, a search result, or related products. When the product card gains a new field, only the fragment gets updated once, and every query that includes it automatically gets the new field, without needing to change itself.

3. Fragment colocation: fragments next to components

The fragment colocation pattern goes a step further than plain reuse: instead of collecting fragments in a central file, a component's fragment gets defined directly in the same file as the component itself. The component declares exactly which data it needs, right next to the code that renders that data. This reduces the cognitive distance between data requirement and data usage to zero.