@pretto/vite-graphql-codegen-loader
v0.9.0
Published
Vite plugin for GraphQL code generation
Readme
@pretto/vite-graphql-codegen-loader
Vite plugin that generates TypeScript types and framework-specific Apollo hooks from GraphQL files during development and build.
Features
- 🔥 Hot reload - Types and hooks generated on-the-fly
- 🎯 Multiple schemas - Support for multiple GraphQL schemas
- 📦 Smart fragment support - Automatic fragment loading with intelligent filtering (only includes used fragments)
- 🚀 Multi-framework - React Apollo hooks & Vue Apollo composables
- ⚡ Vite optimized - Fast builds with caching
- 🔄 Auto-generated schema files - Centralized
enums.tsandschema.d.tsfiles regenerated on startup - 🏗️ Pre-generation - All GraphQL files are pre-generated at build start (no import required)
- 🎯 Optimized output - Fragment tree-shaking ensures minimal file sizes
Installation
yarn add @pretto/vite-graphql-codegen-loaderConfiguration
// vite.config.ts
import { graphqlCodegenPlugin } from "@pretto/vite-graphql-codegen-loader";
export default defineConfig({
plugins: [
graphqlCodegenPlugin({
framework: "react", // Required: "react", "vue", or "none"
debug: true, // Enable debug logs in development
schemas: {
api: {
url: "https://api.example.com/graphql",
match: "*.api.graphql", // Files ending with .api.graphql use this schema
},
gateway: {
file: "./src/schema.graphql",
match: "*.gateway.graphql", // Files ending with .gateway.graphql use this schema
fragmentsPaths: [
"./src/fragments/**/*.graphql", // Glob patterns supported
],
},
},
schemaTypesPath: "./src/types",
scalars: {
DateTime: "string",
Date: "string",
JSON: "any",
},
}),
],
});How it Works
Automatic Pre-generation
The plugin automatically pre-generates TypeScript types for ALL GraphQL files in your project at build start. This means:
- ✅ You don't need to import GraphQL files before their types are available
- ✅ No "chicken-and-egg" problem with circular dependencies
- ✅ All hooks and types are immediately available for use
Smart Fragment Filtering
When using fragments, the plugin intelligently analyzes your GraphQL operations and only includes the fragments that are actually used:
- 📉 Smaller generated files (only necessary fragments included)
- 🔍 Recursive fragment resolution (nested fragments are properly detected)
- ⚡ Better performance with minimal bundle size
Usage
Create GraphQL files with .api.graphql or .gateway.graphql extensions:
# queries.api.graphql
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
mutation UpdateUser($input: UserInput!) {
updateUser(input: $input) {
id
name
}
}With Fragments
# user.gateway.graphql
query GetUserWithDetails {
user {
...UserDetails # Only this fragment will be included
}
}
# fragments.graphql (configured in fragmentsPaths)
fragment UserDetails on User {
id
name
profile {
...ProfileInfo # Nested fragment also included
}
}
fragment ProfileInfo on Profile {
avatar
bio
}
fragment UnusedFragment on User { # This won't be included in generated file
someField
}The plugin automatically generates:
Centralized Schema Files (per schema)
src/types/api/enums.ts- All GraphQL enums from the API schemasrc/types/api/schema.d.ts- All TypeScript types from the API schemasrc/types/gateway/enums.ts- All GraphQL enums from the Gateway schemasrc/types/gateway/schema.d.ts- All TypeScript types from the Gateway schema
These files are regenerated on every Vite startup, ensuring they stay up-to-date with the latest schema changes. You can safely add them to .gitignore.
Per-Query Files
// queries.api.graphql.d.ts - TypeScript types
export type GetUserQuery = { ... }
export type UpdateUserMutation = { ... }
// queries.api.graphql - JavaScript runtime
export const GetUserDocument = gql`...`
export function useGetUserQuery(options) { ... } // React hooks or Vue composables based on framework
export function useUpdateUserMutation(options) { ... }Import and use:
React
import { useGetUserQuery, useUpdateUserMutation } from "./queries.api.graphql";
function UserProfile({ userId }: { userId: string }) {
const { data, loading } = useGetUserQuery({ variables: { id: userId } });
const [updateUser] = useUpdateUserMutation();
// TypeScript knows the exact shape of data!
}Vue
import { useGetUserQuery, useUpdateUserMutation } from "./queries.api.graphql";
export default {
setup() {
const { result, loading } = useGetUserQuery({ id: userId });
const { mutate: updateUser } = useUpdateUserMutation();
// TypeScript knows the exact shape of data!
return { result, loading, updateUser };
}
}Configuration Options
| Option | Type | Default | Description |
| ----------------- | ------------------------------ | ------------- | --------------------------------------------- |
| framework | "react" \| "vue" \| "none" | required | Target framework for hook/composable generation |
| debug | boolean | false | Enable debug logging |
| schemas | Record<string, SchemaConfig> | {} | Schema configurations |
| schemaTypesPath | string | "src/types" | Path for centralized schema files |
| scalars | Record<string, string> | {} | Custom scalar type mappings |
Schema Configuration
interface SchemaConfig {
url?: string; // Remote GraphQL endpoint
file?: string; // Local schema file
match?: string; // File pattern to match (e.g., "*.api.graphql")
fragmentsPaths?: string[]; // Fragment files to include (supports glob patterns)
}Framework Options
react(default): Generates React Apollo hooks (useQuery,useMutation, etc.)vue: Generates Vue Apollo composables (useQuery,useMutation, etc.)none: Only generates TypeScript types without framework-specific hooks
Development
# Install dependencies
yarn install
# Development mode
yarn dev
# Build
yarn buildLicense
MIT
