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.
Also install the graphql
package:
Schema Setup
Relay needs a GraphQL schema in .graphql
or JSON format.
Configure relay.config.js
:
Run the 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.