Axon 911 Frontend DocsAxon 911 Frontend Docs
Axon 911 Frontend Docs
    Loading navigation…
U
User
Switch to light mode
  1. Working With Data
  2. Graphql Colocation

GraphQL Colocation

Organizing GraphQL files with components using near-operation-file pattern

Now that you know how to write GraphQL operations, let's discuss where to organize them. Colocation keeps your GraphQL files next to the components that use them, improving discoverability and maintainability.
What Colocation Means
In our GraphQL setup, "colocation" refers to the near-operation-file preset pattern where:
  • .graphql files are placed in the same folder as the components that use them
  • Generated TypeScript files (.graphql.ts) are created alongside the .graphql files
  • This is NOT about embedding GraphQL strings directly in component files
This approach, documented in the Guild's near-operation-file guide, provides the best balance of organization and type safety.
Directory Structure
Query Roots Own Operations, Components Own Fragments
The route, or a remote's top-level view, owns the request, so its folder holds the operations. Every component below it owns a fragment instead:
See GraphQL Fragments for what counts as a query root.
Benefits of This Approach
  1. Discoverability: a screen's operations sit next to its root, and a component's fragment sits next to the component
  2. Maintainability: Easy to update a fragment when modifying its component
  3. Type Safety: Generated types are imported from the same directory
  4. Modularity: Components are self-contained with their data requirements
  5. Refactoring: Moving a component moves its fragment
Before and After Examples
❌ Don't do this - Centralized Operations
Old Pattern: All operations in a central location
Problems:
  • Operations disconnected from components
  • Hard to find what queries a component uses
  • Refactoring requires hunting down imports
  • No clear ownership of operations
  • Leads to bloated operations files that request too much data and query too many levels deep.
  • Types become difficult to reason about and maintain.
✅ Do this - Colocated Operations
New Pattern: The root's operations next to the root, each component's fragment next to the component
Benefits:
  • Clear ownership and organization
  • Easy to see a component's data needs
  • One request per screen, with no component fetching on its own
  • Types are scoped to the component and are easy to reason about
How Generated Files Work
When codegen runs (at the start of pnpm dev, or manually with pnpm turbo run codegen), the near-operation-file preset:
  1. Finds all .graphql files in your app
  2. Generates a .graphql.ts file next to each one
  3. Includes typed document nodes and operation types
Example Generated Output
For this operation:
Generates this TypeScript file:
Important: NOT Inline GraphQL
❌ Don't do this - Inline GraphQL Strings
✅ Do this - Separate .graphql Files
Organizing a Complex Query Root
A root with several operations keeps them in one folder:
If the root is also a component that reads its own fields, it has a fragments.graphql like any other component.
Best Practices
✅ Do
  • Place .graphql files next to the code that uses them, under src/ of an app, remote, or package
  • Put a screen's operations next to its query root, and each component's fragment next to the component
  • Group related operations in the same file
❌ Don't
  • Put GraphQL strings directly in component files (pnpm lint:graphql rejects gql imports and tags outside tests)
  • Put a .graphql file anywhere codegen does not read, such as a remote's exposes/ directory
  • Name a document anything but queries.graphql, mutations.graphql, subscriptions.graphql, or fragments.graphql
  • Create deeply nested GraphQL folders
  • Share component-specific operations
  • Manually edit generated .graphql.ts files
  • Add a queries.graphql to a component below the query root: it declares a fragment instead
Cross-Feature Contracts
A fragment belongs to one component and never moves between features; it reaches a query only through its parent's spread. If two components need the same fields, each declares its own fragment. The full rules are in GraphQL Fragments. Next, we'll learn how fragments and data masking work.
Previous
Working with data / GraphQL Operations
Next
Working with data / GraphQL Fragments
On this page
What Colocation Means
Directory Structure
Query Roots Own Operations, Components Own Fragments
Benefits of This Approach
Before and After Examples
❌ Don't do this - Centralized Operations
✅ Do this - Colocated Operations
How Generated Files Work
Example Generated Output
Important: NOT Inline GraphQL
❌ Don't do this - Inline GraphQL Strings
✅ Do this - Separate .graphql Files
Organizing a Complex Query Root
Best Practices
✅ Do
❌ Don't
Cross-Feature Contracts