{"id":13799396,"url":"https://github.com/tunnckoCore/koa-better-router","last_synced_at":"2025-05-13T08:31:05.160Z","repository":{"id":48020546,"uuid":"70727414","full_name":"tunnckoCore/koa-better-router","owner":"tunnckoCore","description":":heart: Stable and lovely router for `koa`, using `path-match`. Foundation for building powerful, flexible and RESTful APIs easily.","archived":false,"fork":false,"pushed_at":"2023-01-23T19:25:23.000Z","size":1144,"stargazers_count":90,"open_issues_count":25,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-07T13:38:24.421Z","etag":null,"topics":["composable","extensible","fast","koa2","middleware","powerful","restful","router","small","stable"],"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/tunnckoCore.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-12T18:08:02.000Z","updated_at":"2024-11-19T13:09:54.000Z","dependencies_parsed_at":"2023-01-24T16:30:59.348Z","dependency_job_id":null,"html_url":"https://github.com/tunnckoCore/koa-better-router","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-better-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-better-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-better-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-better-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tunnckoCore","download_url":"https://codeload.github.com/tunnckoCore/koa-better-router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253903689,"owners_count":21981731,"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":["composable","extensible","fast","koa2","middleware","powerful","restful","router","small","stable"],"created_at":"2024-08-04T00:01:02.283Z","updated_at":"2025-05-13T08:31:05.140Z","avatar_url":"https://github.com/tunnckoCore.png","language":"JavaScript","funding_links":[],"categories":["仓库"],"sub_categories":["中间件"],"readme":"# koa-better-router [![NPM version](https://img.shields.io/npm/v/koa-better-router.svg?style=flat)](https://www.npmjs.com/package/koa-better-router) [![NPM monthly downloads](https://img.shields.io/npm/dm/koa-better-router.svg?style=flat)](https://npmjs.org/package/koa-better-router) [![npm total downloads][downloads-img]][downloads-url]\n\n\u003e Stable and lovely router for [koa][], using [path-match][]. Foundation for building powerful, flexible and RESTful APIs easily.\n\n[![standard code style][standard-img]][standard-url]\n[![linux build status][travis-img]][travis-url]\n[![coverage status][coveralls-img]][coveralls-url]\n[![dependency status][david-img]][david-url]\n\nYou may also be interested in [koa-rest-router][]. It uses this router for creating\npowerful, flexible and RESTful APIs for enterprise easily!\n\n## Highlights\n- **production:** ready for and used in\n- **foundation:** very simple core for building more powerful routers such as [koa-rest-router][]\n- **composability:** group multiple routes and multiple routers - see [.groupRoutes](#grouproutes) and [.addRoutes](#addroutes)\n- **flexibility:** multiple prefixes on same router\n- **compatibility:** accepts both old and modern middlewares without deprecation messages\n- **powerful:** multiple routers on same [koa][] app - even can combine multiple routers\n- **light:** not poluting your router instance and app - see [.loadMethods](#loadmethods)\n- **smart:** does only what you say it to do\n- **small:** very small on dependencies - curated and only most needed\n- **backward compatible:** works on koa v1 - use [.legacyMiddleware](#legacymiddleware)\n- **maintainability:** very small, beautiful, maintainable and commented codebase\n- **stability:** strict semantic versioning and very well documented\n- **tested:** very well tested with 100% coverage\n- **lovely:** ~500 downloads for the first 2 days\n- **open:** love PRs for features, issues and recipes - [Contribute a recipe?](#contributing-recipes)\n\n## Table of Contents\n- [Install](#install)\n- [Usage](#usage)\n- [API](#api)\n  * [KoaBetterRouter](#koabetterrouter)\n  * [.loadMethods](#loadmethods)\n  * [.createRoute](#createroute)\n  * [.addRoute](#addroute)\n  * [.getRoute](#getroute)\n  * [.addRoutes](#addroutes)\n  * [.getRoutes](#getroutes)\n  * [.groupRoutes](#grouproutes)\n  * [.extend](#extend)\n  * [.middleware](#middleware)\n  * [.legacyMiddleware](#legacymiddleware)\n- [Related](#related)\n- [Contributing](#contributing)\n- [Contributing Recipes](#contributing-recipes)\n- [Building docs](#building-docs)\n- [Running tests](#running-tests)\n- [Author](#author)\n- [License](#license)\n\n_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_\n\n## Install\nInstall with [npm](https://www.npmjs.com/)\n\n```\n$ npm install koa-better-router --save\n```\n\nor install using [yarn](https://yarnpkg.com)\n\n```\n$ yarn add koa-better-router\n```\n\n## Usage\n\u003e For more use-cases see the [tests](./test.js)\n\n```js\nlet router = require('koa-better-router')().loadMethods()\n\n// or\n\nlet Router = require('koa-better-router')\nlet router = Router() // or new Router(), no matter\n```\n\n## API\n\n### [KoaBetterRouter](index.js#L57)\n\u003e Initialize `KoaBetterRouter` with optional `options` which are directly passed to [path-match][] and so to [path-to-regexp][] too. In addition we have two more - `prefix` and `notFound`.\n\n**Params**\n\n* `[options]` **{Object}**: options passed to [path-match][]/[path-to-regexp][] directly    \n* `[options.notFound]` **{Function}**: if passed, called with `ctx, next` when route not found    \n\n**Example**\n\n```js\nlet Router = require('koa-better-router')\nlet router = Router().loadMethods()\n\nrouter.get('/', (ctx, next) =\u003e {\n  ctx.body = `Hello world! Prefix: ${ctx.route.prefix}`\n  return next()\n})\n\n// can use generator middlewares\nrouter.get('/foobar', function * (next) {\n  this.body = `Foo Bar Baz! ${this.route.prefix}`\n  yield next\n})\n\nlet api = Router({ prefix: '/api' })\n\n// add `router`'s routes to api router\napi.extend(router)\n\n// The server\nlet Koa = require('koa') // Koa v2\nlet app = new Koa()\n\napp.use(router.middleware())\napp.use(api.middleware())\n\napp.listen(4444, () =\u003e {\n  console.log('Try out /, /foobar, /api/foobar and /api')\n})\n```\n\n### [.loadMethods](index.js#L103)\n\u003e Load the HTTP verbs as methods on instance. If you not \"load\" them you can just use [.addRoute](#addroute) method. If you \"load\" them, you will have method for each item on [methods][] array - such as `.get`, `.post`, `.put` etc.\n\n* `returns` **{KoaBetterRouter}** `this`: instance for chaining  \n\n**Example**\n\n```js\nlet router = require('koa-better-router')()\n\n// all are `undefined` if you\n// don't `.loadMethods` them\nconsole.log(router.get)\nconsole.log(router.post)\nconsole.log(router.put)\nconsole.log(router.del)\nconsole.log(router.addRoute) // =\u003e function\nconsole.log(router.middleware) // =\u003e function\nconsole.log(router.legacyMiddleware) // =\u003e function\n\nrouter.loadMethods()\n\nconsole.log(router.get)  // =\u003e function\nconsole.log(router.post) // =\u003e function\nconsole.log(router.put)  // =\u003e function\nconsole.log(router.del)  // =\u003e function\nconsole.log(router.addRoute) // =\u003e function\nconsole.log(router.middleware) // =\u003e function\nconsole.log(router.legacyMiddleware) // =\u003e function\n```\n\n### [.createRoute](index.js#L155)\n\u003e Just creates _\"Route Object\"_ without adding it to `this.routes` array, used by [.addRoute](#addroute) method.\n\n**Params**\n\n* `\u003cmethod\u003e` **{String}**: http verb or `'GET /users'`    \n* `[route]` **{String|Function}**: for what `ctx.path` handler to be called    \n* `...fns` **{Function}**: can be array or single function, any number of arguments after `route` can be given too    \n* `returns` **{Object}**: plain `route` object with useful properties  \n\n**Example**\n\n```js\nlet router = require('koa-better-router')({ prefix: '/api' })\nlet route = router.createRoute('GET', '/users', [\n  function (ctx, next) {},\n  function (ctx, next) {},\n  function (ctx, next) {},\n])\n\nconsole.log(route)\n// =\u003e {\n//   prefix: '/api',\n//   route: '/users',\n//   pathname: '/users',\n//   path: '/api/users',\n//   match: matcher function against `route.path`\n//   method: 'GET',\n//   middlewares: array of middlewares for this route\n// }\n\nconsole.log(route.match('/foobar'))    // =\u003e false\nconsole.log(route.match('/users'))     // =\u003e false\nconsole.log(route.match('/api/users')) // =\u003e true\nconsole.log(route.middlewares.length)  // =\u003e 3\n```\n\n### [.addRoute](index.js#L254)\n\u003e Powerful method to add `route` if you don't want to populate you router instance with dozens of methods. The `method` can be just HTTP verb or `method` plus `route` something like `'GET /users'`. Both modern and generators middlewares can be given too, and can be combined too. **Adds routes to `this.routes` array**.\n\n**Params**\n\n* `\u003cmethod\u003e` **{String}**: http verb or `'GET /users'`    \n* `[route]` **{String|Function}**: for what `ctx.path` handler to be called    \n* `...fns` **{Function}**: can be array or single function, any number of arguments after `route` can be given too    \n* `returns` **{KoaBetterRouter}** `this`: instance for chaining  \n\n**Example**\n\n```js\nlet router = require('koa-better-router')()\n\n// any number of middlewares can be given\n// both modern and generator middlewares will work\nrouter.addRoute('GET /users',\n  (ctx, next) =\u003e {\n    ctx.body = `first ${ctx.route.path};`\n    return next()\n  },\n  function * (next) {\n    this.body = `${this.body} prefix is ${this.route.prefix};`\n    yield next\n  },\n  (ctx, next) =\u003e {\n    ctx.body = `${ctx.body} and third middleware!`\n    return next()\n  }\n)\n\n// You can middlewares as array too\nrouter.addRoute('GET', '/users/:user', [\n  (ctx, next) =\u003e {\n    ctx.body = `GET /users/${ctx.params.user}`\n    console.log(ctx.route)\n    return next()\n  },\n  function * (next) {\n    this.body = `${this.body}, prefix is: ${this.route.prefix}`\n    yield next\n  }\n])\n\n// can use `koa@1` and `koa@2`, both works\nlet Koa = require('koa')\nlet app = new Koa()\n\napp.use(router.middleware())\napp.listen(4290, () =\u003e {\n  console.log('Koa server start listening on port 4290')\n})\n```\n\n### [.getRoute](index.js#L284)\n\u003e Get a route by `name`. Name of each route is its pathname or route. For example: the `name` of `.get('/cat/foo')` route is `/cat/foo`, but if you pass `cat/foo` - it will work too.\n\n**Params**\n\n* `name` **{String}**: name of the Route Object    \n* `returns` **{Object|Null}**: Route Object, or `null` if not found  \n\n**Example**\n\n```js\nlet router = require('koa-better-router')().loadMethods()\n\nrouter.get('/cat/foo', function (ctx, next) {})\nrouter.get('/baz', function (ctx, next) {})\n\nconsole.log(router.getRoute('baz'))      // =\u003e Route Object\nconsole.log(router.getRoute('cat/foo'))  // =\u003e Route Object\nconsole.log(router.getRoute('/cat/foo')) // =\u003e Route Object\n```\n\n### [.addRoutes](index.js#L339)\n\u003e Concats any number of arguments (arrays of route objects) to the `this.routes` array. Think for it like registering routes. Can be used in combination with [.createRoute](#createroute) and [.getRoute](#getroute).\n\n**Params**\n\n* `...args` **{Array}**: any number of arguments (arrays of route objects)    \n* `returns` **{KoaBetterRouter}** `this`: instance for chaining  \n\n**Example**\n\n```js\nlet router = require('koa-better-router')()\n\n// returns Route Object\nlet foo = router.createRoute('GET', '/foo', function (ctx, next) {\n  ctx.body = 'foobar'\n  return next()\n})\nconsole.log(foo)\n\nlet baz = router.createRoute('GET', '/baz/qux', function (ctx, next) {\n  ctx.body = 'baz qux'\n  return next()\n})\nconsole.log(baz)\n\n// Empty array because we just\n// created them, didn't include them\n// as actual routes\nconsole.log(router.routes.length) // 0\n\n// register them as routes\nrouter.addRoutes(foo, baz)\n\nconsole.log(router.routes.length) // 2\n```\n\n### [.getRoutes](index.js#L369)\n\u003e Simple method that just returns `this.routes`, which is array of route objects.\n\n* `returns` **{Array}**: array of route objects  \n\n**Example**\n\n```js\nlet router = require('koa-better-router')()\n\nrouter.loadMethods()\n\nconsole.log(router.routes.length) // 0\nconsole.log(router.getRoutes().length) // 0\n\nrouter.get('/foo', (ctx, next) =\u003e {})\nrouter.get('/bar', (ctx, next) =\u003e {})\n\nconsole.log(router.routes.length) // 2\nconsole.log(router.getRoutes().length) // 2\n```\n\n### [.groupRoutes](index.js#L425)\n\u003e Groups multiple _\"Route Objects\"_ into one which middlewares will be these middlewares from the last \"source\". So let say you have `dest` route with 2 middlewares appended to it and the `src1` route has 3 middlewares, the final (returned) route object will have these 3 middlewares from `src1` not the middlewares from `dest`. Make sense? If not this not make sense for you, please open an issue here, so we can discuss and change it (then will change it in the [koa-rest-router][] too, because there the things with method `.groupResource` are the same).\n\n**Params**\n\n* `dest` **{Object}**: known as _\"Route Object\"_    \n* `src1` **{Object}**: second _\"Route Object\"_    \n* `src2` **{Object}**: third _\"Route Object\"_    \n* `returns` **{Object}**: totally new _\"Route Object\"_ using [.createRoute](#createroute) under the hood  \n\n**Example**\n\n```js\nlet router = require('./index')({ prefix: '/api/v3' })\n\nlet foo = router.createRoute('GET /foo/qux/xyz', function (ctx, next) {})\nlet bar = router.createRoute('GET /bar', function (ctx, next) {})\n\nlet baz = router.groupRoutes(foo, bar)\nconsole.log(baz)\n// =\u003e Route Object {\n//   prefix: '/api/v3',\n//   path: '/api/v3/foo/qux/sas/bar',\n//   pathname: '/foo/qux/sas/bar'\n//   ...\n// }\n\n// Server part\nlet Koa = require('koa')\nlet app = new Koa()\n\nrouter.addRoutes(baz)\n\napp.use(router.middleware())\napp.listen(2222, () =\u003e {\n  console.log('Server listening on http://localhost:2222')\n\n  router.getRoutes().forEach((route) =\u003e {\n    console.log(`${route.method} http://localhost:2222${route.path}`)\n  })\n})\n```\n\n### [.extend](index.js#L466)\n\u003e Extends current router with routes from `router`. This `router` should be an instance of KoaBetterRouter too. That is the **correct extending/grouping** of couple of routers.\n\n**Params**\n\n* `\u003crouter\u003e` **{Object}**: instance of KoaBetterRouter    \n* `returns` **{KoaBetterRouter}** `this`: instance for chaining  \n\n**Example**\n\n```js\nlet router = require('koa-better-router')()\nlet api = require('koa-better-router')({\n  prefix: '/api/v4'\n})\n\nrouter.addRoute('GET', '/foo/bar', () =\u003e {})\nrouter.addRoute('GET', '/api/v4/qux', () =\u003e {}) // intentional !\napi.addRoute('GET', '/woohoo')\n\napi.extend(router)\n\napi.getRoutes().forEach(route =\u003e console.log(route.path))\n// =\u003e outputs (the last one is expected)\n// /api/v4/woohoo\n// /api/v4/foo/bar\n// /api/v4/api/v4/qux\n```\n\n### [.middleware](index.js#L524)\n\u003e Active all routes that are defined. You can pass `opts` to pass different `prefix` for your routes. So you can have multiple prefixes with multiple routes using just one single router. You can also use multiple router instances. Pass `legacy: true` to `opts` and you will get generator function that can be used in Koa v1.\n\n* `returns` **{Function}**: modern [koa][] v2 middleware  \n\n**Example**\n\n```js\nlet Router = require('koa-better-router')\nlet api = Router({ prefix: '/api' })\n\napi.loadMethods()\n  .get('GET /', (ctx, next) =\u003e {\n    ctx.body = 'Hello world!'\n    return next()\n  }, (ctx, next) =\u003e {\n    ctx.body = `${ctx.body} Try out /api/users too`\n    return next()\n  })\n\napi.get('/users', function * (next) {\n  this.body = `Prefix: ${this.route.prefix}, path: ${this.route.path}`\n  yield next\n})\n\n// Server part\nlet Koa = require('koa')\nlet app = new Koa()\n\n// Register the router as Koa middleware\napp.use(api.middleware())\n\napp.listen(4321, () =\u003e {\n  console.log('Modern Koa v2 server is started on port 4321')\n})\n```\n\n### [.legacyMiddleware](index.js#L583)\n\u003e Explicitly use this method when want to use the router on **Koa@1**, otherwise use [.middleware](#middleware) method!\n\n* `returns` **{GeneratorFunction}**: old [koa][] v1 middleware  \n\n**Example**\n\n```js\nlet app = require('koa')() // koa v1.x\nlet router = require('koa-better-router')()\n\nrouter.addRoute('GET', '/users', function * (next) {\n  this.body = 'Legacy KOA!'\n  yield next\n})\n\napp.use(router.legacyMiddleware())\napp.listen(3333, () =\u003e {\n  console.log('Open http://localhost:3333/users')\n})\n```\n\n## Related\n- [koa-bel](https://www.npmjs.com/package/koa-bel): View engine for `koa` without any deps, built to be used with `bel`. Any other engines that can be written… [more](https://github.com/tunnckocore/koa-bel#readme) | [homepage](https://github.com/tunnckocore/koa-bel#readme \"View engine for `koa` without any deps, built to be used with `bel`. Any other engines that can be written in `.js` files would work, too.\")\n- [koa-better-body](https://www.npmjs.com/package/koa-better-body): Full-featured [koa][] body parser! Support parsing text, buffer, json, json patch, json api, csp-report, multipart, form and urlencoded bodies. Works… [more](https://github.com/tunnckocore/koa-better-body#readme) | [homepage](https://github.com/tunnckocore/koa-better-body#readme \"Full-featured [koa][] body parser! Support parsing text, buffer, json, json patch, json api, csp-report, multipart, form and urlencoded bodies. Works for koa@1, koa@2 and will work for koa@3.\")\n- [koa-better-ratelimit](https://www.npmjs.com/package/koa-better-ratelimit): Better, smaller, faster - koa middleware for limit request by ip, store in-memory. | [homepage](https://github.com/tunnckoCore/koa-better-ratelimit \"Better, smaller, faster - koa middleware for limit request by ip, store in-memory.\")\n- [koa-better-serve](https://www.npmjs.com/package/koa-better-serve): Small, simple and correct serving of files, using [koa-send][] - nothing more. | [homepage](https://github.com/tunnckocore/koa-better-serve#readme \"Small, simple and correct serving of files, using [koa-send][] - nothing more.\")\n- [koa-ip-filter](https://www.npmjs.com/package/koa-ip-filter): Middleware for [koa][] that filters IPs against glob patterns, RegExp, string or array of globs. Support custom `403 Forbidden` message… [more](https://github.com/tunnckocore/koa-ip-filter#readme) | [homepage](https://github.com/tunnckocore/koa-ip-filter#readme \"Middleware for [koa][] that filters IPs against glob patterns, RegExp, string or array of globs. Support custom `403 Forbidden` message and custom ID.\")\n- [koa-rest-router](https://www.npmjs.com/package/koa-rest-router): Most powerful, flexible and composable router for building enterprise RESTful APIs easily! | [homepage](https://github.com/tunnckocore/koa-rest-router#readme \"Most powerful, flexible and composable router for building enterprise RESTful APIs easily!\")\n- [nanomatch](https://www.npmjs.com/package/nanomatch): Fast, minimal glob matcher for node.js. Similar to micromatch, minimatch and multimatch, but complete Bash 4.3 wildcard support only (no… [more](https://github.com/jonschlinkert/nanomatch) | [homepage](https://github.com/jonschlinkert/nanomatch \"Fast, minimal glob matcher for node.js. Similar to micromatch, minimatch and multimatch, but complete Bash 4.3 wildcard support only (no support for exglobs, posix brackets or braces)\")\n\n## Contributing\nPull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/tunnckoCore/koa-better-router/issues/new).  \nPlease read the [contributing guidelines](CONTRIBUTING.md) for advice on opening issues, pull requests, and coding standards.  \nIf you need some help and can spent some cash, feel free to [contact me at CodeMentor.io](https://www.codementor.io/tunnckocore?utm_source=github\u0026utm_medium=button\u0026utm_term=tunnckocore\u0026utm_campaign=github) too.\n\n**In short:** If you want to contribute to that project, please follow these things\n\n1. Please DO NOT edit [README.md](README.md), [CHANGELOG.md](CHANGELOG.md) and [.verb.md](.verb.md) files. See [\"Building docs\"](#building-docs) section.\n2. Ensure anything is okey by installing the dependencies and run the tests. See [\"Running tests\"](#running-tests) section.\n3. Always use `npm run commit` to commit changes instead of `git commit`, because it is interactive and user-friendly. It uses [commitizen][] behind the scenes, which follows Conventional Changelog idealogy.\n4. Do NOT bump the version in package.json. For that we use `npm run release`, which is [standard-version][] and follows Conventional Changelog idealogy.\n\nThanks a lot! :)\n\n## Contributing Recipes\nRecipes are just different use cases, written in form of README in human language. Showing some \"Pro Tips\" and tricks, answering common questions and so on. They look like [tests](./test.js), but in more readable and understandable way for humans - mostly for beginners that not reads or understand enough the README or API and tests.\n\n- They are in form of folders in the root [`recipes/`](./recipes) folder: for example `recipes/[short-meaningful-recipe-name]/`.\n- In recipe folder should exist `README.md` file\n- In recipe folder there may have actual js files, too. And should be working.\n- The examples from the recipe README.md should also exist as separate `.js` files.\n- Examples in recipe folder also should be working and actual.\n\nIt would be great if you follow these steps when you want to _fix, update or create_ a recipes. :sunglasses:\n\n- Title for recipe idea should start with `[recipe]`: for example`[recipe] my awesome recipe`\n- Title for new recipe (PR) should also start with `[recipe]`.\n- Titles of Pull Requests or Issues for fixing/updating some existing recipes should start with `[recipe-fix]`.\n\nIt will help a lot, thanks in advance! :yum:\n\n## Building docs\nDocumentation and that readme is generated using [verb-generate-readme][], which is a [verb][] generator, so you need to install both of them and then run `verb` command like that\n\n```\n$ npm install verbose/verb#dev verb-generate-readme --global \u0026\u0026 verb\n```\n\n_Please don't edit the README directly. Any changes to the readme must be made in [.verb.md](.verb.md)._\n\n## Running tests\nClone repository and run the following in that cloned directory\n\n```\n$ npm install \u0026\u0026 npm test\n```\n\n## Author\n**Charlike Mike Reagent**\n\n+ [github/tunnckoCore](https://github.com/tunnckoCore)\n+ [twitter/tunnckoCore](https://twitter.com/tunnckoCore)\n+ [codementor/tunnckoCore](https://codementor.io/tunnckoCore)\n\n## License\nCopyright © 2016-2017, [Charlike Mike Reagent](http://www.tunnckocore.tk). Released under the [MIT license](LICENSE).\n\n***\n\n_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.1, on January 20, 2017._  \n_Project scaffolded using [charlike][] cli._\n\n[charlike]: https://github.com/tunnckocore/charlike\n[commitizen]: https://github.com/commitizen/cz-cli\n[koa-convert]: https://github.com/gyson/koa-convert\n[koa-rest-router]: https://github.com/tunnckocore/koa-rest-router\n[koa-send]: https://github.com/koajs/send\n[koa]: https://github.com/koajs/koa\n[methods]: https://github.com/jshttp/methods\n[micromatch]: https://github.com/jonschlinkert/micromatch\n[path-match]: https://github.com/pillarjs/path-match\n[path-to-regexp]: https://github.com/pillarjs/path-to-regexp\n[recipe]: https://github.com/DamonOehlman/recipe\n[standard-version]: https://github.com/conventional-changelog/standard-version\n[through2]: https://github.com/rvagg/through2\n[use]: https://github.com/jonschlinkert/use\n[verb-generate-readme]: https://github.com/verbose/verb-generate-readme\n[verb]: https://github.com/verbose/verb\n[vinyl]: https://github.com/gulpjs/vinyl\n\n[downloads-url]: https://www.npmjs.com/package/koa-better-router\n[downloads-img]: https://img.shields.io/npm/dt/koa-better-router.svg\n\n[codeclimate-url]: https://codeclimate.com/github/tunnckoCore/koa-better-router\n[codeclimate-img]: https://img.shields.io/codeclimate/github/tunnckoCore/koa-better-router.svg\n\n[travis-url]: https://travis-ci.org/tunnckoCore/koa-better-router\n[travis-img]: https://img.shields.io/travis/tunnckoCore/koa-better-router/master.svg?label=linux\n\n[appveyor-url]: https://ci.appveyor.com/project/tunnckoCore/koa-better-router\n[appveyor-img]: https://img.shields.io/appveyor/ci/tunnckoCore/koa-better-router/master.svg?label=windows\n\n[coveralls-url]: https://coveralls.io/r/tunnckoCore/koa-better-router\n[coveralls-img]: https://img.shields.io/coveralls/tunnckoCore/koa-better-router.svg\n\n[david-url]: https://david-dm.org/tunnckoCore/koa-better-router\n[david-img]: https://img.shields.io/david/tunnckoCore/koa-better-router.svg\n\n[standard-url]: https://github.com/feross/standard\n[standard-img]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FtunnckoCore%2Fkoa-better-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FtunnckoCore%2Fkoa-better-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FtunnckoCore%2Fkoa-better-router/lists"}