High-performance HTTP framework built for node/bun with context-aware request handling and zero boilerplate
npm install @minimajs/serverA modern, high-performance HTTP framework for Node.js and Bun - combining proven routing and lifecycle libraries with a clean, TypeScript-first API designed for today's runtimes.


- File-Based Modules with True Isolation: Create users/module.ts, it auto-loads as /users/\*. Each module is encapsulated.
- Dual Runtime Support: Native integration with both Bun and Node.js - no abstraction overhead
- 100% TypeScript: Built entirely in TypeScript for type safety and better DX
- Web Standards First: Uses native Web API
- Context-Aware: Access request data anywhere with AsyncLocalStorage - no more prop drilling
- Functional Approach: Clean, composable APIs embracing functional programming
- Zero Boilerplate: Get started with minimal setup and configuration
- ESM-Only: Modern ECMAScript Modules with full async/await support
- Powerful Plugin System: Extend functionality with encapsulated, reusable plugins
- Battle-Tested Core: Built on proven libraries (find-my-way, avvio, pino) with a modern API layer
For Bun:
``bash`
bun add @minimajs/server
For Node.js:
`bash`
npm install @minimajs/serveror
yarn add @minimajs/server
Organize your app by features - Minima.js automatically discovers modules.
Convention: Files must be named module.{ts,js,mjs}
``
src/
โโโ index.ts # Entry point
โโโ users/
โ โโโ module.ts # โ
Auto-discovered
โโโ posts/
โโโ module.ts # โ
Auto-discovered
`typescript [src/index.ts]
// src/index.ts
import { createApp } from "@minimajs/server/bun"; // or /node
const app = createApp(); // Discovers modules automatically!
await app.listen({ port: 3000 });
`
`typescript [src/users/module.ts]
// src/users/module.ts
import { params } from "@minimajs/server";
export default async function (app) {
app.get("/list", () => [{ id: 1, name: "John" }]);
app.get("/:id", () => {
const id = params.get("id");
return { id, name: "John" };
});
}
`
Your routes are automatically available:
- GET /users/listGET /users/:id
- GET /posts/list
-
`typescript
const app = createApp({
moduleDiscovery: {
root: "./modules", // Custom directory (default: entry file's directory)
index: "route", // Custom filename (default: 'module')
},
});
// Or disable auto-discovery
const app = createApp({
moduleDiscovery: false, // Manual registration only
});
`
Minima.js provides platform-specific imports that leverage native APIs for maximum performance:
`typescript
// Bun - uses Bun.serve()
import { createApp } from "@minimajs/server/bun";
// Node.js - uses http.createServer()
import { createApp } from "@minimajs/server/node";
// Default - node
import { createApp } from "@minimajs/server";
`
Access request data from anywhere without passing req/res objects:
`typescript
import { createApp } from "@minimajs/server/bun";
import { params, body, headers, request } from "@minimajs/server";
// Helper function that accesses context
function getCurrentUser() {
const token = headers.get("authorization");
return verifyToken(token);
}
app.get("/profile", () => {
// No need to pass context around!
const user = getCurrentUser();
return { user };
});
app.post("/users/:id", () => {
const id = params.get("id", Number); // With type conversion
const data = body
const req = request(); // Native Web API Request
return updateUser(id, data);
});
`
Available Context Functions:
- request() - Get native Web API Request objectresponse()
- - Access response objectparams()
- / params.get(key, parser?) - Route parametersbody
- - Parse request body with typesheaders
- - Access request/response headerssearchParams()
- - Query string parameterscontext()
- - Full context object
Organize your application by features, and let Minima.js discover modules automatically:
`typescript [src/index.ts]
// src/index.ts
import { createApp } from "@minimajs/server/bun";
const app = createApp(); // Auto-discovers from ./src
await app.listen({ port: 3000 });
`
`typescript [src/users/module.ts]
// src/users/module.ts
import { hook } from "@minimajs/server";
import { cors } from "@minimajs/server/plugins";
import { params } from "@minimajs/server";
// Module-scoped plugins via meta
export const meta = {
plugins: [cors({ origin: "*" }), hook("request", () => console.log("User request"))],
};
// Module routes
export default async function (app) {
app.get("/list", () => getUsers());
app.get("/:id", () => getUser(params.get("id")));
}
`
`typescript [src/admin/module.ts]
// src/admin/module.ts
import { hook } from "@minimajs/server";
// Different plugins - completely isolated from users module
export const meta = {
plugins: [hook("request", () => console.log("Admin request"))],
};
export default async function (app) {
app.get("/dashboard", () => getAdminData());
}
`
Routes are automatically created:
- GET /users/listGET /users/:id
- GET /admin/dashboard
-
Each module is completely isolated - plugins and hooks in one module don't affect others.
Control every stage of the request/response lifecycle:
Manage Resource Lifecycle with hook.lifespan:
`typescript
import { createApp, hook } from "@minimajs/server";
const app = createApp();
// Manage database connection lifecycle
app.register(
hook.lifespan(async () => {
// Runs when server starts
await db.connect();
console.log("Database connected");
// Return cleanup function that runs when server stops
return async () => {
await db.disconnect();
console.log("Database disconnected");
};
})
);
`
Request/Response Hooks:
`typescript
import { createApp, hook, abort } from "@minimajs/server";
const app = createApp();
// Request lifecycle hooks
app.register(
hook("request", ({ request, pathname }) => {
console.log(${request.method} ${pathname});
})
);
app.register(
hook("transform", (data, _ctx) => {
return { ...data, timestamp: Date.now() };
})
);
app.register(
hook("send", (response, _ctx) => {
// Called after response is sent - useful for logging and cleanup
console.log(Response sent with status: ${response.status});
})
);
app.register(
hook("error", (error, _ctx) => {
console.error("Request error:", error);
if (abort.is(error)) {
abort({ custom: error.message }, error.statusCode);
}
throw error;
})
);
`
Application lifecycle hooks:
`ts
app.register(
hook("ready", async () => {
console.log("Server is ready!");
})
);
app.register(
hook("close", async () => {
console.log("Server shutting down...");
})
);
`
Available Hooks:
- Request Lifecycle: request, transform, send, error, timeoutready
- Application Lifecycle: , listen, close, register
Create and share request-scoped data:
`typescript
import { createContext } from "@minimajs/server";
// Create a context for the current user
const [getUser, setUser] = createContext
// Middleware to set user
async function authMiddleware() {
const token = headers.get("authorization");
const user = await verifyToken(token);
setUser(user);
}
app.register(hook("request", authMiddleware));
// Access user in any route
app.get("/profile", () => {
const user = getUser();
if (!user) throw new UnauthorizedError();
return { user };
});
`
Minima.js uses native Web API Request/Response objects instead of Node.js-specific abstractions:
`typescript
app.get("/info", () => {
const req = request(); // Native Web API Request
return {
url: req.url,
method: req.method,
headers: Object.fromEntries(req.headers),
userAgent: req.headers.get("user-agent"),
};
});
`
Body parser is enabled by default and configured to parse JSON. You can override the configuration or disable it:
`typescript
import { bodyParser } from "@minimajs/server/plugins";
// Override configuration (supports multiple types)
app.register(
bodyParser({
type: ["json", "text", "form"],
clone: false,
})
);
// Or disable it entirely
app.register(bodyParser({ enabled: false }));
`
`typescript
import { routerLogger } from "@minimajs/server/plugins";
app.register(routerLogger());
`
`typescript
import { cors } from "@minimajs/server/plugins";
app.register(cors({ origin: "*", methods: ["GET", "POST"] }));
`
`typescript
import { shutdown } from "@minimajs/server/plugins";
app.register(shutdown());
`
Minima.js provides mock utilities for testing:
`typescript
import { createApp } from "@minimajs/server/node";
import { createRequest } from "@minimajs/server/mock";
const app = createApp();
app.get("/", () => "Hello World");
const response = await app.handle(new Request("http://localhost")); // returns Native Response
// or
const response = await app.handle(createRequest("/", { method: "GET" })); // returns Native Response
expect(await response.text()).toBe("Hello World");
`
For comprehensive documentation, guides, and examples, visit:
- Getting Started
- Core Concepts
- Routing Guide
- Hooks Guide
- Plugin Development
- Error Handling
- API Reference
Recommended project structure with automatic module discovery:
``
.
โโโ src/
โ โโโ index.ts # Entry point
โ โโโ module.ts # Optional root module (defines /api prefix for all)
โ โโโ users/
โ โ โโโ module.ts # Module entry (auto-loaded)
โ โ โโโ service.ts # Business logic
โ โ โโโ types.ts # Type definitions
โ โโโ posts/
โ โ โโโ module.ts
โ โ โโโ service.ts
โ โโโ auth/
โ โโโ module.ts
โ โโโ middleware.ts
โ โโโ context.ts
โโโ package.json
โโโ tsconfig.json
`typescript [src/index.ts]
// src/index.ts
import { createApp } from "@minimajs/server/bun";
const app = createApp(); // Auto-discovers modules from ./src
await app.listen({ port: 3000 });
`
`typescript [src/users/module.ts]
// src/users/module.ts
import type { App } from "@minimajs/server";
import { cors } from "@minimajs/server/plugins";
import { body } from "@minimajs/server";
// Register module-scoped plugins
export const meta = {
plugins: [cors({ origin: "https://example.com" })],
};
// Define routes
export default async function (app: App) {
app.get("/list", () => getUsers());
app.post("/create", () => createUser(body()));
}
`
Ensure your package.json has ESM enabled:
`json`
{
"name": "my-app",
"type": "module",
"scripts": {
"dev": "bun run src/index.ts",
"build": "bun build src/index.ts --outdir=dist"
}
}
Recommended tsconfig.json:
`json`
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"types": ["bun-types"]
}
}
`bash`Development
bun run src/index.ts
`bashInstall dependencies
npm install -D ebx
๐ค Related Packages
@minimajs/auth - Authentication and authorization
- @minimajs/schema - Data validation with Zod
- @minimajs/cookie - Cookie parsing and signing
- @minimajs/multipart` - File upload handlingMIT ยฉ Minima.js
Built on top of excellent libraries:
- avvio - Boot lifecycle management
- find-my-way - Fast HTTP router
- pino - High-performance logging
---
Made with โค๏ธ for the modern web
See the full documentation at minima-js.github.io
MIT