← Back to nodox

Generate Swagger Docs from
Joi Schemas: Zero Config

Already using Joi to validate your Express routes? nodox-cli reads those schemas automatically and generates a live Swagger UI, no JSDoc, no YAML files, no extra setup.

Get started: npx nodox-cli init

Before vs. after

Without nodox-cli

// You write your Joi schema...
const CreateUser = Joi.object({
  name: Joi.string().min(1).required(),
  email: Joi.string().email().required(),
  age: Joi.number().integer().min(0),
})

// ...then write it AGAIN in YAML
// or JSDoc comments for Swagger:
/**
 * @swagger
 * /users:
 *   post:
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 type: string
 * ...20 more lines
 */
app.post('/users', validate, handler)

With nodox-cli

import nodox, { validate } from 'nodox-cli'
import Joi from 'joi'

const app = express()
app.use(express.json())
app.use(nodox(app))   // ← one line

const CreateUser = Joi.object({
  name: Joi.string().min(1).required(),
  email: Joi.string().email().required(),
  age: Joi.number().integer().min(0),
})

// validate() reads the Joi schema AND
// validates incoming requests
app.post('/users',
  validate(CreateUser),
  handler
)

// Visit /__nodox — docs are live.

Joi features nodox-cli detects

  • Primitives: Joi.string(), Joi.number(), Joi.boolean(), Joi.date()
  • Constraints: .min(), .max(), .email(), .uri(), .uuid(), .pattern()
  • Optional / required: .optional(), .required()
  • Nested objects: Joi.object({ address: Joi.object({...}) })
  • Arrays: Joi.array().items(Joi.string())
  • Enums: Joi.string().valid('admin', 'user')
  • Alternatives: Joi.alternatives().try(...)
  • Response schemas: validate(Input, { response: Output })
  • Joi ≥ 17

Setup in 30 seconds

npm install nodox-cli npx nodox-cli init Full setup guide →

Also supports

nodox-cli reads Zod, express-validator, and yup with the same zero-config approach.