{"id":50100809,"url":"https://github.com/yusukebe/kakera","last_synced_at":"2026-05-23T07:15:46.739Z","repository":{"id":354940926,"uuid":"1225520006","full_name":"yusukebe/kakera","owner":"yusukebe","description":"A file-based routing framework with Cloudflare Dynamic Workers","archived":false,"fork":false,"pushed_at":"2026-05-08T02:39:26.000Z","size":430,"stargazers_count":58,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-08T04:33:11.844Z","etag":null,"topics":[],"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/yusukebe.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-30T11:10:34.000Z","updated_at":"2026-05-08T04:16:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yusukebe/kakera","commit_stats":null,"previous_names":["yusukebe/workerskit","yusukebe/kakera"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/yusukebe/kakera","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusukebe%2Fkakera","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusukebe%2Fkakera/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusukebe%2Fkakera/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusukebe%2Fkakera/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yusukebe","download_url":"https://codeload.github.com/yusukebe/kakera/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusukebe%2Fkakera/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33386339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"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":[],"created_at":"2026-05-23T07:15:45.273Z","updated_at":"2026-05-23T07:15:46.735Z","avatar_url":"https://github.com/yusukebe.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kakera\n\n\u003e **Kakera** (欠片) is Japanese for \"fragment\" or \"shard\" — each route is its own little fragment, sandboxed and loaded on demand.\n\nA file-based routing framework for Cloudflare Workers. Each route file runs as an **independent Dynamic Worker** — fully isolated, loaded via the Worker Loader binding.\n\n\u003e **Status:** experimental.\n\n## Install\n\n```sh\nnpm i kakera-worker\n```\n\n## How it looks\n\n```\nmy-app/\n  routes/\n    index.ts        # GET /\n    users.ts        # /users/*\n    posts.ts        # /posts/*\n  src/\n    app.ts          # host worker entry\n  build.ts          # bun build script\n  wrangler.jsonc\n  package.json\n```\n\nEach route is just a worker — typically a Hono app:\n\n```ts\n// routes/users.ts\nimport { Hono } from 'hono'\n\nconst app = new Hono()\napp.get('/', (c) =\u003e c.json({ users: [] }))\napp.get('/:id', (c) =\u003e c.json({ id: c.req.param('id') }))\n\nexport default app\n```\n\nThe host Worker dispatches by the first path segment (`/users/123` → `users.ts`, then forwards `/123`). Routes are sandboxed from each other.\n\n## Host worker\n\n```ts\n// src/app.ts\nexport { app as default } from 'kakera-worker'\n```\n\nThat's it. Or with options:\n\n```ts\nimport { kakera } from 'kakera-worker'\nexport default kakera({ dir: 'subdir' }) // fetches subdir/\u003cname\u003e.js via ASSETS\n```\n\n`extensions` option (default `['js']`):\n\n```ts\nkakera({ extensions: ['js', 'mjs'] })\n```\n\n## Build script\n\n`build.ts` uses Bun's `Glob` API so route discovery is shell-independent and works whether you have only `.ts`, only `.tsx`, or both:\n\n```ts\n// build.ts\nimport { Glob } from 'bun'\n\nconst entrypoints = [...new Glob('routes/*.{ts,tsx}').scanSync('.')]\n\nconst result = await Bun.build({\n  entrypoints,\n  outdir: './dist',\n  target: 'browser',\n  format: 'esm'\n})\n\nif (!result.success) {\n  for (const log of result.logs) console.error(log)\n  process.exit(1)\n}\n```\n\n## Wrangler config\n\nRoutes are pre-bundled per-file by `bun build`, and the output directory is served via the ASSETS binding. Wrangler's `[build]` runs the bundler on startup and re-runs it when `watch_dir` changes — `wrangler dev` is the only command you need.\n\n```jsonc\n// wrangler.jsonc\n{\n  \"name\": \"my-app\",\n  \"main\": \"src/app.ts\",\n  \"build\": {\n    \"command\": \"bun run build\",\n    \"watch_dir\": \"routes\"\n  },\n  \"assets\": { \"directory\": \"dist\", \"binding\": \"ASSETS\" },\n  \"worker_loaders\": [{ \"binding\": \"LOADER\" }],\n  \"compatibility_date\": \"2026-03-17\"\n}\n```\n\n## Scripts\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"wrangler dev\",\n    \"build\": \"bun run build.ts\",\n    \"deploy\": \"wrangler deploy\"\n  }\n}\n```\n\n- `wrangler dev` — runs `[build].command` (= `bun run build`), then starts workerd. Edits in `routes/` trigger a re-bundle and reload.\n- `wrangler deploy` — same flow, but ships to Cloudflare.\n\n## Try the example\n\n```sh\ncd example\nbun install\nbun run dev\n```\n\n## Why\n\n- **Isolation by default.** Each route is its own Worker — bugs, deps, and runtime crashes can't leak between routes.\n- **Tiny host bundle.** The host worker is ~1.6 KiB. No runtime bundler shipped.\n- **Standard tooling.** Bundling is `bun build`. Watch-and-rebuild is Wrangler's `[build]`. Nothing magic.\n- **Per-route bindings (planned).** Each route can eventually have its own scoped set of bindings.\n\n## How it works\n\n| Step                     |                                                                          |\n| ------------------------ | ------------------------------------------------------------------------ |\n| Host entry               | `src/app.ts` (re-exports `app` from `kakera-worker`)                     |\n| Route source on disk     | `routes/\u003cname\u003e.ts(x)` → `dist/\u003cname\u003e.js` (built by `build.ts`)           |\n| ASSETS binding directory | `dist`                                                                   |\n| Bundling                 | `bun build` invoked by Wrangler `[build]` on startup and on file changes |\n| LOADER cache key         | `\u003cname\u003e` (Worker Loader binding caches by key)                           |\n| Host bundle size         | ~1.6 KiB                                                                 |\n\n## References\n\n- [Dynamic Workers](https://developers.cloudflare.com/dynamic-workers/)\n- [Worker Loader binding](https://developers.cloudflare.com/workers/runtime-apis/bindings/worker-loader/)\n- [Wrangler custom builds](https://developers.cloudflare.com/workers/wrangler/configuration/#custom-builds)\n- [Hono](https://hono.dev/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyusukebe%2Fkakera","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyusukebe%2Fkakera","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyusukebe%2Fkakera/lists"}