New to Claude Skills? Learn how to install them →

orval-labs on GitHub

Orval

Free

Generate type-safe API clients from OpenAPI specs.

by orval-labs6.3k stars on orval-labs/orval
3 views
Updated Aug 10, 2026
Get this skill

Free · Opens the source repo

What Orval does

Orval is a powerful tool designed for developers who need to generate type-safe TypeScript clients, hooks, schemas, mocks, and server handlers directly from OpenAPI v3 or Swagger v2 specifications. By automating the generation of these components, Orval streamlines the process of integrating APIs into applications, ensuring that the generated code adheres to the specifications provided. This helps eliminate common errors associated with manual coding, improving both development speed and reliability.

The setup process for Orval is straightforward. After installation, developers can define a minimal configuration to specify the target OpenAPI specification and the desired output files. Orval supports various client types, including TanStack Query for React, Vue, Svelte, Solid, and Angular, as well as custom HTTP clients like Axios and Fetch. This flexibility allows developers to choose the best tools for their specific projects while maintaining type safety throughout.

Orval also offers advanced configuration options, allowing users to customize input and output settings, manage authentication headers, and apply transformations to the OpenAPI spec before generation. This level of customization is particularly beneficial for larger applications with complex API requirements, where precise control over the generated code is necessary. Additionally, features like mock generation for testing and support for various output modes (single, split, tags-split) further enhance its utility.

In summary, Orval is an essential tool for developers looking to efficiently generate and manage type-safe API interactions in their TypeScript applications. Its comprehensive support for different frameworks and advanced configuration capabilities make it suitable for a wide range of projects, from small applications to large-scale enterprise solutions.

When to use it

Use Orval when you need to quickly generate API clients and schemas from OpenAPI specifications, especially in TypeScript projects.

When not to use it

Orval may not be suitable for projects that do not use TypeScript or do not rely on OpenAPI specifications for API definitions.

What you can build with it

Generating API Clients for a React App

Use Orval to quickly generate a type-safe API client for your React application using the TanStack Query hooks.

Creating Zod Schemas for Validation

Leverage Orval to generate Zod schemas from your OpenAPI specs, ensuring your data validation is type-safe.

Mocking API Responses for Testing

Utilize Orval to create MSW mocks for your API, facilitating easier testing of your application without relying on live data.

How to install Orval

View source

1. Install with the skills CLI

npx skills add orval-labs/orval/orval --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by orval-labs

Orval - OpenAPI to TypeScript Code Generator

Orval generates type-safe TypeScript clients, hooks, schemas, mocks, and server handlers from OpenAPI v3/Swagger v2 specifications.

Quick Start

Installation

npm install orval -D
# or yarn add orval -D
# or pnpm add orval -D
# or bun add orval -D

Minimal Configuration

import { defineConfig } from 'orval';

export default defineConfig({
  petstore: {
    input: {
      target: './petstore.yaml',
    },
    output: {
      target: './src/api/petstore.ts',
      schemas: './src/api/model',
      client: 'react-query',
    },
  },
});

Run

npx orval
npx orval --config ./orval.config.ts
npx orval --project petstore
npx orval --watch

Choosing Your Setup

Client Selection Guide

Use CaseClienthttpClientNotes
React with server statereact-queryfetch or axiosTanStack Query hooks
Vue 3 with server statevue-queryfetch or axiosTanStack Query for Vue
Svelte with server statesvelte-queryfetch or axiosTanStack Query for Svelte
SolidJS standalone appsolid-queryfetch or axiosTanStack Query for Solid
SolidStart full-stacksolid-startnative fetchUses query()/action() primitives
Angular with signalsangular-queryangularInjectable functions, signal reactivity
Angular traditionalangularHttpClient services
React with SWRswrfetch or axiosVercel SWR hooks
Lightweight / EdgefetchZero dependencies, works everywhere
Node.js / existing Axiosaxios-functionsFactory functions (default)
Axios with DIaxiosInjectable Axios instance
Validation onlyzodZod schemas, no HTTP client
Backend API serverhonoHono handlers with Zod validation
AI agent toolsmcpModel Context Protocol servers

Mode Selection Guide

  • single — Everything in one file. Best for small APIs.
  • split — Separate files: petstore.ts, petstore.schemas.ts, petstore.msw.ts. Good for medium APIs.
  • tags — One file per OpenAPI tag + shared schemas. Organizes by domain.
  • tags-split — Folder per tag with split files. Best for large APIs. Recommended.

httpClient Option

For react-query, vue-query, svelte-query, and swr clients:

output: {
  client: 'react-query',
  httpClient: 'fetch',  // 'fetch' (default) | 'axios'
}

For angular-query:

output: {
  client: 'angular-query',
  httpClient: 'angular',  // Uses Angular HttpClient
}

Configuration Reference

Config Structure

import { defineConfig } from 'orval';

export default defineConfig({
  [projectName]: {
    input: InputOptions,
    output: OutputOptions,
    hooks: HooksOptions,
  },
});

Multiple projects can share the same config file with different input/output settings.

Input Options

