
Swagger sounds flashy, but it’s really a practical set of tools built around the OpenAPI Specification (OAS). Define your HTTP API once (in YAML or JSON), and suddenly you can generate interactive docs, mock servers, client SDKs, testing hooks — the works. Below is a quick primer, a real working Express API you can run today, and a step-by-step action plan so you can ship something tangible before your coffee gets cold.
What “Swagger” Actually Is (and Why You Should Care)
- OpenAPI Specification (OAS). The language-agnostic contract for your HTTP API: endpoints, parameters, schemas, responses, auth, and examples. Latest spec info lives here: https://swagger.io/specification/
- Swagger UI. A web app that turns your OpenAPI file into interactive, try-it-out docs: https://swagger.io/tools/swagger-ui/
- Swagger Editor. A browser editor to design and lint your spec: https://editor.swagger.io/
- Swagger UI (npm flavors). If you’re bundling/serving from Node, check
swagger-ui,swagger-ui-dist, orswagger-ui-react: https://www.npmjs.com/package/swagger-ui - Express integration.
swagger-ui-express+swagger-jsdoclet you serve docs from your running app: - https://www.npmjs.com/package/swagger-ui-express
- https://www.npmjs.com/package/swagger-jsdoc
- Alternative/adjacent tools. Want more than UI? Client/server codegen via the community project: https://openapi-generator.tech/
Real, Working Example: A Tiny Express “Todos” API With Swagger
You’ll create a simple CRUD API, annotate it with JSDoc comments, and serve interactive docs at
/docs.
1) Initialize a project
mkdir swagger-todos && cd swagger-todos
npm init -y
npm i express swagger-ui-express swagger-jsdoc
2) Create index.js with routes + Swagger setup
// index.js
const express = require('express');
const swaggerUi = require('swagger-ui-express');
const swaggerJSDoc = require('swagger-jsdoc');
const app = express();
app.use(express.json());
// ---- In-memory data store (for demo only) ----
let todos = [
{ id: 1, title: 'Buy coffee', done: false },
{ id: 2, title: 'Write blog', done: true }
];
// ---- Swagger/OpenAPI configuration ----
const swaggerDefinition = {
openapi: '3.0.3',
info: {
title: 'Todos API (Demo)',
version: '1.0.0',
description: 'A minimal Express API documented with OpenAPI via swagger-jsdoc.'
},
servers: [{ url: 'http://localhost:3000', description: 'Local dev' }],
components: {
schemas: {
Todo: {
type: 'object',
required: ['id', 'title', 'done'],
properties: {
id: { type: 'integer', example: 3 },
title: { type: 'string', example: 'Refill coffee beans' },
done: { type: 'boolean', example: false }
}
},
NewTodo: {
type: 'object',
required: ['title'],
properties: {
title: { type: 'string', example: 'Stretch break' }
}
}
}
}
};
const options = {
definition: swaggerDefinition,
apis: ['./index.js'] // <-- this file contains our JSDoc annotations
};
const swaggerSpec = swaggerJSDoc(options);
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
/**
* @openapi
* /api/todos:
* get:
* summary: List all todos
* tags: [Todos]
* responses:
* 200:
* description: Array of todos
* content:
* application/json:
* schema:
* type: array
* items:
* $ref: '#/components/schemas/Todo'
*/
app.get('/api/todos', (req, res) => res.json(todos));
/**
* @openapi
* /api/todos/{id}:
* get:
* summary: Get a single todo
* tags: [Todos]
* parameters:
* - in: path
* name: id
* required: true
* schema: { type: integer }
* description: Numeric ID of the todo
* responses:
* 200:
* description: A todo
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Todo'
* 404:
* description: Not found
*/
app.get('/api/todos/:id', (req, res) => {
const todo = todos.find(t => t.id === Number(req.params.id));
if (!todo) return res.status(404).json({ message: 'Not found' });
res.json(todo);
});
/**
* @openapi
* /api/todos:
* post:
* summary: Create a new todo
* tags: [Todos]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/NewTodo'
* responses:
* 201:
* description: Created
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Todo'
*/
app.post('/api/todos', (req, res) => {
const nextId = Math.max(0, ...todos.map(t => t.id)) + 1;
const newTodo = { id: nextId, title: req.body.title || 'Untitled', done: false };
todos.push(newTodo);
res.status(201).json(newTodo);
});
/**
* @openapi
* /api/todos/{id}:
* patch:
* summary: Update fields on a todo
* tags: [Todos]
* parameters:
* - in: path
* name: id
* required: true
* schema: { type: integer }
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* title: { type: 'string' }
* done: { type: 'boolean' }
* responses:
* 200:
* description: Updated
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Todo'
* 404:
* description: Not found
*/
app.patch('/api/todos/:id', (req, res) => {
const i = todos.findIndex(t => t.id === Number(req.params.id));
if (i === -1) return res.status(404).json({ message: 'Not found' });
todos[i] = { ...todos[i], ...req.body };
res.json(todos[i]);
});
/**
* @openapi
* /api/todos/{id}:
* delete:
* summary: Remove a todo
* tags: [Todos]
* parameters:
* - in: path
* name: id
* required: true
* schema: { type: integer }
* responses:
* 204:
* description: Deleted
* 404:
* description: Not found
*/
app.delete('/api/todos/:id', (req, res) => {
const before = todos.length;
todos = todos.filter(t => t.id !== Number(req.params.id));
if (todos.length === before) return res.status(404).json({ message: 'Not found' });
res.status(204).end();
});
app.listen(3000, () => {
console.log('API running on http://localhost:3000');
console.log('Docs at http://localhost:3000/docs');
});
3) Run it
node index.js
# open http://localhost:3000/docs and click "Try it out"

