{"id":50791251,"url":"https://github.com/litejs/server","last_synced_at":"2026-06-12T11:02:18.095Z","repository":{"id":362273808,"uuid":"1157773926","full_name":"litejs/server","owner":"litejs","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-10T14:24:55.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-10T16:07:47.560Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/litejs.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":null,"dco":null,"cla":null},"funding":{"github":"lauriro"}},"created_at":"2026-02-14T09:19:49.000Z","updated_at":"2026-06-10T14:25:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/litejs/server","commit_stats":null,"previous_names":["litejs/server"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/litejs/server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litejs%2Fserver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litejs%2Fserver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litejs%2Fserver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litejs%2Fserver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/litejs","download_url":"https://codeload.github.com/litejs/server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litejs%2Fserver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34240817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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-06-12T11:02:17.333Z","updated_at":"2026-06-12T11:02:18.084Z","avatar_url":"https://github.com/litejs.png","language":"JavaScript","funding_links":["https://github.com/sponsors/lauriro","https://www.buymeacoffee.com/lauriro"],"categories":[],"sub_categories":[],"readme":"[1]: https://badgen.net/coveralls/c/github/litejs/server\n[2]: https://coveralls.io/r/litejs/server\n[3]: https://badgen.net/packagephobia/install/@litejs/server\n[4]: https://packagephobia.now.sh/result?p=@litejs/server\n[5]: https://badgen.net/badge/icon/Buy%20Me%20A%20Tea/orange?icon=kofi\u0026label\n[6]: https://www.buymeacoffee.com/lauriro\n\n\nLiteJS Server \u0026ndash; [![Coverage][1]][2] [![Size][3]][4] [![Buy Me A Tea][5]][6]\n=============\n\nA small, zero-dependency HTTP application core that runs the same code across\nBun, Cloudflare Workers, Deno, Node.js, and on browser Service Worker.\n\n\n## Usage\n\n`npm install @litejs/server`\n\n```javascript\n// app.mjs\nimport { App } from \"@litejs/server\"\n\nconst app = App()\n\n// Middlewares runs only if any route matches\napp.use((req, env) =\u003e {\n\t// return a response to stop further execution\n})\n\n// Only single, first matching route get executed!\napp.get('hello/world', (res, env) =\u003e 'Hello MOON!')\napp.get('hello/{name}', (res, env) =\u003e 'Hello ' + req.param.name)\napp.get('bye/{name}', (res, env) =\u003e 'Bye ' + req.param.name)\napp.get('bye/moon', (res, env) =\u003e { /* Never executed as previous handler matches */ })\napp.get('teapot', () =\u003e ({ body: \"no coffee\", status: 418 }))\napp.get('notFound', () =\u003e 404) // Return a number to send status code\n\n// Group routes and mount under a prefix\nconst subApp = App()\n.post(\"\", (req, env) =\u003e {\n    // GET /api -\u003e req.path == '/' and req.fullPath == '/api'\n    return { data: [] }\n})\n.post(\"echo\", async (req, env) =\u003e {\n    // POST /api/echo -\u003e req.path == '/echo' and req.fullPath == '/api/echo'\n    return await req.json()\n})\n\napp.mount(\"api\", subApp)\n\nexport default app\n```\n\nHandlers receive `(req, env)` and may return\na string (sent as `text/plain`),\na number (status only),\nan object (serialized to JSON),\na `{ body, status, headers }` object,\nor a native `Response`.\nThrown errors map to `err.code || 500`.\n\nRequests include `param`, `path`, `fullPath`, `query`, `searchParams`, and `header(name)`.\n\n### Routes\n\n - `user/{username}` matches one path segment (no `/`)\n - `post/{id+}` matches one or more digits\n - `files/{rest*}.ext` matches all chars, greedy\n - `a/{dir/}{name}` matches zero or more slash-terminated directories\n - `pub/\\{x}` matches the literal path `pub/{x}`\n\n\n## Adapters\n\nThe same `app` runs on every runtime.\n`@litejs/server` exports the matching adapter through conditional export,\nso the one file below runs unchanged on Node.js, Bun, and Deno.\n\n```javascript\n// run.mjs\nimport {\n    DB, KV, listen, loadEnv, serveStatic, setupShutdown\n} from \"@litejs/server\"\nimport app from \"./app.mjs\"\n\nconst db = new DB(\"db.sqlite\")\nconst env = loadEnv(\".env.json\", {\n    ASSETS: serveStatic(\"public\"),\n    // Inject Cloudflare style KV on top of sqlite\n    DEVICE: KV(db, \"device\"),\n})\nconst server = listen(app, env)\napp.get(\"/{path*}\", env.ASSETS.fetch)\n\n// Attach SIGINT/SIGTERM/SIGHUP/uncaughtException\nsetupShutdown([ server ])\n```\n\nRun it with `node run.mjs`, `bun run.mjs`, or `deno run -A run.mjs`.\n\n### Runtimes\n\n - Node.js, Bun, Deno: import from `@litejs/server`; the runtime is detected automatically.\n - Cloudflare Workers: `import { worker } from \"@litejs/server\"`, then `export default { fetch: worker(app) }`.\n - Service Workers: `import { listen } from \"@litejs/server\"`.\n\nOn Node, Bun, and Deno `@litejs/server` also exports `serveStatic`, `loadEnv`,\n`setupShutdown`, and SQLite-backed `DB` (D1) and `KV` shims.\n\nRunnable examples are in [`test/server/`](test/server/).\n\n\u003e Copyright (c) 2026 Lauri Rooden \u0026lt;lauri@rooden.ee\u0026gt;  \n[MIT License](https://litejs.com/MIT-LICENSE.txt) |\n[GitHub repo](https://github.com/litejs/server) |\n[npm package](https://npmjs.org/package/@litejs/server) |\n[Buy Me A Tea][6]\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitejs%2Fserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flitejs%2Fserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitejs%2Fserver/lists"}