How can OpenAPI specifications be split across multiple files? #
A single OpenAPI document can grow unwieldy as an API matures. A real-world API with dozens of resources, hundreds of operations, and shared schemas can produce a monolithic YAML file that is difficult to navigate, review in pull requests, and maintain across teams. The solution is to split the OpenAPI specification across multiple files using $ref references, and then bundle them back into a single resolved document for tooling consumption. This approach, often called a “multi-file” or “modular” OpenAPI structure, is widely adopted in professional API development.
Why Split OpenAPI Documents? #
Maintainability #
Large monolithic OpenAPI files are hard to edit. A modular structure lets different team members work on different parts of the API without constant merge conflicts. For example, one team can own the /orders path definitions while another owns the /users paths.
Reusability #
Schemas that appear in multiple operations — like a Pagination envelope, an Error object, or an Address schema — can be defined once in a shared file and referenced from multiple locations without duplication.
Readability #
A file with 3,000 lines of YAML is difficult to navigate. A modular structure with meaningful file names makes the API surface area immediately apparent:
openapi.yaml # root document
paths/
users.yaml # /users operations
orders.yaml # /orders operations
products.yaml # /products operations
schemas/
User.yaml
Order.yaml
Product.yaml
Error.yaml
parameters/
common.yaml # shared parameters (pagination, etc.)
responses/
common.yaml # shared responses (400, 401, 404, 500)
Governance and Ownership #
In API-first organizations, individual files can be owned by specific teams. Code review tooling like GitHub’s CODEOWNERS can enforce that only the responsible team can approve changes to their portion of the API.
Using $ref for External File References
#
The $ref keyword in OpenAPI (and JSON Schema) supports references to external files using relative or absolute paths, in addition to in-document anchors. A reference to an external file looks like this:
# openapi.yaml
paths:
/users:
$ref: './paths/users.yaml'
/orders:
$ref: './paths/orders.yaml'
components:
schemas:
User:
$ref: './schemas/User.yaml'
Order:
$ref: './schemas/Order.yaml'
Error:
$ref: './schemas/Error.yaml'
The referenced files can themselves contain $ref references to other files, enabling deep composition.
Path File Example #
# paths/users.yaml
get:
summary: List users
operationId: listUsers
tags: [Users]
parameters:
- $ref: '../parameters/common.yaml#/parameters/PageSize'
- $ref: '../parameters/common.yaml#/parameters/PageToken'
responses:
"200":
description: A paginated list of users
content:
application/json:
schema:
$ref: '../schemas/UserList.yaml'
"400":
$ref: '../responses/common.yaml#/responses/BadRequest'
"401":
$ref: '../responses/common.yaml#/responses/Unauthorized'
post:
summary: Create a user
operationId: createUser
tags: [Users]
requestBody:
required: true
content:
application/json:
schema:
$ref: '../schemas/CreateUserRequest.yaml'
responses:
"201":
description: User created
content:
application/json:
schema:
$ref: '../schemas/User.yaml'
Fragment References Within External Files #
$ref supports referencing a specific node within an external file using a JSON Pointer fragment:
$ref: './parameters/common.yaml#/parameters/PageSize'
This references the PageSize key under parameters in common.yaml. This allows a single shared file to contain multiple related definitions.
Bundling: Resolving to a Single File #
While multi-file structures are excellent for authoring, most OpenAPI tools expect a single, fully-resolved document. The process of combining all referenced files into one is called bundling. Bundling can be done:
- Inline — replacing each
$refwith the full content of the referenced object. - Dereferenced — resolving all
$refs but maintaining thecomponentsstructure. - Bundled — collecting all external references into
componentsand replacing external$refs with local$refs within the same file.
Bundling Tools #
Redocly CLI is the most popular tool for bundling multi-file OpenAPI documents:
redocly bundle openapi.yaml -o openapi.bundled.yaml
It supports linting as part of the bundle step, catching errors before they propagate.
swagger-cli (deprecated but still widely used):
swagger-cli bundle openapi.yaml -o bundled.yaml -t yaml
@apidevtools/swagger-parser — a JavaScript library for resolving, dereferencing, and validating OpenAPI documents programmatically:
import SwaggerParser from "@apidevtools/swagger-parser";
const api = await SwaggerParser.bundle("openapi.yaml");
openapi-typescript and many generator tools can process multi-file documents directly without a separate bundling step.
Recommended Directory Structure #
A widely adopted convention for large OpenAPI projects:
api/
├── openapi.yaml # Root document with info, servers, security
├── paths/
│ ├── users.yaml # Operations for /users
│ ├── users_{id}.yaml # Operations for /users/{id}
│ ├── orders.yaml
│ └── products.yaml
├── schemas/
│ ├── User.yaml
│ ├── Order.yaml
│ ├── Product.yaml
│ ├── CreateUserRequest.yaml
│ └── Error.yaml
├── parameters/
│ └── common.yaml # Shared parameters
├── responses/
│ └── common.yaml # Shared responses
└── examples/
├── UserExample.yaml
└── OrderExample.yaml
The root openapi.yaml serves only as the entry point, delegating to path and component files:
openapi: 3.1.0
info:
title: Example API
version: 1.0.0
servers:
- url: https://api.example.com/v1
paths:
/users:
$ref: './paths/users.yaml'
/users/{id}:
$ref: './paths/users_{id}.yaml'
/orders:
$ref: './paths/orders.yaml'
Linting Multi-File Documents #
Spectral and Redocly CLI both support linting multi-file documents by following $ref references during analysis:
spectral lint openapi.yaml
redocly lint openapi.yaml
Both tools resolve all references before applying rules, so governance checks apply across the entire API surface regardless of how it is split.
Version Control Best Practices #
When managing a multi-file OpenAPI project in Git:
- Use pull requests for schema changes — individual schema files are small enough to review meaningfully in a PR diff.
- Configure CODEOWNERS — assign ownership of path files to the teams responsible for those endpoints.
- Use a bundling step in CI — always generate and commit (or publish) the bundled document as a CI artifact, so downstream consumers always have a stable, resolved version to reference.
- Tag releases — version the bundled document using Git tags to support consumer pinning.
Conclusion #
Splitting OpenAPI specifications across multiple files is a proven strategy for managing the complexity of large API projects. By combining $ref external references with a well-organized directory structure and a bundling step in the build pipeline, teams gain the authoring benefits of modularity — reusability, parallel development, and focused code review — without sacrificing tooling compatibility. As APIs grow, a multi-file structure is not just a nice-to-have: it is an essential practice for sustainable API development.
Last updated on April 29, 2026.