A lightweight, high-performance web framework for Bun
Karpon is a lightweight, high-performance web framework for Bun with an Express-like API. Built from the ground up for Bun's runtime, Karpon offers zero-cost abstractions and a plugin-style hooks system for maximum flexibility and performance.
- π High Performance - Optimized for Bun runtime with minimal overhead
- πͺ Hook-based Middleware - Pre-hooks, response hooks, and error hooks for flexible request processing
- π Built-in Security - Helmet integration for security headers out of the box
- π‘οΈ Rate Limiting - Built-in rate limiter with Redis support for production workloads
- π CORS Support - Easy cross-origin resource sharing configuration
- π Static File Serving - Serve static assets with built-in security
- π Body Parsing - Automatic JSON, form, and text body parsing
- π TypeScript First - Full TypeScript support with type definitions
- π― Express-like API - Familiar API design for easy migration
# Using Bun (recommended)
bun add karpon
# Using npm
npm install karpon
# Using yarn
yarn add karponimport { Karpon } from "karpon";
const app = new Karpon();
// Define routes
app.get("/", (req, res) => {
res.json({ message: "Hello, Karpon!" });
});
app.get("/users/:id", (req, res) => {
const { id } = req.params;
res.json({ userId: id, message: `User ${id} found` });
});
app.post("/users", (req, res) => {
const { name, email } = req.payload;
res.status(201).json({ name, email, id: Math.random() });
});
// Add middleware
app.useCors({
origin: ["http://localhost:3000"],
credentials: true,
});
app.useSecurityHeaders({
hidePoweredBy: true,
noSniff: true,
xssFilter: true,
});
app.useRateLimiter({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
});
// Serve static files
app.serveStatic({
path: "/static",
dir: "./public",
});
// Start server
app.listen(3000, () => {
console.log("π Karpon server running on http://localhost:3000");
});The main application class that provides the Express-like API.
| Method | Description | Example |
|---|---|---|
get(path, handler) |
Define GET route | app.get("/", handler) |
post(path, handler) |
Define POST route | app.post("/users", handler) |
put(path, handler) |
Define PUT route | app.put("/users/:id", handler) |
patch(path, handler) |
Define PATCH route | app.patch("/users/:id", handler) |
delete(path, handler) |
Define DELETE route | app.delete("/users/:id", handler) |
head(path, handler) |
Define HEAD route | app.head("/health", handler) |
options(path, handler) |
Define OPTIONS route | app.options("/api", handler) |
| Method | Description | Example |
|---|---|---|
onRequest(handler, paths?, methods?) |
Add pre-hook middleware | app.onRequest(authMiddleware) |
onSend(handler, paths?, methods?) |
Add response hook | app.onSend(logResponse) |
onError(handler, paths?, methods?) |
Add error hook | app.onError(errorHandler) |
useCors(options?) |
Enable CORS with options | app.useCors({ origin: "*" }) |
useBodyParser(options?) |
Enable body parsing | app.useBodyParser() |
useRateLimiter(options?) |
Enable rate limiting | app.useRateLimiter({ max: 100 }) |
useSecurityHeaders(options?) |
Add security headers | app.useSecurityHeaders() |
| Method | Description | Parameters |
|---|---|---|
router(Router, path?) |
Add router group | Router: Router class, path?: prefix path |
serveStatic(config) |
Serve static files | config: { path, dir } |
listen(port, callback?) |
Start the server | port: number/string, callback?: function |
Response builder with method chaining for fluent API.
| Method | Description | Returns |
|---|---|---|
status(code) |
Set HTTP status code | KarponResponse |
send(data) |
Set response body | KarponResponse |
json(data) |
Send JSON response | KarponResponse |
text(data) |
Send text response | KarponResponse |
header(key, value) |
Set response header | KarponResponse |
Run before route handlers. Can modify request or return early response.
type KarponPreHook = {
handler: (
req: KarponRequest,
res: KarponResponse,
server: Server
) =>
| KarponResponse
| Promise<KarponResponse>
| void
| Promise<void>
| KarponRequest
| Promise<KarponRequest>
| Promise<KarponResponse | KarponRequest>;
paths?: string[];
methods?: RouteMethod[];
};Run after route handlers. Can modify response before sending.
type KarponResponseHook = {
handler: (
req: KarponRequest,
res: KarponResponse,
server: Server
) =>
| KarponResponse
| Promise<KarponResponse>
| void
| Promise<void>
| Promise<KarponResponse | void>;
paths?: string[];
methods?: RouteMethod[];
};Handle errors thrown during request processing.
type KarponErrorHook = {
handler: (
req: KarponRequest,
res: KarponResponse,
error: any,
server: Server
) => KarponResponse | Promise<KarponResponse> | void | Promise<void>;
paths?: string[];
methods?: RouteMethod[];
};interface RateLimiterOptions {
windowMs?: number; // Time window in milliseconds (default: 15 * 60 * 1000)
max?: number; // Max requests per window (default: 100)
message?: string; // Error message (default: "Too many requests...")
redisUrl?: string; // Redis URL for distributed rate limiting
}interface HelmetOptions {
hidePoweredBy?: boolean; // Hide X-Powered-By header
noSniff?: boolean; // Set X-Content-Type-Options
xssFilter?: boolean; // Set X-XSS-Protection
frameGuard?: { action: "deny" | "sameorigin" }; // X-Frame-Options
hsts?: { maxAge: number; includeSubDomains?: boolean }; // HSTS
referrerPolicy?: string; // Referrer-Policy
contentSecurityPolicy?: Record<string, string[]>; // CSP
}interface GenerateCorsHookOptions {
origin?: string[] | string; // Allowed origins
methods?: RouteMethod[]; // Allowed methods
credentials?: boolean; // Allow credentials
}import { Karpon } from "karpon";
const app = new Karpon();
// Middleware setup
app.useCors({
origin: ["http://localhost:3000", "https://myapp.com"],
credentials: true,
});
app.useSecurityHeaders();
app.useRateLimiter({ max: 1000 });
// API Routes
app.get("/api/health", (_req, res) => {
res.json({ status: "OK", timestamp: new Date().toISOString() });
});
app.get("/api/users", async (_req, res) => {
// Simulate database query
const users = [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Smith" },
];
res.json(users);
});
app.post("/api/users", async (req, res) => {
const { name, email } = req.payload;
if (!name || !email) {
return res.status(400).json({ error: "Name and email required" });
}
// Simulate user creation
const newUser = { id: Date.now(), name, email };
res.status(201).json(newUser);
});
app.listen(3000);// Authentication middleware
const authMiddleware: KarponPreHook["handler"] = async (req, res) => {
const token = req.headers.get("authorization");
if (!token) {
return res.status(401).json({ error: "No token provided" });
}
// Verify token (simplified)
if (token !== "valid-token") {
return res.status(403).json({ error: "Invalid token" });
}
// Add user info to request
(req as any).user = { id: 1, name: "John Doe" };
};app.onError(async (req, res, error) => {
console.error("Unhandled error:", error);
if (error.message.includes("ValidationError")) {
return res.status(400).json({ error: "Invalid input data" });
}
return res.status(500).json({ error: "Internal server error" });
});Karpon follows a zero-cost abstractions philosophy with these key components:
- Route Builder: Compiles routes into optimized Bun route objects
- Hooks Manager: Manages middleware with signature-based optimization
- Response Builder: Fluent API for building HTTP responses
- Plugin System: Easy integration of additional features
The framework is designed for maximum performance on Bun's runtime while maintaining a familiar Express-like developer experience.
MIT Β© Abdullah Ahmed
For more examples and advanced usage, check out the API documentation and examples folder.
