GraphQL to Apollo React Hooks Generator

Convert GraphQL schema SDL to React Apollo hooks with TypeScript types and gql template literals.

What is GraphQL to Apollo React Hooks Generator?

Apollo Client is the most widely used GraphQL client for React applications, and its hook-based API (useQuery, useMutation, useLazyQuery) is the recommended way to fetch and manage GraphQL data in components. However, writing these hooks by hand is repetitive: each query needs a gql document, a variables interface, and a hook call with proper generic types. This tool automates that entire process by reading your GraphQL Schema Definition Language (SDL) and producing ready-to-import React hooks. It parses every field on the Query type into a useQuery and useLazyQuery hook, and every field on the Mutation type into a useMutation hook. Input types are converted to TypeScript interfaces with the Input suffix, and all GraphQL scalar types (String, Int, Float, Boolean, ID) are mapped to their TypeScript equivalents. The generated code uses the standard @apollo/client imports, so it integrates directly into any existing Apollo project without additional configuration.

How to Use

  1. Paste your complete GraphQL schema SDL — including Query, Mutation, and any input/object type definitions — into the left panel
  2. Press the Generate button to parse the schema and produce TypeScript hooks with gql documents and variable interfaces
  3. Inspect the output: each Query field yields a useQuery hook, a useLazyQuery variant, and a gql query document; each Mutation field yields a useMutation hook and a gql mutation document
  4. Copy the generated code into a dedicated file (e.g., generated/hooks.ts) in your React project
  5. Import the hooks in your components and customize the selection sets inside each gql template literal to match the fields your UI actually needs
  6. Run your app and verify that Apollo DevTools shows the expected operations

Why Use This Tool?

Eliminates boilerplate by auto-generating gql documents, variable interfaces, and typed hooks from a single schema
Provides full TypeScript safety: every hook is generic-typed with its data and variables shape, catching mismatches at compile time
Generates both eager (useQuery) and lazy (useLazyQuery) query hooks so you can choose the right fetching strategy per component
Keeps your hook layer in sync with the schema — regenerate whenever the API changes and get updated types instantly
Produces standard @apollo/client code that works with Apollo Cache, refetchQueries, optimistic responses, and all other Apollo features

Tips & Best Practices

  • The generated selection sets are minimal (e.g., { id } for lists). Always expand them to include every field your component renders before shipping
  • If your schema uses custom scalars (DateTime, JSON, etc.), add corresponding TypeScript type overrides after pasting the output
  • For pagination, combine the generated useQuery hook with Apollo's fetchMore method and a cursor-based pagination helper
  • Place the generated file in a separate directory (e.g., graphql/generated/) so it is easy to overwrite when you regenerate

Frequently Asked Questions

How are GraphQL types mapped to TypeScript?

Built-in scalars map as follows: String → string, Int → number, Float → number, Boolean → boolean, ID → string. Input types become TypeScript interfaces with the suffix "Input" appended (e.g., CreateUserInput stays as CreateUserInputInput). Object types referenced in the schema keep their original name as a TypeScript type.

When should I NOT use this generator?

If your project uses a code-first approach with tools like GraphQL Code Generator (graphql-codegen) that already produce typed hooks from .graphql documents, adding this tool would be redundant. It is also not suitable for schemas that rely heavily on custom directives or schema extensions that require special runtime handling.

Does it support GraphQL Subscriptions?

The current version focuses on queries and mutations. For subscriptions, you can manually write a useSubscription hook from @apollo/client using the same gql document pattern, or extend the generated code with subscription documents.

Is my schema data sent to a server?

No. All parsing and code generation happens entirely inside your browser. Your GraphQL schema never leaves your device, making this safe for proprietary or internal APIs.

Can I customize the generated hook names?

Hook names follow the convention use + PascalCase(fieldName). To change a name, simply rename the exported function after copying the output. The underlying gql document variable follows camelCase by convention and can also be renamed.

What happens if my schema has no Query or Mutation type?

The generator will produce only input type interfaces. At least one of Query or Mutation must be present for hook generation. If neither exists, the output will still contain the input interfaces but no hooks.

Real-world Examples

E-commerce product catalog with Apollo hooks

A storefront React app queries a product catalog and manages a shopping cart through mutations. The schema defines a Product type, a Cart type, and corresponding queries and mutations.

Input
type Query {
  products(category: String!): [Product!]!
  cart: Cart!
}

type Mutation {
  addToCart(productId: ID!, quantity: Int!): Cart!
}

type Product { id: ID! name: String! price: Float! }
type Cart { id: ID! items: [CartItem!]! total: Float! }
type CartItem { product: Product! quantity: Int! }
Output
import { gql, useQuery, useMutation, useLazyQuery } from '@apollo/client';

export const productsDocument = gql`
  query Products($category: String!) {
    products(category: $category) { id }
  }
`;

export function useProducts(variables: ProductsQueryVariables) {
  return useQuery<Array<Product>, ProductsQueryVariables>(
    productsDocument, { variables }
  );
}

export function useProductsLazy() {
  return useLazyQuery<Array<Product>, ProductsQueryVariables>(
    productsDocument
  );
}

export interface ProductsQueryVariables {
  category: string;
}

export const addToCartDocument = gql`
  mutation AddToCart($productId: ID!, $quantity: Int!) {
    addToCart(productId: $productId, quantity: $quantity) { id }
  }
`;

export function useAddToCart() {
  return useMutation<Cart, AddToCartMutationVariables>(
    addToCartDocument
  );
}

export interface AddToCartMutationVariables {
  productId: string;
  quantity: number;
}

Blog platform with lazy-loaded author details

A blog UI lists posts on the home page and lazily fetches full author profiles when a user clicks an author card. The useLazyQuery hook is ideal for this on-demand pattern.

Input
type Query {
  posts: [Post!]!
  author(id: ID!): Author
}

type Post { id: ID! title: String! author: Author! }
type Author { id: ID! name: String! bio: String }
Output
// usePosts — eager fetch on mount
export function usePosts() {
  return useQuery<Array<Post>, undefined>(postsDocument);
}

// useAuthorLazy — fetch only when triggered
export function useAuthorLazy() {
  return useLazyQuery<Author, AuthorQueryVariables>(
    authorDocument
  );
}

// Usage in component:
// const [fetchAuthor, { data }] = useAuthorLazy();
// <div onClick={() => fetchAuthor({ variables: { id: '1' } })}>

Related Tools