Skip to content

arisris/abret

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

20 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Abret Logo

Abret

npm version Bun License

Abret is a modern, lightweight, and type-safe web framework built specifically for Bun. It extends Bun.serve with a powerful routing system, composable middleware, and a built-in JSX rendering engine, all while maintaining minimal overhead.

✨ Features

  • πŸš€ Native Bun Integration: Built directly on top of Bun.serve for maximum performance.
  • πŸ›‘οΈ Type-Safe Routing: Strict TypeScript inference for route parameters and handlers.
  • πŸ”— Composable Middleware: Robust middleware system with createMiddleware and composeMiddlewares.
  • βš›οΈ JSX/TSX Support: Server-side rendering with familiar JSX syntax (no Virtual DOM).
  • 🧩 Unified Context: Component and Request context unified into a single API using AsyncLocalStorage.
  • 🧠 Smart HTML Generation: Automatic <head> management (titles, meta tags) and DOCTYPE handling.

⚑ Benchmarks

Abret's JSX engine is optimized for high-performance server-side rendering, avoiding the overhead of Virtual DOM.

  • Simple Render: ~800,000 ops/sec
  • Complex Component Tree: ~82,000 ops/sec
  • VNode Creation: ~2,200,000 ops/sec

Preliminary results on typical hardware. Significantly faster than standard React/Preact renderToString.

πŸ“¦ Installation

bun add abret

πŸš€ Quick Start

Create a simple server with routes and HTML rendering:

import { createRoute, mergeRoutes } from "abret";
import { html } from "abret/html";

const home = createRoute("/", () => {
  return html`
    <!DOCTYPE html>
    <html>
      <head>
        <title>My App</title>
      </head>
      <body>
        <h1>Welcome to Abret!</h1>
      </body>
    </html>
  `;
});

const api = createRoute("/api/hello", () =>
  Response.json({ message: "Hello World" }),
);

const routes = mergeRoutes(home, api);

Bun.serve({
  routes,
});

πŸ“– Key Concepts

Routing & Groups

Organize your routes using createRoute and createRouteGroup. Types for parameters are automatically inferred.

import { createRouteGroup, mergeRoutes } from "abret";

// Create a group with a prefix
const api = createRouteGroup("/api/v1");

const routes = mergeRoutes(
  api("/users", { GET: () => Response.json([]) }),
  api("/users/:id", (req) => {
    // strict type safety: req.params.id is string
    return Response.json({ id: req.params.id });
  }),
);

Bun.serve({ routes });

Middleware & Context

Create reusable middleware and share state across the request lifecycle using the unified Context API. Context is implicit and doesn't require passing req objects.

```ts
import { createRoute, createMiddleware, createContext, setContext, useContext } from "abret";

// Define a type-safe context key
const UserContext = createContext<{ name: string }>("user");

const authMiddleware = createMiddleware((req, server, next) => {
  const token = req.headers.get("Authorization");
  if (!token) return new Response("Unauthorized", { status: 401 });

  // Store user in context (implicit scope)
  setContext(UserContext, { name: "Alice" });
  return next();
});

// Apply middleware to a route
const dashboard = createRoute(
  "/dashboard",
  () => {
    // Safely retrieve context (no req needed)
    const user = useContext(UserContext, { required: true });
    return new Response(`Welcome ${user.name}`);
  },
  authMiddleware,
);

Components & JSX

Build UI with components and share state using Context, just like in React (but on the server).

To use JSX, configure your tsconfig.json:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "abret"
  }
}

Example component:

import { createRoute, createContext, useContext } from "abret";
import { html } from "abret/html";

const ThemeContext = createContext("light"); // Default value

function ThemeButton() {
  const theme = useContext(ThemeContext);
  return <button class={`btn-${theme}`}>Click me</button>;
}

const page = createRoute("/component", () => {
  return html(
    <ThemeContext.Provider value="dark">
      <ThemeButton />
    </ThemeContext.Provider>,
  );
});

πŸ› οΈ API Reference

Core (abret)

import {
  createRoute,
  createRouteGroup,
  mergeRoutes,
  createMiddleware,
  composeMiddlewares,
  createContext,
  useContext,
  setContext,
} from "abret";
  • createRoute(path, handler, ...middlewares) - Creates a route. Uses exact path matching.
  • mergeRoutes(...routes) - Combines multiple route objects.
  • createRouteGroup(prefix, middlewares) - Creates a route group.
  • createMiddleware(fn) - Helper for typed middleware.
  • composeMiddlewares(...middlewares) - Composes multiple middlewares.
  • Context utilities: createContext, useContext, setContext, runWithContext, runWithContextValue.

Context Store (abret/store)

import {
  createContext,
  useContext,
  setContext,
  hasContext,
  clearContext,
} from "abret/store";
  • createContext<T>(name, defaultValue?) - Creates a context key (and Provider if default given).
  • setContext(key, value) - Sets value in current scope.
  • useContext(key, options?) - Gets value (or default).
  • hasContext(key) - Checks if set.
  • clearContext(key) - Clears value.

HTML & JSX (abret/html)

import { html, HTMLResponse } from "abret/html";
  • html(string | jsx) - Creates an HTMLResponse.
  • HTMLResponse - Extended Response with .doctype() and metadata handling.
  • raw(string) - Creates safe unescaped HTML content.

πŸ“„ License

MIT

About

Modern, lightweight extends Bun.serve with a powerful routing system.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors