hypecodeteam/swagger-ui-bundle
Swagger UI Bundle integrates Swagger UI into Laravel, making it easy to publish and browse interactive OpenAPI/Swagger documentation. It bundles the needed assets and routes so you can expose API docs with minimal setup and configuration.
The first thing to internalize: this is a Symfony bundle, not a Laravel package. Its composer.json declares symfony-bundle type, it ships a SwaggerUiBundle class meant for config/bundles.php, and it uses the Symfony DI extension pipeline. Laravel does not run Symfony bundles. If you composer require this into a Laravel app, package discovery will ignore it, and manually wiring a bundle into Laravel's container is brittle adapter work you'll own forever. Treat this as a reference implementation, not a dependency unless you're genuinely in a Symfony codebase.
Where to look first (in the repo, before reading the README, which is likely sparse for a 0-star package):
DependencyInjection/Configuration.php — the actual config keys (READMEs drift; this file is truth).Resources/config/routes.yaml — route name, path default, controller reference.Resources/public/ (or similar) — the bundled Swagger UI assets and how they're published/served.composer.json — Symfony/PHP version constraints; verify they resolve against your target runtime.If you're on Symfony:
composer require hypecodeteam/swagger-ui-bundle
Register HypeCodeTeam\SwaggerUiBundle\SwaggerUiBundle in config/bundles.php if Flex doesn't auto-register, point the bundle at your openapi.yaml/openapi.json, set the docs route (typically /docs), then visit it. That's the whole flow.
If you're on Laravel (the likely case if you're reading this):
composer require darkaonline/l5-swagger # generation + UI
# or
composer require knuckleswtf/scribe # annotated doc generation
For a pure viewer over an existing spec, the fastest Laravel-native path is a single route + a Blade view + Swagger UI assets published to public/vendor/swagger-ui. Roughly one controller, one view, one config entry.
First use case: expose read-only Swagger UI over a pre-existing spec in dev/staging, confirm the spec loads, then gate or disable it before production. Do not make this your production docs surface on day one.
Spec-first workflow (the one that actually scales). Keep openapi.yaml in the repo as the source of truth. Validate in CI (swagger-cli validate, spectral lint). Configure the viewer to point at the committed file. The bundle (or your vendored view) is only the UI layer — generation is upstream of it. This decouples "what the API is" from "how we render it."
Generated-spec workflow. If you want annotations-driven specs, pair this viewer with nelmio/api-doc-bundle (Symfony) or l5-swagger (Laravel) for generation, and use the viewer purely to render the generated JSON/YAML. Don't conflate the two — mixing generation and rendering into one dependency means the viewer's abandonment becomes your generation outage too.
Environment gating. In Symfony, define the docs route only in config/routes/dev/ or wrap the config in when@dev / when@staging. In Laravel, register the route only when app()->environment('local', 'staging') or gate it behind Route::middleware(['auth', ...]). Never let /docs go public unconditionally — your OpenAPI file describes every endpoint, including internal/admin ones.
Access control. Put /docs behind Symfony Security access_control, basic auth, SSO, or an IP allowlist. If it's a customer-facing API reference, this is a product decision, not a technical one — but the default should be locked down until someone deliberately opens it.
Multiple specs (public / admin / internal). Swagger UI supports a urls array with named entries. If the bundle exposes that config, wire one entry per spec. If it doesn't, create separate routes pointing to the same template with different spec URLs — or write a small custom controller. Expect to do the latter; a 0-star bundle rarely exposes every Swagger UI knob.
Asset serving — bundled vs. CDN. The genuine value proposition here is serving Swagger UI assets from your own host, not unpkg.com. If you're in an air-gapped or restricted-egress environment, this matters; if you're on the open internet, the CDN is fine and one fewer thing to patch. When vendoring for Laravel, publish assets to public/vendor/swagger-ui and set url/urls in your init script accordingly.
Customization. Publish the bundle's views/config (bin/console equivalent of vendor:publish) before editing — never patch inside vendor/. Customize the init script (url, urls, deepLinking, displayRequestDuration, persistAuthorization) rather than the Swagger UI source.
License is GPL-3.0 — copyleft. This is the sharpest edge on the package. For a distributed, on-prem, or commercially licensed product this can be a legal blocker. For a hosted SaaS where you never convey the code, it's usually manageable but still needs counsel sign-off. Get this cleared before the technical spike, not after the merge. The cheapest failure mode in software is discovering license contamination under a release deadline.
Zero signal on maintenance. Zero stars, zero dependents, single maintainer, no visible CI or changelog. Assume no upstream fixes and no security response. You are the maintainer from day one. Budget ongoing ownership, not a one-time install. This is the reason the honest recommendation is harvest the pattern, don't adopt the package.
Platform mismatch is disqualifying, not a hurdle. If your stack is Laravel-only, stop here and use l5-swagger, scribe, or a vendored route. Adapter code to make a Symfony bundle run in Laravel is unbounded work with no upstream benefit.
Asset 404s behind a reverse proxy / subpath. The classic breakage: deploying under /app/docs or /api/docs while Swagger UI's url config is hardcoded to /docs/openapi.json. Set an explicit base path and test under your real proxy prefix — this is the most common production failure of any Swagger UI deployment, bundled or not.
Route collisions and accidental exposure. Check /docs, /api/docs, /swagger, /swagger-ui against existing routes before adding. After adding, curl the route from outside your VPN as an unauthenticated user and confirm you get a 401/403 if it should be internal.
Stale specs. The viewer will happily serve last month's spec. Wire spec regeneration into CI; fail the build if openapi.yaml is out of sync with routes/annotations. A browsable-but-wrong reference is worse than none — consumers trust it and file tickets against the wrong contract.
Read Configuration.php, not the README. With a near-zero footprint, the README is aspirational. The real config keys, defaults, and required vs. optional values live in the Symfony Configuration tree (or the equivalent PHP array in a Laravel port). Budget 15 minutes there and you'll save an hour of guessing.
Swagger UI assets age. A pinned, unpatched UI has a history of XSS-class vulnerabilities in spec rendering. If /docs is externally reachable, you need a patching cadence for the assets — a concern that's independent of this bundle but amplified by taking on a dormant dependency.
Silent breakage on framework upgrade. When you eventually bump PHP or Symfony, a manually-registered bundle can stop resolving with no obvious error — usually a ServiceNotFoundException or a route that silently disappears. Isolate the docs feature behind a single configurable route and a swappable asset directory so the whole thing is reversible in minutes.
Extension point worth knowing: the urls array in Swagger UI's init script is where multi-spec support actually lives. If the bundle doesn't expose it in config, override the template's init block — that's a two-line change and far cheaper than forking the bundle.
Air-gapped deployments: if you're the reason the package exists for a team, verify the bundled assets include all of Swagger UI's runtime dependencies (fonts, icon sprite, favicon). Half-bundled assets that still reach out to a CDN for one thing are the worst of both worlds.
How can I help you explore Laravel packages today?