Design production-grade GraphQL schemas with best practices and patterns
View on GitHubpluginagentmarketplace/custom-plugin-graphql
developer-roadmap
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/pluginagentmarketplace/custom-plugin-graphql/blob/main/skills/graphql-schema-design/SKILL.md -a claude-code --skill graphql-schema-designInstallation paths:
.claude/skills/graphql-schema-design/# GraphQL Schema Design Skill
> Architect scalable, maintainable GraphQL APIs
## Overview
Learn industry-standard patterns for designing GraphQL schemas that scale. Covers naming conventions, pagination, error handling, and schema evolution.
---
## Quick Reference
| Pattern | When to Use | Example |
|---------|-------------|---------|
| Connection | Paginated lists | `users: UserConnection!` |
| Payload | Mutation results | `CreateUserPayload` |
| Input | Mutation args | `CreateUserInput` |
| Interface | Shared fields | `interface Node { id: ID! }` |
| Union | Multiple types | `SearchResult = User \| Post` |
---
## Core Patterns
### 1. Naming Conventions
```graphql
# Types: PascalCase
type User { }
type UserProfile { }
# Fields: camelCase
type User {
firstName: String!
lastName: String!
createdAt: DateTime!
isActive: Boolean! # Boolean prefix: is, has, can
}
# Queries: noun (singular/plural)
type Query {
user(id: ID!): User # Singular
users: UserConnection! # Plural
}
# Mutations: verb + noun
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
deleteUser(id: ID!): DeleteUserPayload!
# Actions
sendEmail(input: SendEmailInput!): SendEmailPayload!
publishPost(id: ID!): PublishPostPayload!
}
# Inputs: [Action][Type]Input
input CreateUserInput { }
input UpdateUserInput { }
input UserFilterInput { }
# Payloads: [Action][Type]Payload
type CreateUserPayload { }
type UpdateUserPayload { }
```
### 2. Relay-Style Pagination
```graphql
# Connection pattern
type Query {
users(
first: Int
after: String
last: Int
before: String
filter: UserFilter
): UserConnection!
}
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type UserEdge {
node: User!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: Stri