{"id":22297537,"url":"https://github.com/cjvnjde/nano-router","last_synced_at":"2026-04-29T08:03:07.336Z","repository":{"id":253541807,"uuid":"843806046","full_name":"cjvnjde/nano-router","owner":"cjvnjde","description":"A lightweight and flexible routing library designed for handling complex routes with support for path parameters, wildcard routes, and optional segments","archived":false,"fork":false,"pushed_at":"2024-09-22T13:45:01.000Z","size":73,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-30T20:15:04.130Z","etag":null,"topics":["api","nodejs","router","server"],"latest_commit_sha":null,"homepage":"https://jsr.io/@cjvnjde/nano-router","language":"TypeScript","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/cjvnjde.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}},"created_at":"2024-08-17T13:30:09.000Z","updated_at":"2024-09-22T13:45:03.000Z","dependencies_parsed_at":"2024-08-17T15:30:38.935Z","dependency_job_id":"71e80a39-592c-4f8b-bb0b-12290d029e57","html_url":"https://github.com/cjvnjde/nano-router","commit_stats":null,"previous_names":["cjvnjde/nano-router"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjvnjde%2Fnano-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjvnjde%2Fnano-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjvnjde%2Fnano-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjvnjde%2Fnano-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cjvnjde","download_url":"https://codeload.github.com/cjvnjde/nano-router/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245556960,"owners_count":20634889,"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":["api","nodejs","router","server"],"created_at":"2024-12-03T17:50:03.371Z","updated_at":"2026-04-29T08:03:02.292Z","avatar_url":"https://github.com/cjvnjde.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @cjvnjde/nano-router\n\n[![JSR Version](https://img.shields.io/jsr/v/%40cjvnjde/nano-router)](https://jsr.io/@cjvnjde/nano-router)\n\n[@cjvnjde/nano-router](https://jsr.io/@cjvnjde/nano-router) is a lightweight and flexible routing library designed for handling complex routes with support for path parameters, wildcard routes, and optional segments. This library is ideal for use in Node.js applications where efficient and dynamic routing is essential.\nThis library was inspired by Fastify, a powerful and feature-rich web framework. However, [@cjvnjde/nano-router](https://jsr.io/@cjvnjde/nano-router) focuses on providing a minimalistic and focused routing solution without the overhead of additional features that are not always necessary.\n\n## Features\n\n* Simple API: Add routes and match them with minimal configuration.\n* Path Parameters: Supports named parameters in routes for dynamic matching.\n* Wildcard Routes: Match routes with wildcard segments.\n* Optional Parameters: Handle optional segments in routes.\n* Route Grouping: Group routes with common prefixes to keep your code organized.\n* HTTP Method Support: Full support for GET, POST, PUT, DELETE, PATCH, OPTIONS, and HEAD methods\n\n## Installation\n\nInstall the package using the following command:\n\nnpm:\n```bash\nnpx jsr add @cjvnjde/nano-router\n```\nyarn:\n```bash\nyarn dlx jsr add @cjvnjde/nano-router\n```\npnpm:\n```bash\npnpm dlx jsr add @cjvnjde/nano-router\n```\nbun:\n```bash\nbunx jsr add @cjvnjde/nano-router\n```\ndeno:\n```bash\ndeno add jsr:@cjvnjde/nano-router\n```\n\n## Usage\n\n### Basic Example\n\n```js\nimport * as http from 'node:http';\nimport { Router } from '@cjvnjde/nano-router';\n\nconst router = new Router();\n\nrouter.on('/', (req, res) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('Welcome to the home page!');\n});\n\nrouter.on('/about', (req, res) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('About us');\n});\n\nrouter.on('/user/:id', (req, res, params) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({ userId: params.id }));\n});\n\nconst server = http.createServer((req, res) =\u003e {\n  const match = router.match(req.url);\n\n  if (match) {\n    match.handler(req, res, match.params);\n  } else {\n    res.writeHead(404, { 'Content-Type': 'text/plain' });\n    res.end('Not Found');\n  }\n});\n\nserver.listen(3000, () =\u003e {\n  console.log('Server is running on http://localhost:3000');\n});\n```\n\n### Handling Wildcard Routes\n\nWildcard routes allow for flexible matching of paths. For example, you can use them to match static file paths or any other dynamic segment.\n\n```js\nrouter.on('/static/*', (req, res) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('This is a static file route');\n});\n\nrouter.on('/api/*', (req, res) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({ message: 'API route' }));\n});\n```\n\n### Optional Parameters in Routes\n\nRoutes can have optional segments. These optional parameters allow you to match different lengths of the URL path.\n\n```js\nrouter.on('/posts/:year/:month?/:day?', (req, res, params) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify(params));\n});\n\n// Example matches:\n// /posts/2024 -\u003e { year: \"2024\" }\n// /posts/2024/08 -\u003e { year: \"2024\", month: \"08\" }\n// /posts/2024/08/18 -\u003e { year: \"2024\", month: \"08\", day: \"18\" }\n```\n\n### Combining Multiple Features\n\nYou can combine path parameters, wildcard segments, and optional parameters to create more complex routes.\n\n```js\nrouter.on('/user/:id/profile', (req, res, params) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end(`User Profile for ID: ${params.id}`);\n});\n\nrouter.on('/user/:id/settings', (req, res, params) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end(`Settings for User ID: ${params.id}`);\n});\n\nrouter.on('/files/*', (req, res) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('Serving files');\n});\n\n// Example matches:\n// /user/123/profile -\u003e User Profile for ID: 123\n// /user/123/settings -\u003e Settings for User ID: 123\n// /files/images/photo.png -\u003e Serving files\n```\n\n### Groupping\n\nYou can group routes with a common prefix to simplify route management and keep your code clean. This is especially useful when dealing with APIs or versioned endpoints.\n\n```js\nrouter.group(\"v1\", router =\u003e {\n  router.on('/static/*', (req, res) =\u003e {\n    res.writeHead(200, { 'Content-Type': 'text/plain' });\n    res.end('This is a static file route');\n  });\n\n  router.on('/api/*', (req, res) =\u003e {\n    res.writeHead(200, { 'Content-Type': 'application/json' });\n    res.end(JSON.stringify({ message: 'API route' }));\n  });\n})\n```\n\n### Handling HTTP Methods\n\nThe `MethodRouter` allows you to handle different HTTP methods (e.g., GET, POST, PUT, DELETE, etc.) for the same URL pattern. Here's an example:\n\n```js\nconst methodRouter = new MethodRouter();\n\nmethodRouter.get('/items', (req, res) =\u003e {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({ message: 'GET items' }));\n});\n\nmethodRouter.post('/items', (req, res) =\u003e {\n  res.writeHead(201, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({ message: 'Item created' }));\n});\n\n// Example matches:\n// GET /items -\u003e 'GET items'\n// POST /items -\u003e 'Item created'\n```\n\n### Middleware-like Grouping for Organizing Complex Routes\n\nYou can use the group function to create middleware-like behavior by organizing routes in a hierarchical way.\n\n```js\nmethodRouter.group('api', (router) =\u003e {\n  router.get('/users', (req, res) =\u003e {\n    res.writeHead(200, { 'Content-Type': 'application/json' });\n    res.end(JSON.stringify({ message: 'List of users' }));\n  });\n\n  router.post('/users', (req, res) =\u003e {\n    res.writeHead(201, { 'Content-Type': 'application/json' });\n    res.end(JSON.stringify({ message: 'User created' }));\n  });\n});\n```\n\n### Error Handling\n\nYou can define a default handler to handle unmatched routes, providing a 404 response for routes that are not registered.\n\n```js\nconst server = http.createServer((req, res) =\u003e {\n  const match = router.match(req.method, req.url);\n\n  if (match) {\n    match.handler(req, res, match.params);\n  } else {\n    res.writeHead(404, { 'Content-Type': 'text/plain' });\n    res.end('404 Not Found');\n  }\n});\n```\n\n### Visualizing the Route Tree\n\nUse the toString() method to print the current structure of the route tree.\n\n```js\nconsole.log(router.toString());\n```\n\nThis will output a tree-like structure:\n\n`one/:two`\n`one/three`\n`one/:three/four/:five`\n\n```txt\n└─ root [type: default, params: []]\n   └─ one [type: default, params: []]\n      ├─ * [type: parametrized, params: [two]]\n      │  └─ four [type: default, params: []]\n      │     └─ * [type: parametrized, params: [three, five]]\n      └─ three [type: default, params: []]\n```\n\nSee [tests](https://github.com/cjvnjde/nano-router/blob/main/src/Router.test.ts) for more examples.\n\n## Complexity\n\nTheoretically, the `match` method has O(n) complexity since it uses dictionaries to look up routes. The complexity depends only on the number of route fragments.\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](https://github.com/cjvnjde/nano-router/blob/main/LICENSE) file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjvnjde%2Fnano-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcjvnjde%2Fnano-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjvnjde%2Fnano-router/lists"}