{"id":13515401,"url":"https://github.com/fastify/middie","last_synced_at":"2025-05-14T08:09:25.712Z","repository":{"id":17282389,"uuid":"81619380","full_name":"fastify/middie","owner":"fastify","description":"Middleware engine for Fastify","archived":false,"fork":false,"pushed_at":"2025-05-01T00:13:33.000Z","size":248,"stargazers_count":262,"open_issues_count":0,"forks_count":26,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-05-01T01:25:23.108Z","etag":null,"topics":["fastify","fastify-plugin","middlewares","performances"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@fastify/middie","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fastify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"fastify","open_collective":"fastify"}},"created_at":"2017-02-11T00:33:51.000Z","updated_at":"2025-05-01T00:13:31.000Z","dependencies_parsed_at":"2024-01-23T20:11:26.358Z","dependency_job_id":"ce9433ad-d9ac-4938-a1e1-02d568c660d6","html_url":"https://github.com/fastify/middie","commit_stats":{"total_commits":258,"total_committers":36,"mean_commits":7.166666666666667,"dds":0.7093023255813953,"last_synced_commit":"f45120a56e0738ee11d0bbdcf322cb80ec1a031f"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fmiddie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fmiddie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fmiddie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Fmiddie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fastify","download_url":"https://codeload.github.com/fastify/middie/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101558,"owners_count":22014908,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastify","fastify-plugin","middlewares","performances"],"created_at":"2024-08-01T05:01:10.799Z","updated_at":"2025-05-14T08:09:20.697Z","avatar_url":"https://github.com/fastify.png","language":"JavaScript","readme":"# @fastify/middie\n\n[![CI](https://github.com/fastify/middie/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/fastify/middie/actions/workflows/ci.yml)\n[![NPM version](https://img.shields.io/npm/v/@fastify/middie.svg?style=flat)](https://www.npmjs.com/package/@fastify/middie)\n[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)\n\n*@fastify/middie* is the plugin that adds middleware support on steroids to [Fastify](https://www.npmjs.com/package/fastify).\n\nThe syntax style is the same as [express](http://npm.im/express)/[connect](https://www.npmjs.com/package/connect).\nDoes not support the full syntax `middleware(err, req, res, next)`, because error handling is done inside Fastify.\n\n## Install\n\n```\nnpm i @fastify/middie\n```\n\n## Usage\nRegister the plugin and start using your middleware.\n```js\nconst Fastify = require('fastify')\n\nasync function build () {\n  const fastify = Fastify()\n  await fastify.register(require('@fastify/middie'), {\n    hook: 'onRequest' // default\n  })\n  // do you know we also have cors support?\n  // https://github.com/fastify/fastify-cors\n  fastify.use(require('cors')())\n  return fastify\n}\n\nbuild()\n  .then(fastify =\u003e fastify.listen({ port: 3000 }))\n  .catch(console.log)\n```\n\n### Encapsulation support\n\nThe encapsulation works as usual with Fastify, you can register the plugin in a subsystem and your code will work only inside there, or you can declare the middie plugin top level and register a middleware in a nested plugin, and the middleware will be executed only for the nested routes of the specific plugin.\n\n*Register the plugin in its own subsystem:*\n```js\nconst fastify = require('fastify')()\n\nfastify.register(subsystem)\n\nasync function subsystem (fastify, opts) {\n  await fastify.register(require('@fastify/middie'))\n  fastify.use(require('cors')())\n}\n```\n\n*Register a middleware in a specific plugin:*\n```js\nconst fastify = require('fastify')()\n\nfastify\n  .register(require('@fastify/middie'))\n  .register(subsystem)\n\nasync function subsystem (fastify, opts) {\n  fastify.use(require('cors')())\n}\n```\n\n### Hooks and middleware\n\n__Every registered middleware will be run during the `onRequest` hook phase__, so the registration order is important.\nTake a look at the [Lifecycle](https://fastify.dev/docs/latest/Reference/Lifecycle/) documentation page to understand better how every request is executed.\n\n```js\nconst fastify = require('fastify')()\n\nfastify\n  .register(require('@fastify/middie'))\n  .register(subsystem)\n\nasync function subsystem (fastify, opts) {\n  fastify.addHook('onRequest', async (req, reply) =\u003e {\n    console.log('first')\n  })\n\n  fastify.use((req, res, next) =\u003e {\n    console.log('second')\n    next()\n  })\n\n  fastify.addHook('onRequest', async (req, reply) =\u003e {\n    console.log('third')\n  })\n}\n```\n\nIt is possible to change the Fastify hook that the middleware will be attached to. Supported lifecycle hooks are:\n - `onRequest`\n - `preParsing`\n - `preValidation`\n - `preHandler`\n - `preSerialization`\n - `onSend`\n - `onResponse`\n - `onError`\n - `onTimeout`\n\nTo change the hook, pass a `hook` option like so:\n\n*Note you can access `req.body` from the `preParsing`, `onError`, `preSerialization`, and `onSend` lifecycle steps. Take a look at the [Lifecycle](https://www.fastify.dev/docs/latest/Reference/Lifecycle/) documentation page to see the order of the steps.*\n\n```js\nconst fastify = require('fastify')()\n\nfastify\n  .register(require('@fastify/middie'), { hook: 'preHandler' })\n  .register(subsystem)\n\nasync function subsystem (fastify, opts) {\n  fastify.addHook('onRequest', async (req, reply) =\u003e {\n    console.log('first')\n  })\n\n  fastify.use((req, res, next) =\u003e {\n    console.log('third')\n    next()\n  })\n\n  fastify.addHook('onRequest', async (req, reply) =\u003e {\n    console.log('second')\n  })\n\n  fastify.addHook('preHandler', async (req, reply) =\u003e {\n    console.log('fourth')\n  })\n}\n```\n\n### Restrict middleware execution to a certain path(s)\n\nIf you need to run a middleware only under certain path(s), just pass the path as the first parameter to use and you are done!\n\n```js\nconst fastify = require('fastify')()\nconst path = require('node:path')\nconst serveStatic = require('serve-static')\n\nfastify\n  .register(require('@fastify/middie'))\n  .register(subsystem)\n\nasync function subsystem (fastify, opts) {\n  // Single path\n  fastify.use('/css', serveStatic(path.join(__dirname, '/assets')))\n\n  // Wildcard path\n  fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets')))\n\n  // Multiple paths\n  fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))\n}\n```\n\n#### :warning: potential ReDoS attacks\n\nMiddie uses [`path-to-regexp`](http://npm.im/path-to-regexp) to convert paths to regular expressions.\nThis might cause potential [ReDoS](https://en.wikipedia.org/wiki/ReDoS) attacks in your applications if\ncertain patterns are used. Use it with care.\n\n# Middie Engine\n\nYou can also use the engine itself without the Fastify plugin system.\n\n## Usage\n```js\nconst Middie = require('@fastify/middie/engine')\nconst http = require('node:http')\nconst helmet = require('helmet')\nconst cors = require('cors')\n\nconst middie = Middie(_runMiddlewares)\nmiddie.use(helmet())\nmiddie.use(cors())\n\nhttp\n  .createServer(function handler (req, res) {\n    middie.run(req, res)\n  })\n  .listen(3000)\n\nfunction _runMiddlewares (err, req, res) {\n  if (err) {\n    console.log(err)\n    res.end(err)\n    return\n  }\n\n  // =\u003e routing function\n}\n```\n\u003ca name=\"keep-context\"\u003e\u003c/a\u003e\n#### Keep the context\nIf you need it you can also keep the context of the calling function by calling `run` with `run(req, res, this)`, avoiding closures allocation.\n\n```js\nhttp\n  .createServer(function handler (req, res) {\n    middie.run(req, res, { context: 'object' })\n  })\n  .listen(3000)\n\nfunction _runMiddlewares (err, req, res, ctx) {\n  if (err) {\n    console.log(err)\n    res.end(err)\n    return\n  }\n  console.log(ctx)\n}\n```\n\n\u003ca name=\"restrict-usage\"\u003e\u003c/a\u003e\n#### Restrict middleware execution to a certain path(s)\nIf you need to run a middleware only under certain path(s), just pass the path as the first parameter to `use` and you are done!\n\n*Note that this does support routes with parameters, e.g. `/user/:id/comments`, but all the matched parameters will be discarded*\n\n```js\n// Single path\nmiddie.use('/public', staticFiles('/assets'))\n\n// Multiple middleware\nmiddie.use('/public', [cors(), staticFiles('/assets')])\n\n// Multiple paths\nmiddie.use(['/public', '/dist'], staticFiles('/assets'))\n\n// Multiple paths and multiple middleware\nmiddie.use(['/public', '/dist'], [cors(), staticFiles('/assets')])\n```\n\nTo guarantee compatibility with Express, adding a prefix uses [`path-to-regexp`](https://www.npmjs.com/package/path-to-regexp) to compute\na `RegExp`, which is then used to match every request: it is significantly slower.\n\n## TypeScript support\n\nTo use this module with TypeScript, make sure to install `@types/connect`.\n\n## Middleware alternatives\n\nFastify offers some alternatives to the most commonly used Express middleware:\n\n| Express Middleware | Fastify Plugin |\n| ------------- |---------------|\n| [`helmet`](https://github.com/helmetjs/helmet) | [`fastify-helmet`](https://github.com/fastify/fastify-helmet) |\n| [`cors`](https://github.com/expressjs/cors) | [`fastify-cors`](https://github.com/fastify/fastify-cors) |\n| [`serve-static`](https://github.com/expressjs/serve-static) | [`fastify-static`](https://github.com/fastify/fastify-static) |\n\n## Acknowledgments\n\nThis project is kindly sponsored by:\n- [nearForm](https://nearform.com)\n\nPast sponsors:\n- [LetzDoIt](https://www.letzdoitapp.com/)\n\n## License\n\nLicensed under [MIT](./LICENSE).\n","funding_links":["https://github.com/sponsors/fastify","https://opencollective.com/fastify"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Fmiddie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffastify%2Fmiddie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Fmiddie/lists"}