npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@akuseru_w/kura

v0.1.14

Published

A Bun-native TypeScript web framework.

Readme

Kura

Kura is a Bun-native TypeScript web framework for building HTTP applications with a conventional project structure, typed primitives, and a first-party CLI.

It gives you the foundation of a full-stack framework without hiding the Bun runtime: routing, middleware, configuration, validation, console commands, testing tools, cache, queue, auth primitives, and database building blocks.

Requirements

  • Bun 1.3 or newer
  • TypeScript 5 when type-checking applications

License

Kura is open source software licensed under the MIT license.

Create An Application

Create a new project with the application starter.

bun create kura-app my-app
cd my-app
bun install
bun run dev

The development server starts on http://localhost:3333.

You can also scaffold without prompts.

bun create kura-app my-api -- --yes --preset=api

Available starter choices include:

  • preset: api, web, or full
  • architecture: standard, modular, or domain
  • database: none, sqlite, postgres, or mysql
  • auth: none, session, or access-token
  • cache: memory, file, or redis
  • queue: none, memory, sqlite, or redis
  • module: mail, storage, i18n, or websockets

Application Code

Generated applications install the framework runtime under the local kura alias, while the published package remains @akuseru_w/kura on npm.

import type { Context } from "kura/http";
import { view } from "kura/view";

export class HomeController {
	async index(_ctx: Context): Promise<Response> {
		return view("home", {
			preset: "web",
		});
	}
}

Routes are usually declared in start/routes.ts and point to controllers.

import { Router } from "kura/http";
import { HomeController } from "#controllers/home_controller";

export const router = new Router();

const homeController = new HomeController();

router.get("/", (ctx) => homeController.index(ctx)).as("home");
router.get("/health", () => Response.json({ status: "up" })).as("health");

Kura keeps the root import stable for compatibility and recommends domain entrypoints for smaller, clearer imports.

import { Router } from "kura/http";
import { BaseModel, column } from "kura/database";
import { k } from "kura/validation";
import { SQLiteQueueDriver } from "kura/queue/sqlite";

Request Context

Route handlers receive a typed context. ctx.request stays the native Request, and Kura adds small helpers for the data apps read most often.

router.get("/users/:id", (ctx) => {
	ctx.setState("startedAt", Date.now());

	return Response.json({
		id: ctx.param("id"),
		tab: ctx.query("tab", "overview"),
		tags: ctx.queries("tag"),
		tenant: ctx.header("x-tenant"),
		session: ctx.cookie("session"),
		startedAt: ctx.getState<number>("startedAt"),
	});
});
  • ctx.param() returns all route params, and ctx.param("id") returns string | null.
  • ctx.query() preserves repeated query values as arrays, while ctx.query("page") returns the first value.
  • ctx.queries("tag") always returns string[].
  • ctx.header() and ctx.cookie() read request headers and cookies with predictable null or default-value fallbacks.
  • ctx.bodyValue(), ctx.validatedData(), ctx.validatedParams(), ctx.validatedQuery(), and ctx.validatedBody() expose parsed and validated request input when middleware or route schemas populate it.
  • ctx.setState() and ctx.getState() store request-local values without touching globals.

API and full-stack starters expose OpenAPI docs from the route table.

import { Router } from "kura/http";
import { registerOpenApiRoutes } from "kura/openapi";
import { k } from "kura/validation";

export const router = new Router();

const userResponse = k.object({
	id: k.number(),
	email: k.string().email(),
});

router.get("/users/:id", (ctx) => Response.json({ id: ctx.params?.id })).openapi({
	tags: ["Users"],
	summary: "Get a user",
	responses: {
		200: userResponse,
	},
});

registerOpenApiRoutes(router, {
	title: "My API",
	version: "1.0.0",
	specVersion: "3.1.2",
	ui: "scalar",
});

The generated app serves /openapi.json and /docs. Set ui: "swagger" when you prefer Swagger UI. Kura defaults to OpenAPI 3.1.2; use specVersion: "3.2.0" when you need the latest OpenAPI spec.

Route schemas also validate requests before handlers run. Invalid input returns the standard 422 JSON error response, and handlers can read parsed values from the validated helpers.

const createUserRequest = k.object({
	email: k.string().email(),
	password: k.string().min(8),
});

router.post("/users", (ctx) => {
	const input = ctx.validatedBody<{ email: string; password: string }>();

	return Response.json({ email: input?.email });
}).schema({
	body: createUserRequest,
});

Response Helpers

Route handlers can always return a native Response. For common JSON responses, Kura also exposes KuraResponse.

import { KuraResponse } from "kura/http";

router.post("/users", async () => {
	return KuraResponse.created({ id: 1 });
});

router.get("/me", () => {
	return KuraResponse.unauthenticated();
});

Framework-generated JSON errors use a stable shape.

{
	"error": {
		"code": "E_UNAUTHENTICATED",
		"message": "Unauthenticated",
		"status": 401
	}
}

