DEV Community

Seyves
Seyves

Posted on

Swagger docs from your existing TypeScript types — no framework required

The problem

Recently I was looking for an npm package to generate OpenAPI (Swagger) documentation for my existing TypeScript project. My biggest requirement was TypeScript type-to-schema conversion: I already have all my request and response types, so why should I maintain the same schemas again in OpenAPI? Zod support would be a nice bonus.

After trying most of the existing solutions, I found they generally fall into two categories:

1. Runtime frameworks

The most popular example is tsoa. Honestly, tsoa is one of the best OpenAPI generators available today: it understands TypeScript well, generates schemas automatically and detects status codes.

There are also contract-first libraries like ts-rest, Zodios and express-zod-api.

However, none of these solutions are agnostic when it comes to how you write your code — they all dictate the shape of your routes.

2. Manual generators

The best-known example is swagger-jsdoc. You write raw OpenAPI next to your code in JSDoc comments:

/**
 * @openapi
 * /users:
 *   post:
 *     ...
 */
Enter fullscreen mode Exit fullscreen mode

swagger-jsdoc is simple and framework-agnostic, but it's too verbose and knows nothing about your types.

Then I found a similar tool that solved the verbosity problem: @visulima/jsdoc-open-api. It parses much more readable JSDoc tags:

/**
 * POST /users
 * @summary Creates a new user.
 * @tags Users
 * @bodyContent {User} application/json - User object to create.
 * @bodyRequired
 * @response 201 - User created successfully.
 * @responseContent {User} 201.application/json - The created user object.
 */
Enter fullscreen mode Exit fullscreen mode

But it still doesn't care about your types. User here is just the name of a component you have to define elsewhere in your document. Why not parse the actual types at generation time? That question inspired me to create Autoswag.

The solution - Autoswag

Describe your routes with readable JSDoc, and let the generator convert your TS types along the way. It doesn't affect your runtime code in any way, works with any framework, and even with vanilla JS.

This is what Autoswag does:

// api/users.ts
import type { User, CreateUserRequest } from '@/types/user'

/**
 * @autoswag POST /users
 * @summary Create a new user
 * @tag Users
 * @accept {CreateUserRequest}
 * @response {User} 201 User created successfully
 * @response 400 Invalid input
 * @response 401 Unauthorized
 */
export async function createUser(req, res) {
    // Your implementation
}
Enter fullscreen mode Exit fullscreen mode

The types you specify in @accept and @response are parses and converted to OpenAPI schemas by Autoswag at generation time. You can also attach OpenAPI metadata right on your types:

export interface User {
    /**
     * User ID
     * @example "5516e359-6c9c-4ebb-a409-52373d536d50"
     * @format uuid
     */
    id: string

    /**
     * User's age
     * @example 32
     * @minimum 0
     * @maximum 200
     */
    age: number

    preferences: Preferences
}
Enter fullscreen mode Exit fullscreen mode

Already using Zod? Autoswag converts Zod schemas too, and picks up metadata straight from comments in the declaration:

export const UserSchema = z.object({
    /** @format uuid */
    id: z.uuid(),
    /** User name */
    name: z.string(),
    /** @format email */
    email: z.email(),
    age: z.number().int().optional(),
    address: AddressSchema,
    role: z.enum(['user', 'admin']),
    /** @format datetime */
    createdAt: z.iso.datetime(),
})

export type User = z.infer<typeof UserSchema>
Enter fullscreen mode Exit fullscreen mode

All of this happens at generation time — zero runtime dependencies, zero restrictions on how you structure your code.

JSDoc @typedef in vanilla JS is supported too, along with many more features.

Try it

If you have an existing project and don't want to rewrite it around a framework just to get docs, give Autoswag a try:

$ npm install -D autoswag
Enter fullscreen mode Exit fullscreen mode

Check out the GitHub repository (https://github.com/Seyves/autoswag) for the full feature list — issues, feedback and PRs are very welcome!

Top comments (0)