{"id":19781962,"url":"https://github.com/dcefram/fs-routes","last_synced_at":"2026-04-20T03:02:19.941Z","repository":{"id":42575256,"uuid":"236956658","full_name":"dcefram/fs-routes","owner":"dcefram","description":"Create routes based on the file structure. Works with fastify, express, polkajs, or anything that has the same express-like syntax. Inspired by Next.js' approach for its routes.","archived":false,"fork":false,"pushed_at":"2023-08-28T06:16:18.000Z","size":296,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-11T05:02:56.078Z","etag":null,"topics":["express","fastify","nodejs","polka","router","routes"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dcefram.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-29T10:27:36.000Z","updated_at":"2021-11-12T17:00:09.000Z","dependencies_parsed_at":"2023-02-07T13:16:12.834Z","dependency_job_id":null,"html_url":"https://github.com/dcefram/fs-routes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcefram%2Ffs-routes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcefram%2Ffs-routes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcefram%2Ffs-routes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcefram%2Ffs-routes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dcefram","download_url":"https://codeload.github.com/dcefram/fs-routes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241112281,"owners_count":19911658,"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":["express","fastify","nodejs","polka","router","routes"],"created_at":"2024-11-12T06:03:15.688Z","updated_at":"2026-04-20T03:02:14.918Z","avatar_url":"https://github.com/dcefram.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fs-routes\n\nInspired by Vercel's Nextjs approach to pages. Also inspired by the \"original\" [fs-router](https://github.com/jesseditson/fs-router) for [Micro](https://github.com/vercel/micro).\n\nI initially made this for [Polka](https://github.com/lukeed/polka), but it also worked for my newer fastify-based projects when that became a thing.\n\n## Features\n\n- Structure route handlers like serverless functions/lambdas\n- Zero dependencies\n- Zero configuration\n- Path segments\n\n## Installation\n\n```bash\nnpm i @dcefram/fs-routes\n```\n\n## Usage\n\nIn your entry file where you created your fastify, polka, or express app:\n\n```javascript\nimport Fastify from \"fastify\";\nimport fsRoutes from \"@dcefram/fs-routes\";\nconst fastify = Fastify({ logger: true });\n\nfsRoutes(fastify, \"/routes\").listen(process.env.PORT, (error) =\u003e {\n  if (error) throw error;\n\n  console.log(`API Server running at port ${process.env.PORT}`);\n});\n```\n\nFolder structure of your app:\n\n```bash\nyour-app\n├── index.js # assuming that this is where you initialized your fastify app\n└── routes\n    └── user\n        ├── [slug]\n        │   ├── images.js\n        │   └── comments.js\n        └── [slug].js\n```\n\nEach routes file should have a `module.exports` that exports an object that contains the handlers. Here's an example:\n\n```javascript\nconst httpErrors = require(\"http-errors\");\n\nmodule.exports = {\n  get: (request, reply) =\u003e {\n    const { slug } = req.params;\n    reply.send({ slug });\n  },\n  put: (request, reply) =\u003e {\n    reply.send(httpErrors.NotImplemented());\n  },\n  delete: (request, reply) =\u003e {\n    reply.send(httpErrors.NotImplemented());\n  },\n};\n```\n\nIt could also export the handlers using the ESM format:\n\n```javascript\n// OR export\nexport function get(request, reply) {\n  const { slug } = req.params;\n  reply.send({ slug });\n}\n\nexport function put(request, reply) {\n  reply.send(httpErrors.NotImplemented());\n}\n\nexport function delete(request, reply) {\n  reply.send(httpErrors.NotImplemented());\n}\n```\n\nWith the folder structure above, you'll get the following endpoints:\n\n````bash\nGET /user/:slug\nPUT /user/:slug\nDELETE /user/:slug\nGET /user/:slug/images # assuming that images.js has only `get` exported\nGET /user/:slug/comments # assuming that comments.js has only `get` exported\n\n### Ignore Files\n\nBy default, fs-routes will ignore all files that is prefixed with an underscore (`_`). Example:\n\n```bash\n\nyour-app\n├── index.js\n└── routes\n    └── user\n        ├── _helpers        # This folder will be ignored\n        │   └── some-reusable-logic.js\n        ├── [slug]\n        │   ├── images.js\n        │   ├── comments.js\n        │   └── _utils.js    # This file will be ignored\n        └── [slug].js\n````\n\nYou can overwrite the ignore pattern, and supply it with your own. Example:\n\n```javascript\nimport Fastify from \"fastify\";\nimport fsRoutes from \"@dcefram/fs-routes\";\n\nconst fastify = Fastify({ logger: true });\nconst ignorePattern = \"\\\\.internal\\\\.\"; // Will ignore files and folders with \".internal.\" in its name\n\nfsRoutes(fastify, \"/routes\", { ignorePattern }).listen(\n  process.env.PORT,\n  (error) =\u003e {\n    if (error) throw error;\n\n    console.log(`API Server running at port ${process.env.PORT}`);\n  }\n);\n```\n\n## Why make this?\n\nI liked how easy it was to navigate through a Next.js-based project. But there are times that we simply want to ship a pure Node.js API without the frontend,\nand this is one of the building blocks that I made to make sure that I stay happy building the project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcefram%2Ffs-routes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdcefram%2Ffs-routes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcefram%2Ffs-routes/lists"}