New — now for Python (Flask · FastAPI · Django) and PHP (Laravel)

One schema per route.
Docs, tests, and runtime validation.

DocTreen is a code-first API documentation library for Node.js, Python, and PHP. Define your route shape once and get an interactive docs UI, OpenAPI 3.1 export, runnable integration flows, and 422-on-invalid-request validation — for Express, Fastify, Hono, Koa, NestJS, Flask, FastAPI, Django, and Laravel.

npm install doctreenpip install doctreencomposer require doctreen/doctreen
import express from 'express';
import { z } from 'zod';
import { expressAdapter, defineRoute } from 'doctreen/express';

const app = express();
app.use(express.json());

app.post('/users', defineRoute(
  (req, res) => res.status(201).json({ id: 1, ...req.body }),
  {
    description: 'Create a user',
    request:  { body: z.object({ name: z.string(), email: z.string().email() }) },
    response: z.object({ id: z.number(), name: z.string(), email: z.string() }),
    errors:   { 409: 'Email already in use' },
  }
));

// Mount docs UI + OpenAPI 3.1 + runtime validation in one place.
app.use(expressAdapter(app, {
  meta:     { title: 'My API', version: '1.0.0' },
  validate: true,
}));
from flask import Flask
from pydantic import BaseModel

from doctreen.adapters.flask import define_route, flask_adapter

app = Flask(__name__)


class User(BaseModel):
    id: int
    name: str


@app.get("/users/<int:user_id>")
@define_route(description="Get a user", response=User, errors={404: "Not found"})
def get_user(user_id: int):
    return {"id": user_id, "name": "Ada"}


# Mount docs UI + OpenAPI 3.1 + runtime validation in one place.
app.register_blueprint(flask_adapter(app, {
    "meta": {"title": "My API", "version": "1.0.0"},
    "validate": True,
}))
use Doctreen\Schema\S;

// Docs UI, OpenAPI 3.1, and validation mount from config/doctreen.php —
// the service provider is auto-discovered. One declaration per route:

Route::post('/users', [UserController::class, 'store'])->doc([
    'description' => 'Create a user',
    'request'  => ['body' => S::object([
        'name'  => S::string(),
        'email' => S::string(),
    ])],
    'response' => S::object([
        'id'    => S::number(),
        'name'  => S::string(),
        'email' => S::string(),
    ]),
    'errors'   => [409 => 'Email already in use'],
]);
  • Interactive docs UI at /docs — zero-dependency HTML, one visual surface shared by all three languages
  • OpenAPI 3.1 export with $ref dedup, tags, callbacks, webhooks — conformance-tested across implementations
  • Runtime validation: the same schema returns a structured 422 (Zod, Pydantic, or the s builder)
  • Schema drift detection against live traffic, CI-ready
  • Spec-driven mock server: npx doctreen mock --from <url|file>
  • Postman export, runnable integration flows, and typed codegen

Works with your stack

Node.js
  • Express
  • Fastify
  • Hono
  • Koa
  • NestJS
Python
  • Flask
  • FastAPI
  • Django
PHP
  • Laravel

Drop it next to your existing router.

No router rewrite, no separate spec file, no decorator boilerplate. One contract surface across Node, Python, and PHP.