npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sleekify/sleekify-fastify

v2.0.2

Published

A TypeScript decorator driven approach for developing Fastify web applications.

Downloads

855

Readme

Sleekify Fastify Integration

This project integrates Sleekify with Fastify. Sleekify lets you apply decorators to your resource classes to identify your REST resources and associate them with OpenAPI definitions. This integration turns those resource classes into Fastify routes and generates your OpenAPI specification from them. See the Sleekify README for an overview of the decorators and the full API reference.

Versions

| Sleekify | Fastify | Node.js | OpenAPI Specification | TypeScript | TypeScript Config | Decorator Type | | -------- | ------- | ------- | --------------------- | ---------- | --------------------------------- | ------------------- | | 2.0.0+ | 5.0.0+ | 24 | 3.1.1 | 5.9+ | "experimentalDecorators": false | Standard ES/TC39 | | 1.0.0+ | 5.0.0+ | 20 | 3.1.1 | 5.0+ | "experimentalDecorators": true | Legacy experimental |

Use the same major version of Sleekify and the Fastify integration. To decide which version is right for your project, see Choosing a Version in the Sleekify README.

Getting Started

  1. Install Fastify, Sleekify, and the Fastify integration.

    npm install fastify @sleekify/sleekify @sleekify/sleekify-fastify
  2. Configure your tsconfig.json for the decorators used by your Sleekify version. For 2.0.0+, make sure the legacy experimental decorators are turned off:

    {
      "compilerOptions": {
        "experimentalDecorators": false,
        "emitDecoratorMetadata": false
      }
    }

    See Getting Started in the Sleekify README for more details.

  3. Create REST resources using the provided decorators. src/v1/users.ts

    import { type FastifyReply, type FastifyRequest } from 'fastify';
    import { DELETE, GET, NotFoundError, Path, POST, PUT, Schema } from '@sleekify/sleekify';
    
    @Path('/v1/users')
    export class UsersResource {
      @POST()
      async createOne (request: FastifyRequest, reply: FastifyReply) {
        // TODO: your create user code here
      }
    
      @GET()
      async getMany (request: FastifyRequest, reply: FastifyReply) {
        // TODO: your query users code here
      }
    }
    
    @Path({
      path: '/v1/users/{id}',
      parameters: [
        {
          $ref: '#/components/parameters/id'
        }
      ]
    })
    @Schema({
      $ref: '#/components/schemas/user'
    })
    export class UsersIdResource {
      @GET()
      async getOne (request: FastifyRequest, reply: FastifyReply) {
        const user: object | undefined = undefined; // TODO: look up the user here
    
        if (user === undefined) {
          throw new NotFoundError('The user was not found');
        }
    
        return user;
      }
    
      @PUT()
      async updateOne (request: FastifyRequest, reply: FastifyReply) {
        // TODO: your update user code here
      }
    
      @DELETE()
      async deleteOne (request: FastifyRequest, reply: FastifyReply) {
        // TODO: your delete user code here
      }
    }
  4. Create your base OpenAPI specification. src/openapi.ts

    import { type OpenAPIObject } from '@sleekify/sleekify';
    
    export const specification: OpenAPIObject = {
      openapi: '3.1.1',
      info: {
        title: 'My API',
        version: '1.0.0'
      },
      components: {
        parameters: {
          id: {
            description: 'The identifier of the resource',
            name: 'id',
            in: 'path',
            required: true,
            schema: {
              $ref: '#/components/schemas/id'
            }
          }
        },
        schemas: {
          id: {
            description: 'The id path parameter schema',
            type: ['integer']
          },
          user: {
            type: ['object'],
            properties: {
              id: {
                type: ['number']
              },
              name: {
                type: ['string']
              }
            }
          }
        }
      }
    };
  5. Register your OpenAPI specification and resources with Fastify. src/index.ts

    import Fastify from 'fastify';
    import { Annotation, Path } from '@sleekify/sleekify';
    import { Sleekify } from '@sleekify/sleekify-fastify';
    import { specification } from './openapi';
    
    const fastify = Fastify({
      logger: true
    });
    
    async function run () {
      // 1. Find all of your resource classes
      const classList = await Annotation.getClassesAnnotatedWith('./v1', Path);
      // 2. Create a Sleekify instance
      const sleekify = new Sleekify(specification, classList);
    
      // 3. Register Sleekify with Fastify
      await fastify.register(sleekify.getPlugin());
    
      fastify.listen({ port: 3000 }, function (error) {
        if (error != null) {
          fastify.log.error(error);
          process.exit(1);
        }
      });
    }
    
    void run();

How It Works

Resource Methods

Each resource method decorated with an HTTP method decorator such as @GET becomes a Fastify route handler. The method receives Fastify's request and reply objects, and the value it returns is sent as the response body. You may also use reply directly when you need to set headers or a custom status code.

If a resource method throws one of Sleekify's web application errors, such as NotFoundError, Fastify responds with the error's HTTP status code. You may use Fastify's setErrorHandler to customize how errors are serialized into responses.

Request Validation

Routing and request validation are provided by fastify-openapi-glue. Requests are validated against the parameters and request bodies in your generated OpenAPI specification before your resource methods are called. Any options you pass when registering the plugin are forwarded to fastify-openapi-glue:

await fastify.register(sleekify.getPlugin(), {
  prefix: '/api'
});

Operation IDs

Every operation needs an operationId to connect it to its resource method. If you don't provide one, it's generated from the HTTP method and path in camel case. For example, GET /v1/users/{id} gets the operation ID getV1UsersId. You may set your own operation ID in the decorator, e.g. @GET({ operationId: 'getUser' }).

API Reference

The Sleekify Class

| Method | Description | | - | - | | new Sleekify(specification, classList) | Creates a new instance from your base OpenAPI specification and your resource classes. | | getPlugin() | Gets a Fastify plugin which you can register with fastify.register. | | getSpecification(options?) | Gets the generated OpenAPI specification. Pass { pretty: true } to sort the paths, components, responses, servers, and tags. This is useful for serving your API documentation or saving it to a file. | | getServiceHandlers() | Gets the service handlers keyed by operation ID. This is only needed if you want to register fastify-openapi-glue yourself instead of using getPlugin(). |

For example, to serve your generated OpenAPI specification:

const openApiDocument = sleekify.getSpecification({ pretty: true });

fastify.get('/openapi.json', async () => openApiDocument);

For more information on the provided decorators, OpenAPI types, and web application errors see the Sleekify API Reference.

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines and CODE_OF_CONDUCT.md for our code of conduct.

Security

To report a security vulnerability, see SECURITY.md.

License

Sleekify Fastify Integration is licensed under the Apache License 2.0.