The dark-themed OpenAPI workbench — editor, validator, mock server,
converters and exporters in a single static page.
Crafted and maintained by Kaan Dikeç · @dikeckaan
oasforge.dev · GitHub Pages mirror · Single-file offline app · License (ELv2)
Formerly Swagger Dark UI — the repository keeps its original name.
OASForge (formerly Swagger Dark UI) is a dark-themed OpenAPI workbench — editor, validator, mock server, converters and exporters in a single static site, deployed to both Cloudflare and GitHub Pages from one build.
- 🌗 Dark theme by default, with a light-mode toggle and four color palettes (Default, Nord, Dracula, Catppuccin) — all persisted in
localStorage - 🔀 Spec switcher — flip between the full-feature demo API and the live Swagger Petstore (shareable via
?spec=URL parameter) - ✏️ Bring your own APIs — a built-in split-pane YAML editor with live preview: multiple named specs, open local files, fetch from a URL (CORS required), download, JSON↔YAML conversion,
Cmd/Ctrl+Sto save andCmd/Ctrl+Enterto render - ➕ Insert menu — build a spec without memorizing OpenAPI structure (
js/snippets.js): one click inserts a full CRUD resource, a new endpoint (GET/POST/PUT/PATCH/DELETE), an operation on the path under the cursor, parameters, request bodies, responses, schemas, security schemes, servers or tags — indentation-aware, placed in the right section, with the placeholder name pre-selected for renaming - 🔍 Search everywhere —
Ctrl/Cmd+Fopens an in-editor find bar (js/findbar.js: live highlights, i/N counter, Enter/Shift+Enter cycling), and the preview's old tag-only filter is replaced by a full-text operation search (js/opsearch.js) that indexes the parsed spec — paths, methods, summaries, descriptions, parameter names, schema property names and enum values ($refs resolved), status codes, security scheme names — and filters the rendered operations live with AND terms - 🎛️ Inline rule menu — put the cursor on a schema property, component schema, or parameter and a "+ rule" pill appears (
js/constraints.js): it offers the validation keywords that fit the value's type (minLength,pattern,minimum,enum,required, …) and inserts them in the right place —requiredlands in the parent schema's list, parameter rules go into itsschema:(created on demand) - 🩺 OpenAPI validation with quick fixes — the editor lints your document like Swagger Editor does (
js/validate.js): misplaced/unknown properties, wrong value types (version: 1.0vs"1.0"), security requirements without a matching scheme, unresolved$refs, invalid status codes,example/examplesconflicts and more — each issue is clickable and jumps to the offending line, while the preview keeps rendering. Most issues carry a one-click Fix button (js/quickfix.js): quote the value, create the missing security scheme, remove the offending property, add the missingdescription/responses, … - ⌨️ Context-aware autocomplete (
js/autocomplete.js) — type (or pressCtrl+Space) and get the OpenAPI keys valid right there: operation keys insideget:, parameter keys inside a- name:item, schema keywords underschema:, media types undercontent:, quoted status codes underresponses:, plus value completions forin:/type:/format:/style:and live$ref:targets and security-scheme names read from your own document - 🧪 Example generator — one Insert-menu click derives an
example:block from the schema under the cursor ($refs resolved), reusing the mock server's schema→example engine - 🔁 Swagger 2.0 → OpenAPI 3 converter (
js/convert20.js) — paste a 2.0 document and a banner offers one-click conversion: servers fromhost/basePath/schemes,body/formDataparameters →requestBody,produces→ responsecontent,definitions/securityDefinitions→components, full$refrewrite - 🕒 Version history (
js/history.js) — automatic (rate-limited) and manual snapshots per spec, stored compressed inlocalStorage; restore any snapshot or view a color-coded line diff against the current text - 📤 Export (
js/export.js) — download the current spec as a Postman Collection v2.1 (folders per tag, path/query/header params, example request bodies, auth mapping) or as standalone HTML docs: a single self-contained file with Swagger UI inlined that opens offline from disk - 🔌 Fully offline — all third-party assets are vendored (
vendor/, hash-verified against the previously pinned SRI values), so the site, the Docker image and exported docs work with no internet at all - 📋 Edit a copy — one click turns the demo API or Petstore into an editable copy in the editor (converted to tidy YAML), so the ready-made specs double as starting templates
- 📮 Postman import — drop a Postman Collection (v2 / v2.1+) export into Open file or Load URL and it is converted to OpenAPI 3 automatically (
js/postman.js) - 🔗 Share specs by link — the Share button packs the current spec into a compressed URL hash (lz-string); no backend involved
- ⚡ "Try it out" really works — offline and stateful — the default server is an in-browser mock (
js/mock.js):POSTreally creates records (kept in memory),GETlists them,PUT/PATCH/DELETEupdate and remove; endpoints without stored data return schema-derived examples, the rest echo the request httpbin-style.X-Mock-Statusforces a documented status code,X-Mock-Delaysimulates latency. A live httpbin.org server stays selectable, and Petstore runs against the livepetstore3.swagger.ioserver - 🧾 Request snippets — every operation shows ready-to-copy cURL (bash/PowerShell/CMD), JavaScript
fetch, and Pythonrequestscode - 📲 Installable app (PWA) — a web app manifest plus a service worker make the site installable from the browser; the installed app runs in its own window and works fully offline (the whole app is precached on first visit and silently refreshed on later loads)
- 📦 Zero build step — plain HTML/CSS/JS; third-party libraries are pinned, hash-verified copies in
vendor/(seevendor/README.md)
The custom specs/demo-api.yaml (OpenAPI 3.1) exercises
everything Swagger UI knows how to render:
| Area | Features |
|---|---|
| Operations | GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS, deprecated operations, external docs |
| Parameters | path / query / header / cookie; form, pipeDelimited, deepObject styles |
| Request bodies | JSON with named examples, form-urlencoded, multipart file upload, XML, plain text |
| Schemas | oneOf / anyOf / allOf + discriminator, recursion, readOnly / writeOnly, 3.1 nullable types, const, additionalProperties |
| Responses | Multiple status codes, response headers, content negotiation, links, binary downloads |
| Async | Callbacks and OpenAPI 3.1 webhooks |
| Security | API key (header/query/cookie), HTTP Basic, Bearer JWT, OAuth 2.0 flows, OpenID Connect |
| Extras | Server variables, rich Markdown descriptions, tag external docs |
No dependencies — any static file server works:
python3 -m http.server 8000
# then open http://localhost:8000Download standalone.html
— the entire app in one file. Double-click it and it runs from file://:
no web server, no network, nothing else to install. Every script, style,
vendored library and the demo spec are inlined; the in-browser mock keeps
"Try it out" working. The file is rebuilt by the Pages workflow on every
push to main (build-standalone.js), so the download is always current
with the live site.
docker compose up # → http://localhost:8080
# or without compose:
docker build -t swagger-dark-ui .
docker run --rm -p 8080:80 swagger-dark-uiThe container serves the site with nginx and works fully offline — all
third-party assets (Swagger UI, CodeMirror, js-yaml, lz-string) are vendored
in vendor/, so no internet access is needed on either side. Only the
optional live Petstore spec view requires connectivity.
├─ index.html # Shell: header, spec selector, theme toggle
├─ css/theme.css # Token-based dark/light theme for Swagger UI 5.x
├─ js/app.js # Swagger UI init, spec switcher, theme persistence
├─ js/validate.js # OpenAPI linter for the YAML editor (issues panel)
├─ js/quickfix.js # One-click fixes for linter issues
├─ js/constraints.js # Inline "+ rule" menu for the field under the cursor
├─ js/snippets.js # "+ Insert" menu: OpenAPI building-block templates
├─ js/autocomplete.js # Context-aware OpenAPI autocomplete ($ref picker incl.)
├─ js/convert20.js # Swagger 2.0 → OpenAPI 3.0 converter
├─ js/history.js # Snapshot history with restore + line diff
├─ js/export.js # Postman collection & standalone-HTML exporters
├─ vendor/ # Vendored Swagger UI / CodeMirror / js-yaml / lz-string
├─ Dockerfile / docker-compose.yml # Optional: serve the site locally with nginx (offline)
├─ specs/demo-api.yaml # Comprehensive OpenAPI 3.1 demo spec
└─ .github/workflows/deploy.yml # GitHub Pages deployment
Both deployments publish the same build (build-cf.js: landing page at
the root, the app at /app/, static /guide/, /faq/ and landing pages,
sitemap.xml, robots.txt, cache headers and the single-file
standalone.html) on every push to main:
- Cloudflare (oasforge.dev) — the
Cloudflare workflow builds
dist-cf/and deploys it with Wrangler as an assets-only Worker (static asset requests are free and unmetered on every Workers plan). A no-op until theCLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_IDrepository secrets are set (or connect the repo to Cloudflare Workers Builds instead). - GitHub Pages mirror (
kaandikec.com/swagger-dark-ui) — the Pages workflow runs the same script with--base /swagger-dark-ui --out dist-pagesso internal links carry the sub-path prefix. Canonical URLs point at oasforge.dev, so search signals consolidate on the primary domain.
OASForge — formerly Swagger Dark UI — is designed, built and maintained by Kaan Dikeç (@dikeckaan) — from the dark theme and the demo spec to the in-browser validator, mock server and converters. Feedback, ideas and bug reports are always welcome via issues.
© 2026 Kaan Dikeç · kaandikec.com
Elastic License 2.0 (ELv2) — free to use, copy, modify, distribute and use commercially (internal tools, client projects, embedding in your own products), with three limitations:
- you may not offer the software itself to third parties as a hosted or managed service (e.g. selling access to this editor as a SaaS),
- you may not circumvent any license-key functionality,
- you may not remove or obscure the licensing/copyright notices.
Third-party assets in vendor/ keep their own upstream
licenses (Apache-2.0 / MIT) and are not covered by ELv2.