# NelmioApiDocBundle: Generating OpenAPI Docs from PHP 8 Attributes in Symfony

> NelmioApiDocBundle reads PHP 8 attributes on Symfony controllers and turns them into OpenAPI documentation. It is a good fit for Symfony 6.4+ projects on PHP 8.1 or newer, and a poor fit for anyone who still relies on annotations or Swagger 2.0.

**nelmio/NelmioApiDocBundle** — Generates documentation for your REST API from attributes

- Repository: https://github.com/nelmio/NelmioApiDocBundle
- Stars: 2,370 · Forks: 911
- Language: PHP
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/nelmio-nelmioapidocbundle

## What NelmioApiDocBundle solves, and for whom

REST APIs drift away from their documentation. A controller gains a parameter, a response shape changes, and the spec file sitting in the repository keeps describing the old contract. NelmioApiDocBundle takes the opposite approach: the documentation is derived from the code, so the description lives next to the endpoint it describes.

The intended audience is a Symfony application. The README describes the package plainly as a bundle that "allows you to generate a decent documentation for your APIs", and the repository is laid out as a Symfony bundle, with config/, src/, templates/ and a .symfony.bundle.yaml file at the top level. If your API is not built on Symfony, the bundle has nothing to hook into. If it is, the bundle fits the framework's normal registration and configuration flow.

The output is an OpenAPI document. Version 4.0 of the bundle brought OpenAPI 3.0 support, and the README states that anyone who wants to stay on Swagger 2.0 should use version 3 instead. That is the first decision a new user has to make, and it is a version decision rather than a configuration flag.

## How attributes become an OpenAPI document

The mechanism is attribute-driven. The 5.x line removed support for annotations in favour of PHP 8 attributes, and the README lists that as one of the major changes in the release. So the source of truth is the attribute metadata attached to controllers and models, not a separate YAML or JSON file that someone has to remember to update.

That choice has consequences worth stating. Because the document is generated, there is no hand-written spec to review in a pull request: the diff you review is the attribute diff on the controller. It also means the quality of the generated document is bounded by how thoroughly the attributes are written. An endpoint with thin attributes produces a thin entry, and the bundle cannot infer intent it was never told about.

The bundle is also built to run under FrankenPHP worker mode and other long-running workers. The README points to a dedicated page on symfony.com for that setup, which is a signal that the maintainers treat long-running processes as a supported deployment target rather than an afterthought. If you deploy with a traditional per-request PHP process, that page is irrelevant to you.

The documentation itself lives on symfony.com rather than in the repository README. The README links there directly. That is where configuration options and the full attribute reference are described, and it is the first place to look when the README runs out of detail.

## Installing NelmioApiDocBundle and getting a first document

Installation is a single Composer command. Run it from your project directory, which the README describes as entering your project directory and executing the command to download the latest version of the bundle:

```bash
composer require nelmio/api-doc-bundle
```

Composer resolves the package and its constraints. Because 5.x requires PHP 8.1 or higher and Symfony 6.4 or higher, a project below either floor will fail resolution here rather than at runtime, which is the useful place for that failure to happen.

Once the package is installed, the bundle registers itself the way Symfony bundles do, and the routes it exposes serve the documentation UI. The related searches around this project show people looking for the Swagger UI controller and asking about the JSON output, which matches the shape of the bundle: there is a UI route and there is a generated document behind it.

To run the project's own test suite from a clone, the README gives these steps:

```bash
composer update
composer phpunit
```

The first command installs the Composer dependencies for the bundle itself, and the second runs the test suite. That is the contributor path, not the consumer path, and it is worth keeping the two separate when you are deciding whether to adopt the package.

If you are coming from an earlier major version, the README does not describe an in-place upgrade as a single command. It points to separate migration guides for 2.x to 3.0, 3.x to 4.0, and 4.x to 5.0, each stored as a UPGRADE file in the repository root. Read the guide for your current version before changing the constraint.

## Where the bundle is the wrong tool

The clearest limitation is the version floor. The 5.x line requires PHP 8.1 or higher and Symfony 6.4 or higher, and it removed annotation support entirely. A codebase that still documents endpoints with annotations cannot adopt 5.x without converting those annotations to attributes first. The README frames this as a major change and links to UPGRADE-5.0.md, which is the document that tells you how much work that conversion is for your code.

Swagger 2.0 is the second boundary. The README is explicit that if you want to stick to Swagger 2.0, you should use version 3 of the bundle. Staying on a version that is several majors behind to keep an older spec format is a real position to take, but it is a position with a maintenance cost, and the README does not describe a path that gives you both Swagger 2.0 and the current release.