Helpers also cover noContent(), redirect(), download(), validation(), and problem() for application/problem+json responses.

Expected HTTP failures can be raised with first-party exceptions and rendered by the same pipeline used by Server, kura serve, and the test client.

import { NotFoundException } from "kura/http";

router.get("/users/:id", () => {
	throw new NotFoundException("User not found", {
		details: { resource: "users" },
	});
});

Use createHttpErrorHandler() when an app needs a custom renderer while keeping Kura's normalization for status codes and framework exceptions.

For web apps, views live in resources/views and use the .kura.html extension.

<h1>Kura</h1>
<p>{{ preset }} app</p>

Full-stack apps use Bun's native HTML routes for the browser entrypoint. The generated resources/pages/home.html imports TypeScript and CSS directly, and Kura continues to handle the API, middleware, controllers, and validation.

import home from "../resources/pages/home.html";
import { type BunStaticRouteMap } from "kura/http";

export const staticRoutes = {
	"/": home,
} satisfies BunStaticRouteMap;

Generated Structure

A new application uses the standard structure by default.

app/
  controllers/
bin/
  console.ts
  server.ts
  test.ts
config/
start/
  env.ts
  kernel.ts
  routes.ts
kura.config.ts
package.json
tsconfig.json
  • app/ contains application code.
  • bin/ contains executable entrypoints for the console, server, and tests.
  • config/ contains typed configuration files.
  • start/ contains boot files loaded during application startup.
  • kura.config.ts is the application manifest used by Kura tooling.
  • database/ is added when database or auth features need schema files.

For larger applications, choose the feature-based modular structure.

bun create kura-app my-app -- --architecture=modular
app/
  modules/
    api/
      api_controller.ts
    auth/
      auth_controller.ts
      user.ts
    web/
      home_controller.ts
config/
resources/
start/

For domain-heavy applications, choose the clean domain structure.

bun create kura-app my-app -- --architecture=domain
app/
  domains/
    auth/
      domain/
        user.ts
        user_repository.ts
      application/
        register_user.ts
      infrastructure/
        persistence/
          user_record.ts
          sql_user_repository.ts
      http/
        auth_controller.ts
config/
database/
start/

In the domain structure, domain entities stay framework-free. Database models and other adapters live under infrastructure/.

Console Commands

Generated applications expose a local Kura console.

bun kura
bun kura routes
bun kura doctor
bun kura env
bun kura config app.starter
bun kura make:controller Home
bun kura serve --watch

If the framework is installed globally, the kura binary delegates to the application console when it is run inside a generated project.

bun install -g @akuseru_w/kura
kura serve
kura routes

Common package scripts are also generated.

bun run dev
bun run build
bun run typecheck
bun run test

Framework Primitives

Kura currently includes:

  • Application lifecycle and service container
  • Configuration and environment loading
  • HTTP server, router, middleware pipeline, and controllers
  • Standard JSON response helpers and framework error responses
  • OpenAPI generation with Scalar or Swagger UI docs
  • .kura.html view rendering with escaped interpolation
  • Bun fullstack HTML route support for generated browser entrypoints
  • Body parsing, CORS, request IDs, request logging, and metrics helpers
  • Schema validation with type inference
  • Console kernel and generator commands
  • Cache manager with memory, file, and Redis drivers
  • Queue manager with memory driver and explicit SQLite or Redis driver entrypoints
  • Auth guards, access token guard, session guard, JWT guard, and policy helpers
  • Database manager, query builder, migrations, models, factories, and seeders
  • Test client and framework fakes

Example Validation

import { k } from "kura/validation";

const createUser = k.object({
	email: k.string().email(),
	name: k.string().min(2),
	birthdate: k.date(),
});

const payload = createUser.parse({
	email: "[email protected]",
	name: "Ada",
	birthdate: "1815-12-10",
});

Example Test

import { describe, expect, test } from "bun:test";
import { createTestClient } from "kura/testing";
import { router } from "#start/routes";

describe("home", () => {
	test("returns the home payload", async () => {
		const client = createTestClient(router);
		const response = await client.get("/");

		expect(response.status).toBe(200);
	});
});

Working On Kura

Clone the repository and install dependencies.

bun install

Build, test, and check the framework.

bun run build
bun test
bun run typecheck
bun run lint

Release

The npm packages are published by GitHub Actions when a semver tag is pushed.

git tag v0.1.7
git push origin v0.1.7

Before tagging, make sure package.json, packages/create-kura-app/package.json, and the @akuseru_w/kura dependency range inside create-kura-app all use the same version. The release workflow checks this before publishing.

Publishing uses npm trusted publishing, so both npm packages must allow the publish.yml GitHub Actions workflow as a trusted publisher:

  • @akuseru_w/kura
  • create-kura-app

Project Status

Kura is early-stage. The public API is taking shape around the generated application structure, the local kura import alias, and the Bun runtime. Expect fast iteration before a stable 1.0 release.