Skill

Encode GraphQL schema patterns into reusable Claude skills

A skill for GraphQL query/mutation patterns with Apollo Client - generated hooks, codegen, and mandatory error handling.

Works with githubjiralineargraphqltypescript

48
Spark score
out of 100
Updated 6 months ago
Version 1.0.0

Add to Favorites

Why it matters

Teach Claude Code your team's GraphQL schema conventions, mutation patterns, and type safety standards so it generates schema definitions, resolvers, and queries that match your existing codebase architecture without manual correction.

Outcomes

What it gets done

01

Document GraphQL schema structure conventions (types, inputs, mutations, queries)

02

Define resolver patterns and error handling standards for GraphQL operations

03

Specify type safety rules and nullable field conventions for schema design

04

Establish naming patterns for GraphQL entities, fields, and operation signatures

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/ag-graphql-schema | bash

Overview

GraphQL Schema Patterns

This skill covers GraphQL query and mutation patterns with Apollo Client: .gql files and codegen, generated hooks, mandatory mutation error/loading handling, fetch policies, and optimistic updates. Use it when creating GraphQL operations, working with Apollo Client, or generating types from a GraphQL schema.

What it does

A skill for GraphQL query/mutation patterns and code generation with Apollo Client. Four core rules: never write inline gql template literals - create .gql files instead; always run codegen after creating or modifying a .gql file; always attach an onError handler to mutations; and always use the generated hooks, never raw Apollo useQuery/useMutation. Queries follow a three-step flow: write a .gql file (e.g. GetItems.gql with typed variables), run npm run gql:typegen to produce a GetItems.generated.ts (never hand-edited), then import and use the generated useGetItemsQuery hook, checking error/loading/empty states explicitly before rendering data. Mutations follow the same flow but every trigger must meet four requirements: disabled during the mutation (prevents double-clicks), a visible loading state, a required onError handler so the user knows about failure, and success feedback on completion - shown via a documented complete pattern combining isDisabled/isLoading on the button with onError and onCompleted toasts. Query options cover four fetch policies (cache-first for rarely-changing data, cache-and-network as the fast-plus-fresh default, network-only for always-latest data, no-cache for the rare case of never caching) plus common options like notifyOnNetworkStatusChange, skip for conditional queries, and pollInterval for periodic refetching. Optimistic updates provide instant UI feedback via optimisticResponse, with automatic rollback on error - but are explicitly not for operations that can fail validation, have server-generated values, are destructive (delete), or affect other users. Reusable field selections use named fragments (e.g. a shared ItemFields fragment spread into multiple queries). Documented anti-patterns show the wrong-vs-right side by side: inline gql instead of a generated hook, a mutation with no error handler, and a submit button that stays enabled/unlabeled during a pending mutation. Two codegen commands are documented: npm run gql:typegen (generate types from existing .gql files) and npm run sync-types (download the schema and generate types). This skill integrates with react-ui-patterns for loading/error/empty states, testing-patterns for mocking generated hooks in tests, and formik-patterns for mutation submission.

When to use - and when NOT to

Use it when creating GraphQL queries or mutations, working with Apollo Client, or generating types from a GraphQL schema.

Inputs and outputs

Given a GraphQL operation need, it produces a .gql file plus the codegen command to run, and the resulting generated hook usage with required loading/error/empty-state handling and, for mutations, the mandatory disabled/loading/onError/success pattern.

Integrations

npm run gql:typegen
npm run sync-types

Apollo Client with GraphQL code generation - generated hooks, fragments, cache.modify for manual cache updates, and optimisticResponse for instant UI feedback with automatic error rollback.

Who it's for

Frontend developers working with Apollo Client and GraphQL who want consistent, type-safe query and mutation patterns - generated hooks instead of inline gql, mandatory error handling on every mutation trigger, and clear guidance on when optimistic updates are and aren't appropriate.

Source README

GraphQL Schema Patterns

When to Use

Use this skill when you need graphQL queries, mutations, and code generation patterns. Use when creating GraphQL operations, working with Apollo Client, or generating types.

Core Rules

  1. NEVER inline gql literals - Create .gql files
  2. ALWAYS run codegen after creating/modifying .gql files
  3. ALWAYS add onError handler to mutations
  4. Use generated hooks - Never write raw Apollo hooks

File Structure

src/
├── components/
│   └── ItemList/
│       ├── ItemList.tsx
│       ├── GetItems.gql           # Query definition
│       └── GetItems.generated.ts  # Auto-generated (don't edit)
└── graphql/
    └── mutations/
        └── CreateItem.gql         # Shared mutations

Creating a Query

Step 1: Create .gql file

### src/components/ItemList/GetItems.gql
query GetItems($limit: Int, $offset: Int) {
  items(limit: $limit, offset: $offset) {
    id
    name
    description
    createdAt
  }
}

Step 2: Run codegen

npm run gql:typegen

Step 3: Import and use generated hook