input: {
  target: './spec.yaml',              // Path or URL to OpenAPI spec (required)
  override: {
    transformer: './transform.js',    // Transform spec before generation
  },
  filters: {
    mode: 'include',                  // 'include' | 'exclude'
    tags: ['pets', /health/],         // Filter by OpenAPI tags
    schemas: ['Pet', /Error/],        // Filter by schema names
  },
  parserOptions: {
    headers: [                        // Auth headers for remote spec URLs
      {
        domains: ['api.example.com'],
        headers: {
          Authorization: 'Bearer YOUR_TOKEN',
          'X-API-Key': 'your-api-key',
        },
      },
    ],
  },
}

Output Options

output: {
  target: './src/api/endpoints.ts',     // Output path (required)
  client: 'react-query',               // Client type (see table above)
  httpClient: 'fetch',                  // 'fetch' (default) | 'axios' | 'angular'
  mode: 'tags-split',                   // 'single' | 'split' | 'tags' | 'tags-split'
  schemas: './src/api/model',           // Output path for model types
  operationSchemas: './src/api/params', // Separate path for operation-derived types
  workspace: 'src/',                    // Base folder for all files
  fileExtension: '.ts',                 // Custom file extension
  namingConvention: 'camelCase',        // File naming: camelCase | PascalCase | snake_case | kebab-case
  indexFiles: true,                     // Generate index.ts barrel files
  clean: true,                          // Clean output before generating
  prettier: true,                       // Format with Prettier
  biome: true,                          // Format with Biome
  headers: true,                        // Generate header parameters
  baseUrl: '/api/v2',                   // API base URL
  // or from spec:
  // baseUrl: { getBaseUrlFromSpecification: true, index: 0, variables: { environment: 'api.dev' } },
  mocks: true,                          // Generate MSW + Faker mocks (boolean, object, or function)
  docs: true,                           // Generate TypeDoc documentation
  // docs: { configPath: './typedoc.config.mjs' },
  allParamsOptional: true,              // Make all params optional (except path params)
  urlEncodeParameters: true,            // URL-encode path/query parameters
  optionsParamRequired: false,          // Make options parameter required
  propertySortOrder: 'Specification',   // 'Alphabetical' | 'Specification'
  tsconfig: './tsconfig.json',          // Custom tsconfig path
  override: { ... },                    // Advanced overrides (see below)
}

Multiple API Specs

export default defineConfig({
  petstoreV1: {
    input: { target: './specs/v1.yaml' },
    output: { target: 'src/api/v1', client: 'react-query' },
  },
  petstoreV2: {
    input: { target: './specs/v2.yaml' },
    output: { target: 'src/api/v2', client: 'react-query' },
  },
});

Filter Endpoints

input: {
  target: './spec.yaml',
  filters: {
    mode: 'include',
    tags: ['pets'],
  },
}

Detailed Guides

When the user's question involves a specific topic below, read the corresponding file from this skill's directory.

TopicFileLoad when user asks about...
TanStack Query / SWRtanstack-query.mdReact Query, Vue Query, Svelte Query, Solid Query, SWR, query hooks, invalidation, infinite queries, suspense, prefetch
Angularangular.mdAngular Query, Angular HttpClient, signals, inject functions, Angular services, providedIn
SolidStartsolid-start.mdSolidStart, @solidjs/router, query(), action(), createAsync, revalidate
Custom HTTP / Authcustom-http-clients.mdCustom mutator, authentication, tokens, interceptors, custom fetch/axios, baseURL, hook-based mutator
Zod Validationzod-validation.mdZod schemas, validation, runtime validation, coerce, strict, preprocess
Mocking / MSWmocking-msw.mdMSW mocks, testing, test setup, faker, Vitest, mock handlers, useExamples
Hono Serverhono.mdHono handlers, zValidator, composite routes, context types, server-side generation
Advanced Configadvanced-config.mdType generation, enums, per-operation overrides, FormData, JSDoc, params serializer, full example
Tooling / Workflowtooling-workflow.mdProgrammatic API, transformers, hooks, NDJSON streaming, MCP, afterAllFilesWrite

OpenAPI Specification Best Practices

  1. Use unique operationId for every operation — Orval uses these for function and hook names
  2. Define reusable schemas in components/schemas — reduces duplication in generated types
  3. Use tags to group operations — works with tags and tags-split modes
  4. Define response types for all operations — enables full type safety
  5. Mark required fields — affects optional/required in generated TypeScript interfaces
  6. Use x-enumNames for numeric enums — generates readable const names
  7. Provide example values — used by mock generation when useExamples: true
  8. Use application/x-ndjson content type for streaming endpoints — enables typed NDJSON generation

CLI Reference

orval                                    # Generate using auto-discovered config
orval --config ./api/orval.config.ts     # Specify config file
orval --project petstore                 # Run specific project(s)
orval --watch                            # Watch mode
orval --watch ./src                      # Watch specific directory
orval --clean                            # Clean generated files
orval --prettier                         # Format with Prettier
orval --biome                            # Format with Biome
orval --tsconfig ./src/tsconfig.json     # Custom tsconfig path
orval --mode split                       # Override output mode
orval --client react-query               # Override client
orval --mock                             # Override mock generation
orval --input ./spec.yaml --output ./api.ts  # Direct generation

Resources

Frequently asked questions about Orval

Similar skills