tamsi
v0.0.8
Published
Lightweight micro-engine for explicit h3-based servers.
Downloads
174
Readme
Tamsi
Lightweight micro-engine for explicit h3-based servers.
Table of Contents
Installation
Use your favorite package manager npm, pnpm and etc.
pnpm add tamsiCLI
Tamsi ships with a CLI for dev, build, and production start.
Common usage
tamsi init my-api --template minimal
tamsi init my-api --template minimal --kysely --betterAuth
tamsi dev --env .env.local
tamsi build --outDir dist
tamsi start --outDir distCommands
init
Create a new project from a template.
tamsi init my-api --template standardFlags:
--template minimal|standard(defaultminimal)--kyselyadd Kysely setup (defaults to sqlite)--betterAuthadd Better Auth (email/password) and Kysely--db sqlite|postgresdatabase driver for Kysely--forceoverwrite if directory is not empty--cwd <path>base directory to create the project in
dev
Start in development mode with file watching.
tamsi dev --port 5555 --host 0.0.0.0Flags:
--config <path>path to config file--env <path>path to env file (replaces default.env)--port <number>port to listen on--host <string>host to bind--quietreduce output to only the URL--health <path>override health endpoint path--no-healthdisable health endpoint
build
Build a production bundle to dist/ (or --outDir).
tamsi build --outDir dist --minify --sourcemap=externalFlags:
--config <path>path to config file--outDir <path>output directory (defaultdist)--cleanremove output directory before build--minifyminify build output--sourcemap true|false|inline|external(defaultfalse)--target node18|node20|node22|node24(defaultnode18)--env <path>path to env file (replaces default.env)
start
Start from a production build.
tamsi start --outDir dist --env .env.productionFlags:
--outDir <path>build output directory (defaultdist)--env <path>path to env file (replaces default.env)--port <number>port to listen on--host <string>host to bind--quietreduce output to only the URL--health <path>override health endpoint path--no-healthdisable health endpoint
config
Print resolved config (redacted by default).
tamsi config --env .env.production --showSourcesFlags:
--config <path>path to config file--env <path>path to env file (replaces default.env)--rawprint full values without redaction--showSourcesinclude config source metadata
Features
tamsi.config.ts
import { defineTamsiConfig } from "tamsi";
import { defineEventHandler } from "h3";
const hello = defineEventHandler(() => ({ ok: true }));
export default defineTamsiConfig({
host: "localhost",
port: 5555,
routesBasePath: "/api",
routes: [
{
method: "GET",
path: "/hello",
handler: hello,
middleware: [defineEventHandler(() => console.log("Middleware before '/' endpoint."))]
}
],
serveStatic: {
publicDir: "public",
publicPath: "/public",
},
health: { enabled: true, path: "/health" },
shutdownTimeoutMs: 10000,
onBeforeClose() {
console.log("Tamsi is landing...");
}
});Config reference
host: string(default0.0.0.0) Host to listen on when runningtamsi devortamsi start.port: number(default3000) Port to listen on when runningtamsi devortamsi start.routes: TamsiRoute[](default[]) Explicit routes with{ method, path, handler, middleware? }.routesBasePath: string(default"") Prefix added to all routes (e.g."/api").middlewares: TamsiMiddleware[](default[]) Global middleware applied to all requests.serveStatic.publicDir: string | false(defaultfalse) Directory of static assets to serve. Disabled whenfalseor unset.serveStatic.publicPath: string(default"/public") URL prefix for static assets.health: { enabled?: boolean; path?: string }(default enabled, path"/health") Built-in health endpoint.shutdownTimeoutMs: number(default10000) Time limit for graceful shutdown hooks.onBeforeClose: () => void | Promise<void>Hook called before the server closes.
Notes
- Relative paths like
publicDirresolve from the directory containingtamsi.config.ts. - Health is enabled by default; disable with
health: { enabled: false }.
TamsiRoute type
import type { EventHandler, Middleware, HTTPMethod } from "h3";
type TamsiRoute = {
method?: "ALL" | HTTPMethod | Lowercase<HTTPMethod>;
path: string;
handler: EventHandler;
middlewares?: Middleware[];
};Config patterns
// API-only
export default defineTamsiConfig({
routesBasePath: "/api",
routes: [{ method: "GET", path: "/ping", handler: ping }],
health: { enabled: true }
});
// Static-only
export default defineTamsiConfig({
serveStatic: {
publicDir: "public",
publicPath: "/public",
},
health: { enabled: false }
});Shutdown hooks
Use onBeforeClose to run cleanup logic during a graceful shutdown. The CLI
waits for this hook before closing the listener, with a timeout guard.
import { defineTamsiConfig } from "tamsi";
export default defineTamsiConfig({
shutdownTimeoutMs: 10000,
async onBeforeClose() {
console.log("Tamsi is landing...");
// close DB connections, flush queues, etc.
}
});shutdownTimeoutMsdefaults to 10000 if not set.onBeforeCloseruns for bothtamsi devandtamsi start.
Routing helpers
Use defineTamsiRouter to group routes under a base path and shared middlewares.
import { defineTamsiConfig, defineTamsiRouter } from "tamsi";
import { defineEventHandler } from "h3";
const routes = defineTamsiRouter({
basePath: "/api",
routes: [
{
method: "GET",
path: "/ping",
handler: defineEventHandler(() => ({ ok: true }))
}
]
});
export default defineTamsiConfig({ routes });You can also set a global prefix with routesBasePath.
Static files (optional)
Static serving is disabled by default. Enable it by setting serveStatic.publicDir.
import { defineTamsiConfig } from "tamsi";
export default defineTamsiConfig({
serveStatic: {
publicDir: "public",
publicPath: "/public"
}
});Static assets pipeline
- Tamsi does not minify public assets.
- Build/minify assets into
public/with your own tooling. tamsi buildcopiespublic/intodist/public/.
Examples
examples/basic/README.mdexamples/static/README.mdexamples/router/README.md
Scaffolding
Create a new project:
tamsi init my-api --template minimal
tamsi init my-api --template minimal --kysely --betterAuthTemplates:
minimalstandard
Notes:
- Templates use
"tamsi": "workspace:*"while developing locally to avoid the npm name collision. - For local workspace installs, set
node-linker=isolatedin.npmrcso each app gets anode_modules/.bin.
Build & start
Build a project into dist/:
tamsi build --outDir distAsset pipeline example:
pnpm run assets:buildtamsi build --outDir dist
See the CLI section above for full build flags.
Start from the compiled output:
NODE_ENV=production tamsi start --outDir distNotes:
tamsi startrequiresdist/server.mjs.- Use
--cleanwithtamsi buildto remove the output directory before building.
See the CLI section above for full start flags.
Config introspection
Print resolved config (redacted by default):
tamsi config --env .env.production --showSourcesUse --raw to print full values.
