Scalar vs Redoc vs Swagger UI: API Documentation UIs (2026)
TL;DR
Scalar is the modern API documentation UI — beautiful design, built-in API client for testing, dark mode, OpenAPI 3.1 support, customizable theming. Redoc is the three-panel API docs renderer — clean three-column layout, OpenAPI 3.x, search, code samples, used by major API providers. Swagger UI is the original OpenAPI renderer — interactive "Try it out" feature, the most widely used, powers SwaggerHub, official OpenAPI tooling. In 2026: Scalar for modern beautiful docs with API client, Redoc for clean reference documentation, Swagger UI for interactive API testing.
Key Takeaways
- Scalar: ~500K weekly downloads — modern UI, API client, dark mode, OpenAPI 3.1
- Redoc: ~1M weekly downloads — three-panel layout, search, code samples
- Swagger UI: ~3M weekly downloads — "Try it out", most widely used, official tooling
- All three render OpenAPI/Swagger specs into interactive documentation
- Scalar has the most modern design and built-in API testing
- Swagger UI's "Try it out" makes live API requests from the docs
Scalar
Scalar — modern API documentation:
Basic setup
<!-- CDN (quickest start): -->
<script
id="api-reference"
data-url="https://api.pkgpulse.com/openapi.json"
></script>
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
Express integration
import express from "express"
import { apiReference } from "@scalar/express-api-reference"
const app = express()
app.use(
"/docs",
apiReference({
spec: {
url: "/openapi.json",
},
theme: "purple",
})
)
app.get("/openapi.json", (req, res) => {
res.json(openapiSpec)
})
// → http://localhost:3000/docs
Hono integration
import { Hono } from "hono"
import { apiReference } from "@scalar/hono-api-reference"
const app = new Hono()
app.get(
"/docs",
apiReference({
spec: { url: "/openapi.json" },
pageTitle: "PkgPulse API",
theme: "kepler",
})
)
Configuration
import { apiReference } from "@scalar/express-api-reference"
app.use("/docs", apiReference({
spec: { url: "/openapi.json" },
// Theme:
theme: "purple", // purple, saturn, kepler, mars, moon, default
darkMode: true,
// Customization:
layout: "modern", // modern, classic
showSidebar: true,
// Authentication:
authentication: {
preferredSecurityScheme: "bearerAuth",
apiKey: {
token: "default-api-key",
},
},
// Custom CSS:
customCss: `
.scalar-app { --scalar-color-1: #3b82f6; }
`,
// Metadata:
metaData: {
title: "PkgPulse API Reference",
description: "Compare npm packages",
},
}))
Features
Scalar highlights:
✅ Built-in API client (test endpoints without leaving docs)
✅ Dark mode (toggleable)
✅ Modern, clean design
✅ OpenAPI 3.0 and 3.1 support
✅ Search across endpoints
✅ Request/response examples
✅ Multiple language code samples
✅ Authentication support
✅ Customizable themes
✅ Framework integrations (Express, Hono, Fastify, Next.js)
Redoc
Redoc — three-panel docs:
Basic setup
<!-- CDN: -->
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
<div id="redoc-container"></div>
<script>
Redoc.init("https://api.pkgpulse.com/openapi.json", {
theme: {
colors: { primary: { main: "#3b82f6" } },
},
}, document.getElementById("redoc-container"))
</script>
React component
import { RedocStandalone } from "redoc"
function APIReference() {
return (
<RedocStandalone
specUrl="https://api.pkgpulse.com/openapi.json"
options={{
theme: {
colors: {
primary: { main: "#3b82f6" },
},
typography: {
fontFamily: "Inter, sans-serif",
},
sidebar: {
backgroundColor: "#1a1a1a",
textColor: "#ffffff",
},
},
hideDownloadButton: false,
expandResponses: "200,201",
requiredPropsFirst: true,
sortPropsAlphabetically: true,
pathInMiddlePanel: true,
}}
/>
)
}
Express middleware
import express from "express"
import redoc from "redoc-express"
const app = express()
app.get("/docs", redoc({
title: "PkgPulse API",
specUrl: "/openapi.json",
redocOptions: {
theme: {
colors: { primary: { main: "#3b82f6" } },
},
},
}))
Configuration
const redocOptions = {
// Layout:
hideDownloadButton: false,
hideHostname: false,
hideLoading: false,
hideSchemaPattern: false,
hideSingleRequestSampleTab: false,
// Content:
expandResponses: "200,201", // Auto-expand these status codes
requiredPropsFirst: true,
sortPropsAlphabetically: true,
pathInMiddlePanel: true,
jsonSampleExpandLevel: 2,
// Sidebar:
menuToggle: true,
nativeScrollbars: false,
// Code samples:
generateCodeSamples: {
languages: [
{ lang: "curl" },
{ lang: "Node.js" },
{ lang: "Python" },
],
},
// Theme:
theme: {
colors: {
primary: { main: "#3b82f6" },
success: { main: "#10b981" },
error: { main: "#ef4444" },
},
typography: {
fontFamily: "Inter, sans-serif",
fontSize: "15px",
headings: { fontFamily: "Inter, sans-serif" },
},
sidebar: {
width: "260px",
backgroundColor: "#1a1a1a",
},
rightPanel: {
backgroundColor: "#0f172a",
},
},
}
Swagger UI
Swagger UI — interactive API docs:
Basic setup
<!-- CDN: -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist/swagger-ui.css" />
<div id="swagger-ui"></div>
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
url: "https://api.pkgpulse.com/openapi.json",
dom_id: "#swagger-ui",
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset,
],
})
</script>
Express integration
import express from "express"
import swaggerUi from "swagger-ui-express"
import openapiSpec from "./openapi.json"
const app = express()
app.use("/docs", swaggerUi.serve, swaggerUi.setup(openapiSpec, {
customSiteTitle: "PkgPulse API",
customCss: ".swagger-ui .topbar { display: none }",
swaggerOptions: {
persistAuthorization: true,
displayRequestDuration: true,
filter: true,
tryItOutEnabled: true,
},
}))
// → http://localhost:3000/docs
"Try it out" feature
Swagger UI's killer feature — execute API requests from the docs:
1. Open endpoint: GET /api/packages
2. Click "Try it out"
3. Fill in parameters: name = "react"
4. Click "Execute"
5. See real response:
curl -X GET "https://api.pkgpulse.com/api/packages?name=react"
Response:
200 OK
{
"name": "react",
"downloads": 25000000,
"version": "19.0.0"
}
This makes API testing and exploration interactive.
Configuration
import swaggerUi from "swagger-ui-express"
const options = {
// UI options:
customSiteTitle: "PkgPulse API",
customfavIcon: "/favicon.ico",
customCss: `
.swagger-ui .topbar { display: none }
.swagger-ui .info .title { color: #3b82f6 }
`,
// Swagger options:
swaggerOptions: {
persistAuthorization: true,
displayRequestDuration: true,
docExpansion: "list", // "list", "full", "none"
filter: true, // Search filter
tryItOutEnabled: true, // Enable "Try it out" by default
defaultModelsExpandDepth: 2,
defaultModelExpandDepth: 2,
// OAuth2:
oauth2RedirectUrl: "https://api.pkgpulse.com/docs/oauth2-redirect",
initOAuth: {
clientId: "your-client-id",
scopes: ["read", "write"],
},
},
}
app.use("/docs", swaggerUi.serve, swaggerUi.setup(spec, options))
Feature Comparison
| Feature | Scalar | Redoc | Swagger UI |
|---|---|---|---|
| Design | Modern, beautiful | Three-panel | Classic |
| Dark mode | ✅ (built-in) | ✅ (theme) | ❌ (custom CSS) |
| "Try it out" | ✅ (API client) | ❌ (paid addon) | ✅ |
| Search | ✅ | ✅ | ✅ (filter) |
| Code samples | ✅ | ✅ | ❌ |
| OpenAPI 3.1 | ✅ | ✅ | ✅ |
| OpenAPI 3.0 | ✅ | ✅ | ✅ |
| Swagger 2.0 | ❌ | ✅ | ✅ |
| React component | ✅ | ✅ | ✅ |
| Express middleware | ✅ | ✅ | ✅ |
| Hono/Fastify | ✅ | ❌ | ✅ (Fastify) |
| Custom theming | ✅ | ✅ (deep) | ✅ (CSS) |
| Self-hosted | ✅ | ✅ | ✅ |
| Weekly downloads | ~500K | ~1M | ~3M |
When to Use Each
Use Scalar if:
- Want the most modern, beautiful API documentation
- Need a built-in API client for testing endpoints
- Building with Hono, Express, or Fastify
- Want dark mode and customizable themes out of the box
Use Redoc if:
- Need clean three-panel reference documentation
- Want auto-generated code samples in multiple languages
- Building public-facing API docs for developer portals
- Need deep theming and branding customization
Use Swagger UI if:
- Need interactive "Try it out" API testing
- Want the most widely recognized API docs format
- Need OAuth2 flow support in the docs
- Have Swagger 2.0 specs (legacy support)
Methodology
Download data from npm registry (weekly average, February 2026). Feature comparison based on @scalar/api-reference v1.x, redoc v2.x, and swagger-ui-express v5.x.
Compare API tooling and documentation libraries on PkgPulse →