{"id":13452024,"url":"https://github.com/lukeed/trouter","last_synced_at":"2025-10-21T07:14:51.741Z","repository":{"id":57380132,"uuid":"109609665","full_name":"lukeed/trouter","owner":"lukeed","description":":fish: A fast, small-but-mighty, familiar fish...errr, router*","archived":false,"fork":false,"pushed_at":"2024-06-02T16:21:11.000Z","size":72,"stargazers_count":642,"open_issues_count":2,"forks_count":23,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-10-25T19:09:27.052Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/lukeed.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"lukeed"}},"created_at":"2017-11-05T19:35:11.000Z","updated_at":"2024-10-22T20:36:42.000Z","dependencies_parsed_at":"2024-02-04T15:09:43.442Z","dependency_job_id":"db4512e5-10f6-4c67-ae3f-6b7879f1c056","html_url":"https://github.com/lukeed/trouter","commit_stats":{"total_commits":92,"total_committers":4,"mean_commits":23.0,"dds":0.03260869565217395,"last_synced_commit":"c5176edd1cd94b439a341c6b009f2f7b3d42d5a6"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeed%2Ftrouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeed%2Ftrouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeed%2Ftrouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukeed%2Ftrouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukeed","download_url":"https://codeload.github.com/lukeed/trouter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221796399,"owners_count":16881845,"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":[],"created_at":"2024-07-31T07:01:10.436Z","updated_at":"2025-10-09T18:24:27.012Z","avatar_url":"https://github.com/lukeed.png","language":"JavaScript","funding_links":["https://github.com/sponsors/lukeed"],"categories":["JavaScript","Packages"],"sub_categories":[],"readme":"# trouter [![CI](https://github.com/lukeed/trouter/actions/workflows/ci.yml/badge.svg)](https://github.com/lukeed/trouter/actions/workflows/ci.yml)\n\n\u003e 🐟 A fast, small-but-mighty, familiar ~fish~ router\n\n\n## Install\n\n```\n$ npm install --save trouter\n```\n\n\n## Usage\n\n```js\nimport { Trouter } from 'trouter';\n\nconst router = new Trouter();\n\n// Define all routes\nrouter\n  .get('/users', _ =\u003e {\n    console.log('\u003e Getting all users');\n  })\n  .add('POST', '/users', _ =\u003e {\n    console.log('~\u003e Adding a user');\n  })\n  .get('/users/:id', val =\u003e {\n    console.log('~\u003e Getting user with ID:', val);\n  });\n\n// Find a route definition\nlet obj = router.find('GET', '/users/123');\n//=\u003e obj.params ~\u003e { id:123 }\n//=\u003e obj.handlers ~\u003e Array\u003cFunction\u003e\n\n// Execute the handlers, passing value\nobj.handlers.forEach(fn =\u003e {\n  fn(obj.params.id);\n});\n//=\u003e ~\u003e Getting user with ID: 123\n\n// Returns empty keys when no match\nrouter.find('DELETE', '/foo');\n//=\u003e { params:{}, handlers:[] }\n```\n\n## API\n\n### Trouter()\nInitializes a new `Trouter` instance.\n\n\n### trouter.add(method, pattern, ...handlers)\nReturns: `self`\n\nStores a `method` + `pattern` pairing internally, along with its handler(s).\n\n#### method\nType: `String`\n\nAny uppercased, [valid HTTP/1.1 verb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods#Specifications) \u0026mdash; choose from one of the following:\n\n```\nGET  HEAD  PATCH  OPTIONS  CONNECT  DELETE  TRACE  POST  PUT\n```\n\n#### pattern\nType: `String` or `RegExp`\n\nTrouter supports simple route patterns which are fast and well readable but limited. If you need more complex patterns, you can pass an instance of `RegExp` with parameters specified as named capture groups.\n\n\u003e **Important:** RegExp named capture groups are [supported in Node.js 10.x](https://node.green/#ES2018-features--RegExp-named-capture-groups) and above!\n\nThe supported route pattern types are:\n\n* static (`/users`)\n* named parameters (`/users/:id`)\n* nested parameters (`/users/:id/books/:title`)\n* optional parameters (`/users/:id?/books/:title?`)\n* suffixed parameters (`/movies/:title.mp4`, `movies/:title.(mp4|mov)`)\n* any match / wildcards (`/users/*`)\n* optional wildcards (`/users/*?`)\n\n#### ...handlers\nType: `Function`\n\nThe function(s) that should be tied to this `pattern`.\n\nBecause this is a [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters), whatever you pass will _always_ be cast to an Array.\n\n\u003e **Important:** Trouter does not care what your function signature looks like!\u003cbr\u003e You are not bound to the `(req, res)` standard, or even passing a `Function` at all!\n\n\n### trouter.use(pattern, ...handlers)\nReturns: `self`\n\nThis is an alias for [`trouter.add('', pattern, ...handlers)`](#trouteraddmethod-pattern-handlers), matching **all** HTTP methods.\n\nHowever, unlike [`trouter.all`](#trouterallpattern-handlers), the `pattern` you defined **IS NOT RESTRICTIVE**, which means that the route will match any \u0026 all URLs that start (but not end) with a matching segment.\n\n```js\nrouter.use('/foo', 'USE /foo');\nrouter.use('/foo/:name', 'USE /foo/:name');\nrouter.post('/foo/:name', 'POST /foo/:name');\nrouter.head('/foo/:name/hello', 'HEAD /foo/:name/hello');\n\nrouter.find('GET', '/foo').handlers;\n//=\u003e ['USE /foo']\n\nrouter.find('POST', '/foo/bar').handlers;\n//=\u003e ['USE /foo', 'USE /foo/:name', 'POST /foo/:name']\n\nrouter.find('HEAD', '/foo/bar/hello').handlers;\n//=\u003e ['USE /foo', 'USE /foo/:name', 'HEAD /foo/:name/hello']\n```\n\u003csup\u003e_Compare this snippet with the one below to see differences between `trouter.all` and this method._\u003c/sup\u003e\n\n\n### trouter.all(pattern, ...handlers)\nReturns: `self`\n\nThis is an alias for [`trouter.add('', pattern, ...handlers)`](#trouteraddmethod-pattern-handlers), matching **all** HTTP methods.\n\nHowever, unlike [`trouter.use`](#trouterusepattern-handlers), the `pattern` you defined **IS RESTRICTIVE** and behaves like any other [`trouter.METHOD`](#trouteraddmethod-pattern-handlers) route. This means that the URL must match the defined `pattern` exactly – or have the appropriate optional and/or wildcard segments to accommodate the desired flexibility.\n\n```js\nrouter.all('/foo', 'ALL /foo');\nrouter.all('/foo/:name', 'ALL /foo/:name');\nrouter.post('/foo/:name', 'POST /foo/:name');\nrouter.head('/foo/:name/hello', 'HEAD /foo/:name/hello');\n\nrouter.find('GET', '/foo').handlers;\n//=\u003e ['ALL /foo']\n\nrouter.find('POST', '/foo/bar').handlers;\n//=\u003e ['ALL /foo/:name', 'POST /foo/:name']\n\nrouter.find('HEAD', '/foo/bar/hello').handlers;\n//=\u003e ['HEAD /foo/:name/hello']\n```\n\u003csup\u003e_Compare this snippet with the one above to see differences between `trouter.use` and this method._\u003c/sup\u003e\n\n\n\n### trouter.METHOD(pattern, ...handlers)\n\nThis is an alias for [`trouter.add(METHOD, pattern, ...handlers)`](#trouteraddmethod-pattern-handlers), where `METHOD` is any lowercased HTTP verb.\n\n```js\nconst noop = _ =\u003e {}:\nconst app = new Trouter();\n\napp.get('/users/:id', noop);\napp.post('/users', noop);\napp.patch('/users/:id', noop);\n\n// less common methods too\napp.trace('/foo', noop);\napp.connect('/bar', noop);\n```\n\n### trouter.find(method, url)\nReturns: `Object`\n\nSearches within current instance for **all** `method` + `pattern` pairs that satisfy the current `method` + `url`.\n\n\u003e **Important:** Parameters and handlers are assembled/gathered _in the order that they were defined!_\n\nThis method will always return an Object with `params` and `handlers` keys.\n\n* `params` \u0026mdash; Object whose keys are the named parameters of your route pattern.\n* `handlers` \u0026mdash; Array containing the `...handlers` provided to [`.add()`](#trouteraddmethod-pattern-handlers) or [`.METHOD()`](#troutermethodpattern-handlers)\n\n\u003e **Note:** The `handlers` and `params` keys will be empty if no matches were found.\n\n\n#### method\nType: `String`\n\nAny valid HTTP method name, uppercased.\n\n\u003e **Note:** When searching for `HEAD` routes, `GET` routes will also be inspected.\n\n#### url\nType: `String`\n\nThe URL used to match against pattern definitions. This is typically `req.url`.\n\n\n## Benchmarks\n\n\u003e Run on Node v10.13.0\n\n```\nGET /                           x 10,349,863 ops/sec ±2.15% (93 runs sampled)\nPOST /users                     x 13,895,099 ops/sec ±0.40% (94 runs sampled)\nGET /users/:id                  x  6,288,457 ops/sec ±0.25% (93 runs sampled)\nPUT /users/:id/books/:title?    x  6,176,501 ops/sec ±0.22% (96 runs sampled)\nDELETE /users/:id/books/:title  x  5,581,288 ops/sec ±2.04% (96 runs sampled)\nHEAD /hello (all)               x  9,700,097 ops/sec ±0.47% (90 runs sampled)\n```\n\n## License\n\nMIT © [Luke Edwards](https://lukeed.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukeed%2Ftrouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukeed%2Ftrouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukeed%2Ftrouter/lists"}