{"id":43065450,"url":"https://github.com/nikrowell/kahe","last_synced_at":"2026-01-31T12:38:34.432Z","repository":{"id":57288094,"uuid":"102529201","full_name":"nikrowell/kahe","owner":"nikrowell","description":"Minimal frontend framework for managing transition flow between pages.","archived":false,"fork":false,"pushed_at":"2018-08-25T15:57:08.000Z","size":130,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-12-26T17:18:02.536Z","etag":null,"topics":["browser","framework","frontend","pushstate","router","transitions"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/nikrowell.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":"2017-09-05T20:57:48.000Z","updated_at":"2022-01-25T20:14:50.000Z","dependencies_parsed_at":"2022-09-11T08:03:15.223Z","dependency_job_id":null,"html_url":"https://github.com/nikrowell/kahe","commit_stats":null,"previous_names":[],"tags_count":22,"template":null,"template_full_name":null,"purl":"pkg:github/nikrowell/kahe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikrowell%2Fkahe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikrowell%2Fkahe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikrowell%2Fkahe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikrowell%2Fkahe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nikrowell","download_url":"https://codeload.github.com/nikrowell/kahe/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikrowell%2Fkahe/sbom","scorecard":{"id":687690,"data":{"date":"2025-08-11","repo":{"name":"github.com/nikrowell/kahe","commit":"32abcf87e72d4427a44047b24574f7cebd401790"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"46 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-9vvw-cc9w-f27h","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-hr2v-3952-633q","Warn: Project is vulnerable to: GHSA-qrmc-fj45-qfc2","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-xf7w-r453-m56c","Warn: Project is vulnerable to: GHSA-44pw-h2cw-w3vq","Warn: Project is vulnerable to: GHSA-jp4x-w63m-7wgm","Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-fvqr-27wr-82fm","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-6g33-f262-xjp4","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-2m39-62fm-q8r3","Warn: Project is vulnerable to: GHSA-mf6x-7mm4-x2g7","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-g7q5-pjjr-gqvp","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-w5p7-h5w8-2hfq"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T01:23:09.213Z","repository_id":57288094,"created_at":"2025-08-22T01:23:09.214Z","updated_at":"2025-08-22T01:23:09.214Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28943627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T12:10:04.904Z","status":"ssl_error","status_checked_at":"2026-01-31T12:09:58.894Z","response_time":128,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["browser","framework","frontend","pushstate","router","transitions"],"created_at":"2026-01-31T12:38:33.761Z","updated_at":"2026-01-31T12:38:34.427Z","avatar_url":"https://github.com/nikrowell.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kahe\n\nkahe (k\u0026#257;'-he) is a 2k client-side router built on ideas from [page.js](https://visionmedia.github.io/page.js/), [bigwheel](https://github.com/bigwheel-framework/bigwheel) and [ReactTransitionGroupPlus](https://www.npmjs.com/package/react-transition-group-plus).\n\nkahe's emphasis is on enabling animated transitions between pages or application states. Routes are mapped to views which support several lifecyle methods and are responsible for all rendering logic with the provided request data. Before and after hooks receive information about where the request is going, and were it's coming from.\n\n**Why kahe?**\nBecause it's the Hawaiian word for _flow_. And because nearly everything else is taken.\n\n## Installation\n\nInstall through [npm](https://www.npmjs.com/package/kahe) or use as a standalone library with a script tag and one of the bundled files. Please message me if you're interested in a CDN version!\n\n`npm install kahe`\n\n## Usage\n\n```javascript\nimport kahe from 'kahe';\nimport { Home, About, Project } from './views';\n\nkahe.start({\n  routes: {\n    '/': Home,\n    '/about': About\n    '/projects/:slug': Project\n  }\n});\n```\n\n### Options\n\nProperty         | Default  | Description\n---------------- | -------- | -----------------------------------------\n**`base`**       | `/`      | Base URL to use when resolving routes.\n**`routes`**     | `[]`     | an object mapping URL patterns to view function(s), or an array of routes config objects with `path` and `view` properties. These can also be defined using the `route(path, config)` method.\n**`before`**     | `null`   | A function or array of functions to be called before a transition begins. Each callback recieves a transition object with `to` and `from` properties representing the incoming and outgoing requests.\n**`after`**      | `null`   | A function or array of functions to be called after a transition completes. Each callback recieves a transition object with `to` and `from` properties representing the incoming and outgoing requests.\n**`transition`** | `null`   | A string to specify the default transition flow (see [transitions](#transitions)) or a function to be called before a transition begins.\n\n### Routes\n\nRoutes can be defined in several ways.\n\n**Using individual `route()` calls:**\n```javascript\nimport { route, start } from 'kahe';\n\nroute('/', Home);\nroute('/about', About);\nroute('/projects/:slug', Project);\n\n// start resolving routes\nstart();\n```\n\n**Using a routes array:**\n```javascript\nkahe.start({\n  routes: [\n    {path: '/', view: Home},\n    {path: '/about', view: About},\n    {path: '/projects/:slug', view: Project}\n  ]\n});\n```\n\n**Using a routes object:**\n```javascript\nkahe.start({\n  routes: {\n    '/': Home,\n    '/about': About\n    '/projects/:slug': Project\n  }\n});\n```\n\n### Views\n\nViews are functions or objects that optionally implement the following lifescyle methods:\n\n- init\n- resize\n- animateIn\n- animateOut\n- destroy\n\nThe `init`, `animateIn` and `animateOut` methods receives two arguments: `req` and `done`. `req` is an object representing request data, including captured url params. The `resize` method is called immediately before `animateIn` and recieves the current window width and height as arguments. Use the `destory` method to run cleanup work such as removing DOM nodes or event listeners.\n\n### Transitions\n\nTransitions manage the flow between application states and are what make kahe unique. Inspired by [ReactTransitionGroupPlus](https://www.npmjs.com/package/react-transition-group-plus) and the once popular [Gaia Framework](https://github.com/stevensacks/Gaia-Framework/wiki/The-gaia-flow) for Flash, transitions come in three types which control the order at which lifecycle methods are called on incoming and outgoing views.\n\n#### normal\n\nTransitions are synchronous.\n\n* incoming.init(req, done)\n* incoming.animateIn(req, done) _and_ outgoing.animateOut(req, done)\n\n#### out-in\n\n* incoming.init(req, done)\n* outgoing.animateOut(req, done)\n* incoming.animateIn(req)\n\n#### in-out\n\n* incoming.init(req, done)\n* incoming.animateIn(req, done)\n* outgoing.animateOut(req, done)\n\nWith all transition types, if another URL is requested while a transitio is in progress, it will be queued and executed imediately after the current transition completes.\n\n## API\n\n### route(path[, config]);\n\nAdds a route definition if both path and config are specificed. Route config optinos can be a single object representing a view function, an array of view functions or objects or an object containing a `view` property (object or array). The advantage of the last option is being able to add custom route meta that gets merged with the request object. Example:\n\n```javascript\nroute('/', {view: Home, name: 'home'});\nroute('/photos/:category', {view: Gallery, name: 'gallery'});\n```\n\nCalling route with only a string with navigate to the given URL. This is called internally by the framework when a link is clicked, but can be useful to programmatically change states. ~~~Optionally pass `{replace: true}` to update the current `window.history` record rather than pushing a new entry onto the stack.~~~\n\n### before(transition);\n\n### after(transition);\n\n### start(options);\n\nStart the framework and begin resolving routes.\n\n## Browser Support\n\nkahe uses Promises to handle transition flow, which means a polyfill would be required for IE11 and below.\n\n## Development\n\nUnit tests (which are incomplete!) use [budo](https://www.npmjs.com/package/budo), [tape](https://www.npmjs.com/package/tape) and [tap-dev-tool](https://www.npmjs.com/package/tap-dev-tool) (for more readable output).\n\n```bash\nnpm install -g budo\nnpm install\nnpm run test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikrowell%2Fkahe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikrowell%2Fkahe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikrowell%2Fkahe/lists"}