There is also a framework boundary that no configuration removes. This is a Symfony bundle. It hooks into Symfony's bundle system, its configuration, and its routing. If your API is written in another PHP framework, or in another language, none of that applies, and a standalone OpenAPI generator is the more sensible starting point.

Finally, generated documentation is only as complete as the attributes behind it. If your team will not write attributes on controllers, the bundle will produce a document that is technically valid and practically thin. That is not a bug in the tool, but it is the failure mode that makes people conclude the tool does not work.

## The alternative: swagger-php without the Symfony bundle

The related searches for this project repeatedly surface zircote/swagger-php, and that is the right comparison to make. swagger-php is the underlying generator for OpenAPI documents in PHP, and it is not tied to Symfony. NelmioApiDocBundle sits in front of that world and adds the Symfony integration: bundle registration, framework configuration, routing, and a UI.

The difference in approach is where the work happens. With swagger-php on its own, you drive generation yourself and decide how the resulting document is served and where the UI comes from. With the bundle, that plumbing is part of the package and follows Symfony conventions, at the cost of the version floors described above. If you are on Symfony and want the integration, the bundle saves you writing it. If you are not on Symfony, or you want to control the generation step yourself, swagger-php is the layer to use directly.

The same search list mentions FOSRestBundle and Symfony/type-info. Those are adjacent rather than equivalent: FOSRestBundle is a REST layer for Symfony applications, and Symfony/type-info is a component in the Symfony ecosystem. Neither replaces the bundle's job of producing an OpenAPI document from attribute metadata.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-09-28. Releases are frequent and recent: v5.12.2 on 2026-09-14, v5.12.1 on 2026-09-07, and v5.12.0 on 2026-09-03. The patch cadence suggests a project that fixes things between feature releases rather than batching everything into major versions.

The upgrade cost is concentrated in major versions, and the README treats it that way. Each of the 3.0, 4.0 and 5.0 transitions has its own UPGRADE file, and the 5.0 guide is the one that matters for anyone moving from 4.x, since it covers the removal of annotations, the PHP 8.1 floor, and the Symfony 6.4 floor. Minor and patch upgrades within 5.x are not described as requiring migration steps.

On licensing, the README states that the bundle is released under the MIT license, and the repository carries a LICENSE file. MIT is permissive, which matters if you are embedding the bundle in a commercial Symfony application. This is a description of what the repository says, not legal advice; if your organisation has rules about third-party licence obligations, run the LICENSE file past whoever handles that.

## Conclusion

Adopt NelmioApiDocBundle if you run Symfony 6.4 or newer on PHP 8.1 or higher, already describe endpoints with attributes, and want the OpenAPI document generated from the code you ship rather than maintained beside it. Do not adopt it if you are still on annotations, pinned to Swagger 2.0, or below the minimum Symfony version, because the 5.x line removed annotation support and requires PHP 8.1. Before you commit, read UPGRADE-5.0.md against your own controllers and check the frankenphp page if you deploy under a long-running worker.

## FAQ

### What PHP and Symfony versions does NelmioApiDocBundle 5.x require?

The 5.x line requires PHP 8.1 or higher, and the minimum Symfony version is 6.4. Both are listed in the README as major changes introduced by the 5.0 release.

### Does NelmioApiDocBundle still support annotations?

No. Support for annotations was removed in favour of PHP 8 attributes, and the README lists that removal among the major changes in 5.0. Projects still using annotations need to convert them before moving to 5.x.

### How do I install NelmioApiDocBundle?

Run composer require nelmio/api-doc-bundle from your project directory, which is the command the README gives for downloading the latest version of the bundle.

### Can I keep using Swagger 2.0 with NelmioApiDocBundle?

The README states that version 4.0 brought OpenAPI 3.0 support and that anyone who wants to stick to Swagger 2.0 should use version 3 of the bundle.

## Sources

- [Issues](https://github.com/nelmio/NelmioApiDocBundle/issues)
- [License: MIT](https://github.com/nelmio/NelmioApiDocBundle/blob/5.x/LICENSE)
- [nelmio/NelmioApiDocBundle on GitHub](https://github.com/nelmio/NelmioApiDocBundle)
- [README](https://github.com/nelmio/NelmioApiDocBundle/blob/5.x/README.md)
- [Releases](https://github.com/nelmio/NelmioApiDocBundle/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nelmio-nelmioapidocbundle