import { useGetItemsQuery } from './GetItems.generated';

const ItemList = () => {
  const { data, loading, error, refetch } = useGetItemsQuery({
    variables: { limit: 20, offset: 0 },
  });

  if (error) return <ErrorState error={error} onRetry={refetch} />;
  if (loading && !data) return <LoadingSkeleton />;
  if (!data?.items.length) return <EmptyState />;

  return <List items={data.items} />;
};

Creating a Mutation

Step 1: Create .gql file

### src/graphql/mutations/CreateItem.gql
mutation CreateItem($input: CreateItemInput!) {
  createItem(input: $input) {
    id
    name
    description
  }
}

Step 2: Run codegen

npm run gql:typegen

Step 3: Use with REQUIRED error handling

import { useCreateItemMutation } from 'graphql/mutations/CreateItem.generated';

const CreateItemForm = () => {
  const [createItem, { loading }] = useCreateItemMutation({
    // Success handling
    onCompleted: (data) => {
      toast.success({ title: 'Item created' });
      navigation.goBack();
    },
    // ERROR HANDLING IS REQUIRED
    onError: (error) => {
      console.error('createItem failed:', error);
      toast.error({ title: 'Failed to create item' });
    },
    // Cache update
    update: (cache, { data }) => {
      if (data?.createItem) {
        cache.modify({
          fields: {
            items: (existing = []) => [...existing, data.createItem],
          },
        });
      }
    },
  });

  return (
    <Button
      onPress={() => createItem({ variables: { input: formValues } })}
      isDisabled={!isValid || loading}
      isLoading={loading}
    >
      Create
    </Button>
  );
};

Mutation UI Requirements

CRITICAL: Every mutation trigger must:

  1. Be disabled during mutation - Prevent double-clicks
  2. Show loading state - Visual feedback
  3. Have onError handler - User knows it failed
  4. Show success feedback - User knows it worked
// CORRECT - Complete mutation pattern
const [submit, { loading }] = useSubmitMutation({
  onError: (error) => {
    console.error('submit failed:', error);
    toast.error({ title: 'Save failed' });
  },
  onCompleted: () => {
    toast.success({ title: 'Saved' });
  },
});

<Button
  onPress={handleSubmit}
  isDisabled={!isValid || loading}
  isLoading={loading}
>
  Submit
</Button>

Query Options

Fetch Policies

Policy Use When
cache-first Data rarely changes
cache-and-network Want fast + fresh (default)
network-only Always need latest
no-cache Never cache (rare)

Common Options

useGetItemsQuery({
  variables: { id: itemId },

  // Fetch strategy
  fetchPolicy: 'cache-and-network',

  // Re-render on network status changes
  notifyOnNetworkStatusChange: true,

  // Skip if condition not met
  skip: !itemId,

  // Poll for updates
  pollInterval: 30000,
});

Optimistic Updates

For instant UI feedback:

const [toggleFavorite] = useToggleFavoriteMutation({
  optimisticResponse: {
    toggleFavorite: {
      __typename: 'Item',
      id: itemId,
      isFavorite: !currentState,
    },
  },
  onError: (error) => {
    // Rollback happens automatically
    console.error('toggleFavorite failed:', error);
    toast.error({ title: 'Failed to update' });
  },
});

When NOT to Use Optimistic Updates

  • Operations that can fail validation
  • Operations with server-generated values
  • Destructive operations (delete)
  • Operations affecting other users

Fragments

For reusable field selections:

### src/graphql/fragments/ItemFields.gql
fragment ItemFields on Item {
  id
  name
  description
  createdAt
  updatedAt
}

Use in queries:

query GetItems {
  items {
    ...ItemFields
  }
}

Anti-Patterns

// WRONG - Inline gql
const GET_ITEMS = gql`
  query GetItems { items { id } }
`;

// CORRECT - Use .gql file + generated hook
import { useGetItemsQuery } from './GetItems.generated';


// WRONG - No error handler
const [mutate] = useMutation(MUTATION);

// CORRECT - Always handle errors
const [mutate] = useMutation(MUTATION, {
  onError: (error) => {
    console.error('mutation failed:', error);
    toast.error({ title: 'Operation failed' });
  },
});


// WRONG - Button not disabled during mutation
<Button onPress={submit}>Submit</Button>

// CORRECT - Disabled and loading
<Button onPress={submit} isDisabled={loading} isLoading={loading}>
  Submit
</Button>

Codegen Commands

### Generate types from .gql files
npm run gql:typegen

### Download schema + generate types
npm run sync-types

Integration with Other Skills

  • react-ui-patterns: Loading/error/empty states for queries
  • testing-patterns: Mock generated hooks in tests
  • formik-patterns: Mutation submission patterns

Limitations

  • Use this skill only when the task clearly matches its upstream source and local project context.
  • Verify commands, generated code, dependencies, credentials, and external service behavior before applying changes.
  • Do not treat examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.