15 Concrete, Do-This-Now Steps With Swagger
- Install prerequisites: Node 18+ (
node -v) and npm. - Bootstrap a folder:
mkdir swagger-todos && cd swagger-todos && npm init -y. - Add dependencies:
npm i express swagger-ui-express swagger-jsdoc. - Create
index.js: Paste the code above (routes + OpenAPI config + annotations). - Start the server:
node index.js. - Open your docs: Visit
http://localhost:3000/docs. You should see Swagger UI. (Behind the scenes:[swagger-ui-express](https://www.npmjs.com/package/swagger-ui-express)renders your generated spec.)
7. List todos: In Swagger UI, expand GET /api/todos → Try it out → Execute.

8. Create a todo: Use POST /api/todos with { "title": "Stretch break" }.

9. Fetch one: GET /api/todos/{id} with id: 1 (or whatever you created).

10. Update it: PATCH /api/todos/{id} with { "done": true }.

11. Delete it: DELETE /api/todos/{id} → Execute → check GET /api/todos again.

12. Add examples: In swaggerDefinition.components.schemas.Todo, add examples to show realistic payloads in UI. Docs: https://swagger.io/docs/specification/adding-examples/
13. Tighten contracts: Mark required fields, add enum constraints, and HTTP error responses (400/404). Reference syntax: https://swagger.io/specification/
14. Publish docs: Host your app and expose /docs, or serve a static UI using swagger-ui-dist. Install notes: https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/
15. Generate clients/servers: Export your spec (Swagger UI → View JSON), then run it through https://openapi-generator.tech/ to create SDKs or server stubs.
What to Learn Next (and How)
- OpenAPI 3.1 features. Learn discriminators, oneOf/anyOf/allOf, links, callbacks. Start here: https://swagger.io/specification/
- Design-first vs. code-first. Try Swagger Editor for design-first (https://editor.swagger.io/), then wire to your code.
- Linting & governance. As teams scale, enforce style with rules; validate specs in CI. (Search your stack for OpenAPI linters.)
- Auth flows. Add
securitySchemes(Bearer, OAuth2) and per-routesecurityarrays in your spec. - Beyond docs. Explore mocks, contract tests, and changelogs powered by OpenAPI diffs.
- Front-end happiness. Generate typed clients so UIs get autocomplete and compile-time safety.
Fun Tidbits You Can Drop in Stand-Ups
- The spec started life as “Swagger,” then moved under the OpenAPI Initiative (Linux Foundation). https://www.openapis.org/
- Swagger UI isn’t just pretty; it’s interactive, so non-backend folks can explore APIs without cURL. https://swagger.io/tools/swagger-ui/
- You can bundle Swagger UI straight into your app or host it as static assets. https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/
Art Prompt:
A crystalline city of angular facets and interlocking planes, figures reduced to geometric shards that tilt and overlap in a compressed, shallow space. Muted rose, ochre, and slate tones dominate, with accents of dusty blue; edges slice across the canvas like fractured glass. Multiple viewpoints collide at once, collapsing depth into a rhythmic mosaic. The mood is analytical yet electric, as if reality were rearranged into a chorus of shapes breathing in sync.

Video Prompt:
Cut straight into a kinetic collage of geometric fragments snapping into place like shuffled cards. Jump-cuts rotate through multiple viewpoints: a face becomes facets, a street becomes slanted planes, colors pulse from muted rose to ochre to slate. Quick push-ins reveal angular edges; a whip-tilt flips the scene into a fresh perspective; a staccato zoom synchronizes with percussion as forms assemble, dissolve, and reassemble — reality recomposed into a living mosaic that never sits still.
Songs to pair with the video:
- Midnight City — The XX
- All We Ever Knew — The Head and the Heart
If this helped, follow for more hands-on deep dives. Got your own Swagger tricks? Drop a comment — I read them all.