Skip to content

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.

openapi-laravell5-swagger / scrambleensi-platform/*hand-writing
DirectionSpec to codeCode to specSpec to coden/a
Generates laravel-data DTOsYesNoNo (custom DTOs)You do
Spec-derived validation rules()Yes, differentially tested against the real Laravel Validator (see below)NoPartialYou do
Differential validation oracleYes: spec-valid payloads must pass and spec-invalid must fail through the real Validator; a known-gap ratchet prevents silent accumulation of new gapsNoNoNo
Native PHP enumsYesNoNoYou do
Server scaffold (abstract controllers + routes)Yes (default)NoYesYou do
allOf / additionalPropertiesYesn/aPartialYou do
oneOf / anyOfYes: scalar union type hints; discriminated object unions validated and hydrated; undiscriminated ones presence-onlyn/aPartialYou do
Minimum Laravel version119+10+n/a
Runtime peer dependencyspatie/laravel-data v4 (the generator itself is dev-only: no runtime dep on the generator, support classes inlined into your own namespace)noneown DTO layernone
Standard OpenAPI (no custom extensions)YesYesNo (custom OAS)n/a
Owned, readable, committed outputYesn/aGeneratedYes
Runs without Laravel (CI)Yes (bin)NoNon/a
Byte-level drift gate in CIYes (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 againstNoManual 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.

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.

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.

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.

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.