Skip to content

Latest commit

 

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LiteJS Server – Coverage Size Buy Me A Tea

A small, zero-dependency HTTP application core that runs the same code across local runtimes (Bun, Deno, Node.js, txiki.js), cloud providers (Cloudflare Workers, Deno Deploy, Netlify, Vercel), and browser service workers.

Usage

npm install @litejs/server

// server.mjs
import { App, Server } from "@litejs/server"

const app = App()

// Routes and middleware run in registration order
// Only middleware registered before the matching route runs
// Without a matching route, no middleware runs
app.use((req, env) => {
    // Return a truthy response to stop further execution
})

// Write route paths without leading or trailing `/`
// Only the first matching route is executed
app.get("hello/world", (req, env) => "Hello MOON!")
app.get("hello/{name}", (req, env) => "Hello " + req.param.name)
app.get("bye/{name}", (req, env) => "Bye " + req.param.name)
app.get("bye/moon", (req, env) => { /* Never executed because the previous handler matches */ })
app.get("teapot", (req) => (req.resStatus = 418, "no coffee"))
app.get("notFound", () => 404) // Return a number to send a status code

// Middleware does not accept a path; add it to a sub-app to scope it to the mount prefix.
// Mount the sub-app under a prefix written without leading or trailing `/`.
const subApp = App()
.use(auth)
.post("", (req, env) => {
    // POST /api -> req.path == "/" and req.fullPath == "/api"
    return { data: [] }
})
.post("echo", async (req, env) => {
    // POST /api/echo -> req.path == "/echo" and req.fullPath == "/api/echo"
    return await req.json()
})

app.mount("api", subApp)

// A common entry point that handles runtime differences.
// On Cloudflare and Vercel, it returns `{ fetch }`; on Netlify, the handler itself;
// on Node.js, Bun, Deno, and txiki.js, it starts the server.
export default Server(app)

Handlers receive (req, env, ctx) and may return a native Response, a number (status only), an object or array (serialized to JSON), or any value accepted as the body of a new Response.

Set the status with req.resStatus = 409 and add headers with req.resHeaders.allow = "GET, PUT". Thrown errors map to err.code || 500; 5xx bodies are kept generic.

Requests include param, path, fullPath, query, searchParams, and header(name). Routes match against path, the raw, percent-encoded pathname; fullPath and param values are decoded.

Routes

  • user/{username} matches one path segment (no /)
  • post/{id+} matches one or more digits
  • files/{rest*}.ext greedily matches all characters
  • a/{dir/}{name} matches zero or more slash-terminated directories
  • pub/\{x} matches the literal path pub/{x}

Runtime environments

More complex setups require manually configured environments. For example, env.KV is provided natively on Cloudflare but must be configured for local runtimes.

Runtime-specific environments can be selected in several ways. One option is to use a separate entry file for each runtime. Another is to use conditional imports in package.json, allowing runtimes to share an entry point:

{
  "imports": {
    "#env": {
      "workerd": "./env/workerd.mjs",
      "default": "./env/local.mjs"
    }
  }
}

Configure ASSETS and KV bindings in wrangler.jsonc for Cloudflare. On local runtimes, serveStatic provides ASSETS, while a SQLite-backed shim provides KV.

// env/workerd.mjs
export { env } from "cloudflare:workers"
// env/local.mjs
import { DB, KV, serveStatic } from "@litejs/server"
var db = new DB(":memory:")
, env = {
	ASSETS: serveStatic("public"),
	KV: KV(db, "kv"),
}
export { env }

The same server entry point runs on Cloudflare, Bun, Deno, Node.js, and txiki.js:

// server.mjs
import { Server } from "@litejs/server"
import { env } from "#env"
import { app } from "./app.mjs"

export default Server(app, env)

Runnable examples are in demo/ and test/server/.

Copyright (c) 2026 Lauri Rooden <lauri@rooden.ee>
MIT License | GitHub repo | npm package | Buy Me A Tea

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages