How it compares
The Laravel ecosystem is full of code-first tools that generate an OpenAPI document from your controllers and annotations: l5-swagger, dedoc/scramble, and vyuldashev/laravel-openapi. Those are excellent if your code is the source of truth.
openapi-laravel is for the other direction: spec-first, where the OpenAPI document is the contract and your models derive from it.
At a glance
Section titled “At a glance”openapi-laravel | l5-swagger / scramble | ensi-platform/* | hand-writing | |
|---|---|---|---|---|
| Direction | Spec to code | Code to spec | Spec to code | n/a |
| Generates laravel-data DTOs | Yes | No | No (custom DTOs) | You do |
Spec-derived validation rules() | Yes, differentially tested against the real Laravel Validator (see below) | No | Partial | You do |
| Differential validation oracle | Yes: spec-valid payloads must pass and spec-invalid must fail through the real Validator; a known-gap ratchet prevents silent accumulation of new gaps | No | No | No |
| Native PHP enums | Yes | No | No | You do |
| Server scaffold (abstract controllers + routes) | Yes (default) | No | Yes | You do |
allOf / additionalProperties | Yes | n/a | Partial | You do |
oneOf / anyOf | Yes: scalar union type hints; discriminated object unions validated and hydrated; undiscriminated ones presence-only | n/a | Partial | You do |
| Minimum Laravel version | 11 | 9+ | 10+ | n/a |
| Runtime peer dependency | spatie/laravel-data v4 (the generator itself is dev-only: no runtime dep on the generator, support classes inlined into your own namespace) | none | own DTO layer | none |
| Standard OpenAPI (no custom extensions) | Yes | Yes | No (custom OAS) | n/a |
| Owned, readable, committed output | Yes | n/a | Generated | Yes |
| Runs without Laravel (CI) | Yes (bin) | No | No | n/a |
| Byte-level drift gate in CI | Yes (openapi:check, byte-for-byte comparison, exit 1 on divergence between spec and committed code) | Structurally impossible: code-first tools generate the spec FROM your code, so there is nothing to check against | No | Manual review |
The oneOf / anyOf cell is honest: scalar unions get native PHP union type hints, and an object union with a discriminator is validated against the selected variant and hydrated polymorphically at runtime. An undiscriminated object union (CatData|DogData with no discriminator) stays presence-only and does not auto-hydrate. See the Unions & polymorphism page.
The spatie/laravel-data v4 runtime peer is a real adoption cost: the generated DTOs are laravel-data classes, so your app takes on that dependency and its conventions, and you need Laravel 11 or newer. The generator itself (codewithagents/openapi-laravel) is a dev-time tool only: it goes in require-dev, not require, and has no runtime presence in consuming applications. The support classes the generated code uses (custom validation rules, the map transformer, the status-enforcement middleware) are inlined into your own \Support namespace alongside the generated Data classes, so nothing from vendor is loaded at runtime beyond spatie/laravel-data itself. See runtime coupling for the full story.
Code-first: l5-swagger and scramble
Section titled “Code-first: l5-swagger and scramble”These tools read your controllers, annotations, or type hints and produce an OpenAPI document from them. Your PHP is the source of truth, and the spec is the artifact.
Pick them when your code is authoritative and you want documentation generated from it. They do not produce DTOs, validation rules, or enums for you to consume, because in their model your code already exists. That is the opposite problem from the one this tool solves.
Spec-first: ensi-platform
Section titled “Spec-first: ensi-platform”ensi-platform/laravel-openapi-server-generator is one of the few spec-first generators in the ecosystem. It generates server scaffolding, but it relies on custom OpenAPI extensions, so the input is not a plain standard spec, and it produces its own DTO shape rather than laravel-data classes with derived validation.
openapi-laravel reads standard OpenAPI with no custom extensions, emits laravel-data classes with explicit rules() and native enums, and a server scaffold (abstract controllers per tag plus a routes file) typed by those same classes, all in one default run. See the server scaffold guide.
Hand-writing
Section titled “Hand-writing”You can always write the DTOs, validation, and enums by hand. The cost is keeping every one of them aligned with the spec as it changes, by hand, forever. A generator turns that recurring manual reconciliation into a diff you review.
Why not just ask an AI agent?
Section titled “Why not just ask an AI agent?”An agent can write a Data class from your spec, and the first one will probably be fine. But the output is non-deterministic (the same prompt produces a different class tomorrow), nobody reviews the hundredth one, and the moment the spec changes you are back to hand-maintained code that drifts. This generator is deterministic: same spec in, byte-identical files out. That makes the output diffable, reviewable once instead of every time, and re-runnable in CI on every spec change.
The honest kicker: agents built this generator. The generator is what makes their output trustworthy on the hundredth run, not just the first.