Skip to content

Relay

Relay is a powerful JavaScript framework for building data-driven React applications using GraphQL. Developed by Facebook, Relay emphasizes performance, scalability, and maintainability.


Why Use Relay?

✅ Declarative data fetching with co-located queries
✅ Automatic data consistency and normalization
✅ Built-in pagination and mutations
✅ Optimized for large-scale applications


Key Concepts

1. Colocation

Relay encourages colocating GraphQL fragments with the components that use them, improving modularity and maintainability.

2. Normalized Cache

Relay stores data in a normalized format (like a database), which allows efficient updates and cache reuse across components.

3. Fragments

Relay components declare fragments for their data requirements. These are composed automatically into larger queries.


Installation

Relay requires some setup for compilation and schema introspection.

npm install react-relay
npm install --save-dev relay-compiler

Also install the graphql package:

npm install graphql

Schema Setup

Relay needs a GraphQL schema in .graphql or JSON format.

npx graphql-inspector introspect-schema http://localhost:4000/graphql > schema.graphql

Configure relay.config.js:

module.exports = {
  src: "./src",
  schema: "./schema.graphql",
  language: "javascript",
};

Run the compiler:

npx relay-compiler

Basic Example

Define a Fragment

// User.js
import { graphql, useFragment } from "react-relay";

const userFragment = graphql`
  fragment User_user on User {
    id
    name
    email
  }
`;

export default function User({ userRef }) {
  const data = useFragment(userFragment, userRef);
  return (
    <div>
      <p>
        {data.name} - {data.email}
      </p>
    </div>
  );
}

Parent Query

// App.js
import { graphql, useLazyLoadQuery } from "react-relay";
import User from "./User";

const query = graphql`
  query AppQuery {
    user(id: "1") {
      ...User_user
    }
  }
`;

export default function App() {
  const data = useLazyLoadQuery(query, {});
  return <User userRef={data.user} />;
}

Mutations

Relay uses the commitMutation function to perform mutations.

import { commitMutation, graphql } from "react-relay";

const mutation = graphql`
  mutation AddUserMutation($input: CreateUserInput!) {
    createUser(input: $input) {
      user {
        id
        name
      }
    }
  }
`;

function addUser(environment, input) {
  return commitMutation(environment, {
    mutation,
    variables: { input },
    onCompleted: (response) => {
      console.log("User created:", response.createUser.user);
    },
  });
}

Pagination

Relay supports cursor-based pagination out of the box using @connection and usePaginationFragment.

fragment UsersList_users on UserConnection
@argumentDefinitions(
  first: { type: "Int", defaultValue: 5 }
  after: { type: "String" }
)
@refetchable(queryName: "UsersListPaginationQuery") {
  edges {
    node {
      id
      name
    }
  }
}

Best Practices

  • ✅ Use fragments for modular data dependencies
  • ✅ Normalize schema with Relay-specific directives
  • ✅ Rely on compiler for static validation
  • ✅ Avoid over-fetching; fetch only what's used
  • ✅ Structure your app around component-based data requirements

Limitations

  • Steeper learning curve than Apollo Client
  • Requires GraphQL schema and compiler step
  • Not ideal for small apps or quick prototyping

Tools & Resources


Summary

Relay is a powerful and opinionated GraphQL client for React. It provides an efficient, scalable way to build applications with deeply integrated data requirements — making it ideal for large, performance-sensitive apps.