Getting Started (And What Will Break)
The CLI approach is genuinely simple:
npx @redocly/cli build-docs openapi.yaml
This spits out redoc-static.html
that you can host anywhere. Works every time, no surprises. I've used this for quick demos and it's never failed.
For existing sites, the HTML embed method works but has gotchas:
<redoc spec-url=\"https://api.example.com/openapi.json\"></redoc>
<script src=\"https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js\"></script>
CORS will fuck you sideways: Your spec lives at api.company.com
but docs at docs.company.com
? Congrats, you just got CORS'd. The browser throws Access to fetch at 'https://api.company.com/openapi.json' from origin 'https://docs.company.com' has been blocked by CORS policy
and your docs show a blank page. Took me 2 hours and 3 Stack Overflow tabs to figure out I needed Access-Control-Allow-Origin: *
on the spec endpoint.
Version-specific gotchas that'll ruin your day: Redoc 2.4.1 has a parser bug that crashes on schemas with deeply nested objects - anything over 5 levels deep and you get Maximum call stack size exceeded
. Version 2.3.0 is completely broken, crashes on any spec with $ref
loops. And 2.1.x randomly fails to render code examples on Safari mobile. Pin your version or suffer.
React integration is smooth: The React component actually works reliably with Create React App, Next.js, and Vite. Never had it break during framework updates, unlike some other tools that explode when you upgrade webpack.
Docker is overkill unless you're already containerized: The official image works but adds 500MB for what's essentially a static site generator. We used it initially because "everything needs Docker" until we realized we were deploying half a gigabyte to serve a 1MB HTML file.
Redoc works great until your OpenAPI spec hits ~1MB, then it becomes unusably slow. This isn't theoretical - our 200-endpoint API with complex nested objects made Redoc take 10+ seconds to render. Issue #1615 has the gory details.
Solutions that actually work:
Split your API specs by domain. Instead of one massive api.yaml
, create:
user-api.yaml
payment-api.yaml
admin-api.yaml
Deploy separate Redoc instances for each. Not ideal but it works. FastAPI makes this easy with multiple routers.
The x-internal
trick: Hide internal endpoints from public docs:
paths:
/internal/health:
x-internal: true
get: ...
This reduces spec size and keeps private stuff private. GitHub's API docs do this extensively.

CDN hosting matters: Static HTML files are fast, but 1MB+ bundles can be slow on mobile. Cloudflare or AWS CloudFront help a lot. Found this out when our mobile users complained docs took 30 seconds to load because we were serving a massive bundle from a slow server in the wrong region.
Windows is a nightmare: CLI fails with Error: ENOENT: no such file or directory
when your spec path has spaces. PowerShell wants \"./api docs/openapi.yaml\"
but cmd.exe chokes on that. WSL works fine but your CI runs native Windows and randomly explodes with path separator issues. I learned to put everything in folders with no spaces because debugging Windows path problems at 3am isn't my idea of fun.
Customization Without Going Insane
Unlike tools that require separate config files, Redoc customization lives in your OpenAPI spec. This is actually genius - your branding travels with your API definition.
Logo integration:
info:
x-logo:
url: 'https://example.com/logo.png'
altText: 'Company Logo'
Organized navigation when you have tons of endpoints:
x-tagGroups:
- name: Authentication
tags: [auth, users, sessions]
- name: Payments
tags: [billing, invoices, cards]
Multi-language code samples:
paths:
/users:
post:
x-codeSamples:
- lang: 'curl'
source: |
curl -X POST https://api.example.com/users \
-H \"Content-Type: application/json\" \
-d '{\"name\": \"John\"}'
- lang: 'javascript'
source: |
const response = await fetch('/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John' })
});
This beats maintaining code samples in separate files that get out of sync. Twilio's API docs show how good this can look.

Deploying This Thing in Production
CI/CD integration is straightforward. Add this to your GitHub Actions:
- name: Generate API docs
run: npx @redocly/cli build-docs api/openapi.yaml
- name: Deploy to S3
run: aws s3 cp redoc-static.html s3://docs-bucket/
Netlify and Vercel work great for this since it's just static files.
Auth is your problem, not Redoc's: Static HTML means no login forms, no user sessions, no "personalized" features. We tried building custom auth into the generated HTML before realizing that's a terrible idea. Now everything sits behind nginx with basic auth, or Cloudflare Access when the security team decides basic auth isn't "enterprise-grade" enough.
Environment config makes you want to scream: Production uses https://api.company.com/openapi.json
, staging uses https://staging-api.company.com/openapi.json
, but dev uses http://localhost:3000/openapi.json
and Chrome throws mixed content warnings because your docs are served over HTTPS. Then QA uses some random IP address that changes daily. By the time you're done, you have 47 different spec URLs and nobody remembers which one actually works.
Analytics: Unlike ReadMe or GitBook, you need to add tracking yourself. Google Analytics, Mixpanel, or PostHog work fine.
Migration Pain Points
From Swagger UI: Dead simple since both use OpenAPI specs. The hardest part is explaining to developers why they can't test APIs from the docs anymore. Some teams run both - Redoc for external-facing docs, Swagger UI for internal testing.
From manual docs: Pain in the ass. You have to restructure everything to fit OpenAPI's schema-driven approach. But once you do, updates are automatic instead of manual. Postman's API docs show how this transformation can work.
Documentation gets deprioritized when deadlines approach: Your PM will say "ship the feature, we'll update docs later" and then "later" becomes next quarter. This is why half the APIs in the world have outdated documentation.
From hosted solutions: Easy technically, but you lose features like user management, analytics, and support. The MIT license means no vendor lock-in risks, but you're on your own for maintenance.
When It Actually Makes Sense
Use Redoc when you want professional-looking docs without hiring designers or building custom solutions. Don't use it for large APIs (>1MB specs), APIs that need interactive testing, or multi-API sites.
The fact that Docker, Stripe, and Discord use it means it's solid enough for production. Just know the limitations before you commit.