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

asijs

v1.5.0

Published

Bun-first web framework — fast, type-safe, simple

Downloads

679

Readme

AsiJS

CI npm version JSR License: MIT Tests


✨ Features

Core

  • 🚀 Blazing Fast — Trie + Radix tree router, route compilation, static router, schema cache LRU
  • 🎯 Type-safe — Full TypeScript with TypeBox validation, phantom types, type inference
  • 🔌 Pluggable — Rich plugin ecosystem with dependency ordering, lazy init, lifecycle hooks
  • 📦 Zero Config — Sensible defaults, works out of the box
  • 🖥️ Multi-runtime — Bun, Node.js (HTTP/HTTPS+WebSocket), Edge (Cloudflare, Deno, Vercel, Lambda@Edge)

Developer Experience

  • 🔥 Hot Reload 2.0fs.watch with 200ms debounce, module-level hot swap, HMR browser push via WebSocket
  • 💬 Interactive REPLasi repl: create routes on the fly, test requests, inspect state
  • 🌐 Web Playground — Browser-based IDE: code editor, output panel, request bar, 5 built-in examples
  • 🛠️ CLI v2asi create/dev/inspect/build/plugin/repl/generate/migrate/integrate/analyze/doctor/upgrade/db/template
  • 📊 Benchmark Dashboard — Chart.js dashboard with trend lines, CI pipeline

Resilience & Performance

  • Circuit Breaker — CLOSED/OPEN/HALF_OPEN with sliding window, timeout, fallback, healthcheck integration
  • 🔁 Request Deduplication — Inflight manager, XFetch cache stampede protection, MemoryCache/Redis
  • ❄️ Serverless Optimisation — Warm start emulation, lazy imports, bundle config for 6 platforms
  • 🗺️ Radix Tree Router — Up to 2× faster for 1M+ routes
  • 💾 Schema Cache LRU — Bounded memory for TypeBox compiled validators
  • ⚙️ Response Serialization (3.2)schema.response pre-compiles TypeBox → fast serializer (status-keyed {200, "2xx", default} + per-content-type serializers via Accept negotiation); e2e ×1.4 vs plain JSON

API & Documentation

  • 📄 OpenAPI / Swagger — Auto-generated OpenAPI 3.0/3.1, Swagger UI, security schemes
  • 🔄 Data Formatsapp.setFormat("yaml") + registerFormat(): JSON native, YAML lazy (bun add yaml), custom formats (TOML/INI/…); ctx.parseBody() parses by Content-Type, responses/errors/404 serialize in the default format with Accept-negotiation; TOON (token-optimized LLM format) via the toon-asijs package — registerToonFormat() + setFormat("toon") out of the box
  • 📖 API Docs Portal — Full documentation portal: sidebar search, code samples (curl/Python/JS/Go), try-it-out proxy, dark/light theme
  • 🔄 API Versioning — URL/Header/Combined strategies, fallback, deprecation headers (Sunset, Deprecation)
  • 📝 API Changelog — Snapshot/diff between API versions, Markdown/HTML export for CI/CD

WebSocket

  • 🔌 WebSocket — First-class app.ws() with typed data, lifecycle hooks
  • 📡 Pub-Sub — Rooms (ws.join(), ws.leave()), broadcast, presence tracking, typed events
  • 🔄 Redis Bridge — Cross-instance pub-sub via Redis for horizontal scaling
  • 💤 Graceful Shutdown — Drain active connections with 1001 close frames

Security

  • 🛡️ Built-in Security ModuleAsiConfig.security with zero-config sensible defaults:
    • autoEscape — Automatic XSS prevention in HTML responses
    • maxBodySize — Request body size limiting (configurable per unit)
    • autoNonce — CSP nonce generation for inline scripts
    • strictContentType — Content-Type enforcement with error/sanitize/off modes
    • OWASP Headers — CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy
  • 🔐 Security PresetsmaxSecurity, apiSecurity, devSecurity
  • 🔑 JWT — Sign/verify/decode, bearer auth middleware, CSRF protection
  • 🔒 Rate Limiting — Sliding window + token bucket, IP/API Key/User presets, per-tenant isolation

Static Site Generation

  • 📄 SSGasi build --ssg: scan GET routes, render HTML, pretty URLs (/about/index.html) or flat format
  • 📦 JSON Export--export-api for static API data
  • Edge-ready — SPA + Hybrid rendering with islands architecture

Observability

  • 📊 Metrics — Prometheus + OTLP exporters, request metrics collector, histograms
  • 🕵️ Tracing — W3C Trace Context, Server-Timing headers, request IDs, span events
  • 📋 Structured Logging — JSON log middleware for ELK/Datadog/Splunk, multi-level (debug/info/warn/error)
  • 🐛 Sentry — Fetch-based error tracking (no SDK required), breadcrumbs, envelopes
  • 🔬 OpenTelemetry — Full OTel instrumentation: spans, metrics, logs. W3C TraceContext propagation. Exporters: Console, OTLP, Jaeger, Zipkin

Ecosystem

  • 🤖 MCP Ready — Model Context Protocol server for AI/LLM integration (7 built-in tools, 4 resources)
  • 📦 Plugin Registryasi plugin search/install/create/list. 40+ curated plugins in 8 categories
  • 🧩 asijs-next — Next.js App Router, Pages Router, Edge Runtime adapter
  • 🧩 asijs-astro — Astro server endpoints, method-specific endpoints, middleware
  • 🧩 asijs-remix — Remix resource routes, loaders, actions
  • 🧩 asijs-sveltekit — SvelteKit handle hook, server handler, universal handler
  • 🧩 asijs-opentelemetry — OpenTelemetry automatic instrumentation
  • 📋 ESLint Plugineslint-plugin-asijs with 4 rules: no-duplicate-route, no-missing-handler, validate-schema, no-unused-route
  • 🎨 VS Code Extension — Snippets, route explorer, hover provider, debug config, template explorer, create wizard
  • 🦀 Native / Polyglot Modulesasi native scaffold <lang> + ctx.native — write functions in Rust/Go/C/C++/Zig/Nim/Haskell (via bun:ffi), Python/Ruby/PHP (sidecar via Bun.spawn + JSON-RPC) or Lua (embedded interpreter via dlopen liblua — no compilation, no IPC); AsiJS generates stubs and typed wrappers — zero manual glue, no WASM. Zig requires 0.15–0.17; older versions will not work

Migration

  • 🔄 Express → AsiJSexpressPlugin.wrap(mw), codemod with 22 rules, CLI: asi integrate ./app.js
  • 🔄 Koa → AsiJSkoaPlugin.wrap(mw), codemod with 22 rules
  • 🔄 Elysia/Hono/Fastify → AsiJSasi migrate with automatic transformation

📦 Installation

Bun:

bun add asijs

npm:

npm install asijs

JSR:

bunx jsr add @baconana/asijs

Node.js Adapter

For Node.js HTTP(S) + WebSocket support:

bun add asijs  # same package, use asijs/node
import { Asi } from "asijs";
import { nodeAdapter } from "asijs/node";

const app = new Asi({ serverAdapter: nodeAdapter() });
app.listen(3000);

🚀 Quick Start

import { Asi } from "asijs";

const app = new Asi();

// Simple route
app.get("/", () => "Hello, AsiJS! 👋");

// With validation
app.post("/users", async (ctx) => {
  const body = await ctx.parseBody();
  return { id: 1, ...body };
}, {
  schema: {
    body: Type.Object({
      name: Type.String({ minLength: 1 }),
      email: Type.String({ format: "email" }),
    }),
  },
});

// Start server
app.listen(3000);

🛠️ CLI

# Create a new project
bunx asijs create my-app

# Development server (with hot reload)
bunx asijs dev

# Inspect routes/plugins/size
bunx asijs inspect --routes --verbose
bunx asijs inspect --plugins
bunx asijs inspect --size

# Build for production
bunx asijs build                  # SPA/SSR build
bunx asijs build --ssg            # Static site generation
bunx asijs build --target cloudflare  # Serverless build

# Interactive REPL
bunx asijs repl

# Plugin management
bunx asijs plugin search auth
bunx asijs plugin install cors
bunx asijs plugin create my-plugin
bunx asijs plugin list

# Migrate from other frameworks
bunx asijs integrate ./app.js

# Generate scaffold
bunx asijs generate route users
bunx asijs generate plugin auth

# CLI v2 — Smarter Developer Tools
bunx asijs analyze              # Static analysis: dead routes, validation, bottlenecks
bunx asijs analyze --info --json
bunx asijs doctor               # Project diagnostics: config, deps, strict, security
bunx asijs upgrade --dry-run    # Check for AsiJS updates
bunx asijs upgrade --codemod    # Update + breaking-changes codemod
bunx asijs template api         # Install template into current dir
bunx asijs dev --inspect        # Dev + DevTools hint (dashboard, REPL, analyze)

Templates

| Template | Description | |----------|-------------| | minimal | Basic setup with routing | | api | REST API with validation, CORS, OpenAPI | | fullstack | API + JSX rendering | | auth | JWT authentication + protected routes | | realtime | WebSocket chat | | workspace | Monorepo with multiple sub-apps |

📚 Examples

REST API with Validation

import { Asi, Type } from "asijs";

const app = new Asi();
const users: { id: number; name: string; email: string }[] = [];

app.get("/users", () => users);

app.get("/users/:id", (ctx) => {
  const user = users.find(u => u.id === +ctx.params.id);
  if (!user) return ctx.status(404).jsonResponse({ error: "Not found" });
  return user;
}, {
  params: Type.Object({ id: Type.String() }),
});

app.post("/users", async (ctx) => {
  const body = await ctx.body<{ name: string; email: string }>();
  const user = { id: users.length + 1, ...body };
  users.push(user);
  return ctx.status(201).jsonResponse(user);
}, {
  schema: {
    body: Type.Object({
      name: Type.String({ minLength: 1 }),
      email: Type.String({ format: "email" }),
    }),
  },
});

app.listen(3000);

Circuit Breaker

import { Asi, circuitBreaker, apiCircuitBreaker } from "asijs";

const app = new Asi();

// Global: protect against external API failures (middleware, not a plugin)
app.use(circuitBreaker({
  threshold: 5,           // 5 failures → OPEN
  window: 30000,          // 30 second sliding window
  recoveryTimeout: 10000, // 10s recovery
  fallback: () => ({ cached: true, data: [] }),
}));

// Per-route with presets — apiCircuitBreaker(name) takes a breaker name
app.get("/api/external", apiCircuitBreaker("stripe-api"), async (ctx) => {
  const data = await ctx.circuitBreaker!("stripe-api", () =>
    fetch("https://api.stripe.com/v1/charges")
  );
  return data;
});

app.listen(3000);

WebSocket Pub-Sub

import { Asi, createRoomManager } from "asijs";

const app = new Asi();
const rooms = createRoomManager({ maxRoomsPerConnection: 10 });

// Create a chat room
app.ws("/chat", {
  open(ws) {
    ws.data = { joinedAt: Date.now() };
    ws.join("lobby");
  },
  message(ws, message) {
    const msg = typeof message === "string" ? message : JSON.stringify(message);
    rooms.broadcast(msg, { rooms: ["lobby"] });
  },
  close(ws) {
    rooms.cleanup(ws);
  },
}, { roomManager: rooms });

app.listen(3000);

SSG — Static Site Generation

import { Asi, buildSSG, staticPath } from "asijs";

const app = new Asi();

app.get("/", () => "<h1>Home</h1>");
app.get("/about", () => "<h1>About</h1>");

// Dynamic routes: define static paths
const paths = [
  staticPath("/blog/:slug", { slug: "hello-world" }),
  staticPath("/blog/:slug", { slug: "second-post" }),
];

// CLI: bunx asijs build --ssg
// Or programmatically:
const result = await buildSSG(app, {
  staticPaths: paths,
  outDir: "./dist",
  format: "pretty",  // /about → about/index.html
});
// result: { totalPages: 4, successPages: 4, failedPages: 0, durationMs: 12 }

API Versioning

import { Asi, apiVersion, versionPath } from "asijs";

const app = new Asi();

app.use(apiVersion({
  defaultVersion: "2.0",
  supportedVersions: ["1.0", "2.0"],
  strategy: "url",       // URL-based: /v1/users, /v2/users
  fallback: "latest",    // Unsupported version → latest
  deprecationHeaders: true, // Add Sunset/Deprecation headers
}));

// v1 users endpoint
app.get(versionPath("/users", "1.0"), () =>
  users.map(u => ({ id: u.id, name: u.name }))
);

// v2 users endpoint (richer response)
app.get(versionPath("/users", "2.0"), () => users);

app.listen(3000);

Built-in Security

import { Asi } from "asijs";

// Zero-config: OWASP headers, XSS escape, body limits, CSP nonce
const app = new Asi({
  security: {
    autoEscape: true,
    maxBodySize: "1mb",
    strictContentType: "sanitize",
    headers: {
      contentSecurityPolicy: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'"],
      },
      hsts: { maxAge: 31536000, includeSubDomains: true },
      xFrameOptions: "DENY",
    },
  },
});

// Presets — plain SecurityConfig objects, merged into AsiConfig.security
import { maxSecurity, apiSecurityCore, devSecurity } from "asijs";

const strictApp = new Asi({ security: maxSecurity });
// Or merge with your own overrides:
// const app = new Asi({ security: { ...apiSecurityCore, maxBodySize: "2mb" } });

app.listen(3000);

Serverless / Edge

import { Asi, serverless } from "asijs";

const app = new Asi();

// Warm start emulation
await serverless.warmUp(app);

// Routes...
app.get("/api/hello", () => ({ message: "Hello from edge!" }));

// Build for target
// CLI: bunx asijs build --target cloudflare
// CLI: bunx asijs build --target lambda-edge
// CLI: bunx asijs build --target vercel-edge

Framework Adapter — Next.js

// app/api/[[...asi]]/route.ts
import { createNextHandler } from "asijs-next";
import { Asi } from "asijs";

const app = new Asi();
app.get("/api/hello", () => ({ message: "Hello from AsiJS in Next.js!" }));

export const { GET, POST, PUT, DELETE } = createNextHandler(app);

🔌 Plugins

Built-in Plugins

| Plugin | Description | Since | |--------|-------------|-------| | cors() | Cross-Origin Resource Sharing (advanced: dynamic origin, wildcard, PNA) | v1.0 | | staticFiles() | Static file serving with ETag, cache, range requests | v1.0 | | openapi() | OpenAPI/Swagger documentation | v1.0 | | rateLimit() | Rate limiting with sliding window + token bucket | v1.0 | | security() | Security headers (CSP, HSTS, XFO, etc.) | v1.0 | | cache() | Response caching with ETags | v1.0 | | trace() | Request tracing & metrics | v1.0 | | lifecycle() | Graceful shutdown with drain | v1.0 | | devMode() | Development tools (chaos, delay, debug) | v1.0 | | mcp() | Model Context Protocol for AI/LLM | v1.0 | | sessions() | Session middleware (Memory, Cookie, Redis stores) | v1.2 | | requestLogger() | Coloured request logging (4 formats) | v1.2 | | compression() | gzip/brotli response compression | v1.2 | | negotiateResponse() | Content negotiation helper (JSON/HTML/XML) | v1.2 | | healthCheck() | /health, /ready, /live endpoints | v1.2 | | sse() | Server-Sent Events | v1.2 | | graphql() | GraphQL (Yoga/Helix adapter) | v1.2 | | sentry() | Sentry error tracking | v1.2 | | structuredLogger() | JSON structured logging | v1.2 | | circuitBreaker() | Circuit breaker with 3 states, presets | v1.3 | | deduplicate() | Request dedup + cache stampede protection | v1.3 | | playgroundPlugin() | Browser-based IDE with code editor | v1.3 | | apiDocsPlugin() | Full API documentation portal | v1.3 | | apiVersion() | API versioning (URL/Header/Combined) | v1.3 | | authjs() | Auth.js integration (GitHub, Google, Credentials) | v1.3 | | upload() | File upload (Local, S3, R2) — streaming: true for memory-efficient large files | v1.3 | | autoAPI() | PostgREST-like auto CRUD from database | v1.3 | | expressPlugin() / koaPlugin() | Express/Koa middleware wrapper | v1.3 | | otelLogs() | OpenTelemetry instrumentation (spans, metrics, logs) | v1.3 | | webhooks() | Stripe/GitHub/Svix signature verification | v1.2 | | trustProxy() | Real IP extraction from X-Forwarded-For | v1.2 | | domainRouting() | Subdomain-based routing | v1.2 | | serverPush() | Link preload headers | v1.2 | | native() | Native modules — Rust/Go/C/C++/Zig/Nim/Haskell via bun:ffi, Python/Ruby/PHP via sidecar, Lua via dlopen → ctx.native.* | v1.5 |

Core API (v1.5)

| API | Description | |-----|-------------| | app.setFormat("yaml" / DataFormat) + format option | Default response format: objects, errors & 404 serialize in it; ctx.parseBody() parses by Content-Type | | registerFormat() / listFormats() | Data formats layer — JSON native, YAML lazy, TOON via toon-asijs, custom formats in 3 lines | | schema.response + serializers | JSON Schema response serialization: status-keyed {200, "2xx", default} + per-content-type with Accept negotiation |

Plugin Ordering & Dependencies

import { createPlugin } from "asijs";

// Plugins can declare dependencies
const authPlugin = createPlugin({
  name: "auth",
  dependencies: ["sessions", "cors"],
  setup(app) {
    app.onBeforeHandle(async (ctx) => {
      ctx.user = await authenticate(ctx);
    });
  },
});

app.plugin(authPlugin());  // Auto-ordered: sessions → cors → auth
app.pluginInfo();           // Visualize dependency graph

📦 Ecosystem Packages

| Package | Description | Tests | |---------|-------------|-------| | asijs-next | Next.js App Router / Pages Router / Edge adapter | 10 ✅ | | asijs-astro | Astro server endpoints + middleware | 7 ✅ | | asijs-remix | Remix resource routes + loader/action | 8 ✅ | | asijs-sveltekit | SvelteKit handle hook + server/universal handlers | 8 ✅ | | asijs-opentelemetry | Full OTel: spans, metrics, logs. 5 exporters | 22 ✅ | | eslint-plugin-asijs | 4 ESLint rules for AsiJS projects | ✅ | | asijs-mcp | MCP v2 server — tools, resources, prompts, workflows | 67 ✅ | | asijs-react | React Server Components — Flight, streaming SSR + hydration | 24 ✅ | | asijs-vite | AsiJS inside a Vite dev server — one port, HMR bridge | 16 ✅ | | graphql-asijs | Code-first GraphQL — TypeBox → SDL, WS subscriptions, Federation, DataLoader | 42 ✅ | | toon-asijs | TOON (token-optimized LLM format) as a native DataFormat | 21 ✅ | | miyocss | SSR-first utility CSS + SVG engine (framework-agnostic) | 129 ✅ |

VS Code Extension — asijs-code

  • 15 code snippets (GET/POST, WebSocket, CORS, JWT, OpenAPI, etc.)
  • Route Explorer webview with colour-coded method badges
  • Hover provider showing method + path on app.get()/post()
  • Debug Configuration Provider (Launch, Attach, Workspace)
  • Template Explorer (9 templates, 4 categories, search, preview)
  • Create Project Wizard (4-step GUI)
  • Inline Diagnostics (6 checks: missing dep, missing app, async/await, TODO/FIXME)

🛡️ Security (Built-in)

AsiJS includes a zero-config security module as part of AsiConfig:

const app = new Asi({
  security: {
    autoEscape: true,              // Auto-escape HTML in responses (XSS)
    maxBodySize: "1mb",            // Limit request body size
    autoNonce: true,               // Auto-generate CSP nonces
    strictContentType: "sanitize", // Sanitize Content-Type headers
    headers: {
      contentSecurityPolicy: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'"],
      },
      hsts: { maxAge: 31536000, includeSubDomains: true },
      xFrameOptions: "DENY",
      xContentTypeOptions: "nosniff",
      referrerPolicy: "strict-origin-when-cross-origin",
    },
  },
});

Presets (plain SecurityConfig objects — pass them to security: in AsiConfig):

  • maxSecurity — Maximum security for web apps (strict CSP, strict HSTS)
  • apiSecurityCore — Minimal overhead for API-only services
  • devSecurity — Relaxed for development (inline scripts allowed)

Includes OWASP-recommended headers by default: CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy.

📊 Benchmarks

AsiJS is built for performance. Full benchmark dashboard available at /benchmarks/.

Numbers below are from the CI benchmark pipeline (GitHub Actions runner, bare metal) — see the dashboard for history across commits and trends normalized across all categories.

🧭 How to read these numbers. AsiJS and Hono are monolithic — every capability (CORS, security headers, ETag, rate limiting, caching, validation) ships in the core and is always loaded. Elysia is a microkernel: all of that lives in external plugins (@elysiajs/cors, elysia-rate-limit, …), so its benchmark apps are bare routers with a couple of plugins attached. Comparing full-stack throughput across these two architectures is apples-to-oranges (a monolithic kernel is supposed to be bigger than a microkernel — the question is whether the price buys something). We therefore treat Hono as the primary competitor: it is self-contained like AsiJS, so percentages are apples-to-apples. Elysia columns are kept for reference only — see the 1a/1b fully-loaded split for why raw Elysia numbers can mislead.

Where AsiJS Wins (vs best competitor, latest run)

| Scenario | AsiJS (compiled) | vs Hono | vs Elysia (ref) | |----------|-----------------|-----------|---------| | POST /users + validation | 225,763 req/s | — | 110.9% 🏆 (ref) | | Auth POST (JWT + val + CORS + security) | 94,104 req/s | 9.3× 🏆 | 8.1× (ref) | | CRUD POST /api/products (auth + val) | 98,731 req/s | 9.7× 🏆 | 8.6× (ref) | | JSX rendering (100-row table) | 57,457 req/s | 2.1× 🏆 | — | | Array validation (100 items, valid) | 37,000 req/s | — | 107.1% 🏆 (ref) | | Validation error path (invalid payload) | 6,796 req/s | — | 1.9× 🏆 (ref) | | Large JSON body 10KB (validated) | 24,139 req/s | — | 106.4% 🏆 (ref) | | Large JSON body 100KB (validated) | 2,684 req/s | — | 109.6% 🏆 (ref) | | File upload 1MB (multipart) | 5,093 req/s | 100.8% | 100.2% (ref) | | Static preload (in-memory cache, 2.2.7) | 77,898 req/s | — | AsiJS-only (1.26× vs own disk path) | | Upload + save to disk (256KB, streaming) | 538 req/s | — | AsiJS-only (streaming +28% vs buffered) | | Response serialization (3.2, compiled schema) | 117k ops/s | — | AsiJS-only (×1.4 vs own plain JSON path) |

Competitive / Near-Parity

| Scenario | AsiJS | vs Hono | vs Elysia (ref) | |----------|-------|---------|-----------------| | CRUD PUT /api/products/:id | 11,485 req/s | 115.8% | 99.8% (ref) | | Blog API POST /posts (auth + val) | 172,366 req/s | 119.7% | 96.2% (ref) | | File upload 5MB (multipart) | 920 req/s | 92.8% | 170.4% (ref) | | CRUD GET list + filter + pagination | 94,145 req/s | 11.7× | 88.5% (ref) | | CORS preflight OPTIONS | 101,546 req/s | 113.8% | 82.3% (ref) | | GET /search (query params) | 352,050 req/s | 168.6% | 71.7% (ref) | | Concurrency C=100 / C=1000 | 692k / 738k req/s | 1.9× | 59.3% / 59.7% (ref) | | Query cache hit (repeated query, 2.2.6) | 235,899 req/s | 111.6% | 71.9% (ref) |

Known Gaps (honest, vs Hono)

Where AsiJS loses to Hono, and exactly why. 13 of 18 categories AsiJS wins; these 5 are the remaining work:

| Scenario | AsiJS | vs Hono | Why | |----------|-------|---------|-----| | 404 fast path (no route match) | 207,505 req/s | 82.6% | AsiJS generates a JSON body {error, path, method} + searches similar routes in dev mode on every miss; Hono returns a pre-built bare NOT_FOUND Response with no body. AsiJS intentionally ships a useful 404 body — a bare-response fast path is a candidate. | | Error path (handler throws → 500) | 162,516 req/s | 73.3% | AsiJS builds a structured error response (status, error class, message) and routes it through the error pipeline; Hono rethrows the minimal 500. A pre-built generic 500 body is a candidate. | | Query cache miss (unique query) | 164,273 req/s | 66.8% | Unique query strings bypass the 2.2.6 cache, so the single-pass parser runs per request and builds a fresh object; Hono's fixed benchmark query hits its own fast path. | | Static file serving (small / 2MB) | 107k / 136k req/s | 71.4% / 78.1% | AsiJS's static plugin goes through middleware + cache + header pipeline; Hono returns Bun.file() directly. A zero-copy fast path in the static plugin is a candidate. | | Complex validation (4-level nested) | 33,350 req/s | — (Elysia only) | The 2.2.5 compiled validator still walks TypeBox's generic check pipeline per level. Narrowing codegen (object/array hot paths) is the tracked follow-up. |

⚠️ Numbers are from a single CI run; runner hardware and bun-version: latest drift between runs. Compare within one run (percentages), not absolute values across runs — use the dashboard trends (normalized avg % of best across all categories) for commit-to-commit comparisons.

Benchmark Suites

| Suite | Command | Covers | |-------|---------|--------| | Core | bun run bench | GET/params/query/POST, validation, compiled mode | | Production | bun run bench:production | middleware chain, upload, static, JSX, blog API | | Fullstack | bun run bench:fullstack | auth, gateway, CRUD, preflight, security headers, fair middleware-set comparison | | P0 Hot-Path | bun run bench:p0 | concurrency, route scaling, static preload, array validation | | P1 API-Case | bun run bench:p1 | query cache, 404, error path, large bodies | | P2 Features | bun run bench:p2 | WebSocket pub/sub, cache layer, DB layer, allocations | | Serialization | bun run bench:serialize | compiled schema serializer vs plain JSON (codegen + e2e through AsiJS) | | SSR frameworks | bun run bench:ssr | production servers on ports (C=32 concurrent fetch): AsiJS (JSX + string) vs Hono vs Astro (standalone) vs SvelteKit (adapter-node) vs Nuxt (nitro bun) — 100-row table page |

SSR frameworks methodology. Port-based, production builds only — real TCP + HTTP stack, so numbers include server + network overhead (not just render cost, unlike the in-process JSX row above). Framework apps live in bench/frameworks/*; build once with bun run bench:ssr:build (installs SvelteKit/Astro/Nuxt — heavy, opt-in in CI via the run_ssr_frameworks workflow input). All competitors are pinned to current latest majors (astro 7, nuxt 4, sveltekit 2 + vite 7; hono 4.13 / elysia 1.4.29 in the core benches) so AsiJS never races year-old code. Next.js / Remix are a tracked follow-up: their build toolchains require Node (next build / remix build), which the Bun-only CI doesn't have.

Benchmark Dashboard

AsiJS includes an automated benchmark dashboard:

  • bun run bench:collect — run all benchmark suites (above; skips SSR when framework builds are absent)
  • bun run bench:dashboard — generate Chart.js HTML dashboard
  • Historical trends: normalized avg score vs best across all categories (with lower-is-better groups inverted) + per-category RPS picker
  • Integrated into vitepress docs at /benchmarks/
  • CI pipeline auto-generates on every push to main

📁 Project Structure

asijs/
├── src/
│   ├── asi.ts                  # Core framework
│   ├── router.ts               # Trie router
│   ├── router-perf.ts          # Radix tree + middleware flattener
│   ├── context.ts              # Request context
│   ├── validation.ts           # TypeBox validation
│   ├── compiler.ts             # Route compiler
│   ├── security-core.ts        # Built-in security module
│   ├── circuit-breaker.ts      # Circuit breaker resilience
│   ├── deduplicate.ts          # Request dedup + cache stampede
│   ├── ws-pubsub.ts            # WebSocket pub/sub rooms
│   ├── ws-redis.ts             # Redis pub-sub bridge
│   ├── api-version.ts          # API versioning
│   ├── ssg.ts                  # Static site generation
│   ├── serverless.ts           # Serverless optimisation
│   ├── api-docs.ts             # API documentation portal
│   ├── hot-reload.ts           # Hot reload 2.0
│   ├── hmr.ts                  # HMR browser push
│   ├── repl.ts                 # Interactive REPL
│   ├── playground.ts           # Web playground
│   ├── plugin-deps.ts          # Plugin dependency manager
│   ├── plugin-registry.ts      # Plugin registry
│   ├── migrate-express.ts      # Express migration
│   ├── migrate-koa.ts          # Koa migration
│   ├── authjs.ts               # Auth.js integration
│   ├── upload.ts               # File upload provider
│   ├── auto-api.ts             # PostgREST-like auto API
│   ├── codegen.ts              # OpenAPI client codegen
│   ├── serialize.ts            # JSON Schema response serialization (3.2)
│   ├── formats.ts              # Data formats layer: JSON/YAML/custom + TOON
│   ├── native/                 # Native/polyglot modules (FFI + sidecars + Lua)
│   └── plugins/
│       ├── cors.ts             # CORS plugin
│       └── static.ts           # Static files plugin
├── packages/
│   ├── vscode-asijs/           # VS Code extension
│   ├── eslint-plugin-asijs/    # ESLint rules
│   ├── next-asijs/             # Next.js adapter
│   ├── astro-asijs/            # Astro adapter
│   ├── remix-asijs/            # Remix adapter
│   ├── sveltekit-asijs/        # SvelteKit adapter
│   ├── opentelemetry-asijs/    # OpenTelemetry integration
│   ├── mcp-asijs/              # MCP v2 server
│   ├── asijs-react/            # React Server Components
│   ├── asijs-vite/             # Vite dev server
│   ├── graphql-asijs/          # GraphQL plugin v2
│   ├── toon-asijs/             # TOON format adapter
│   └── MiyoCSS/                # SSR-first CSS + SVG framework
├── examples/                   # Example apps
├── test/                       # 2036 tests (2018 pass, 18 skip)
│   ├── integration/            # Docker-based integration tests
│   ├── e2e/                    # End-to-end tests
│   └── k6/                     # k6 load testing scripts
├── bench/                      # Benchmarks + dashboard + SSR frameworks
└── docs/                       # VitePress documentation site

🧪 Testing

# Run all tests (2036 tests)
bun test

# With coverage
bun test --coverage

# Integration tests (requires Docker)
bun test test/integration/

# E2E tests
bun test test/e2e/

# Load testing with k6
bun run test:k6

# TypeScript check
bun run typecheck

Test Quality

  • 2036 tests (2018 pass, 18 skip) — 0 failures
  • Integration tests — Docker-based PostgreSQL, Redis, MinIO
  • E2E tests — Full cycle: auth → upload → CRUD → WebSocket
  • Load tests — k6 scenarios: auth flow, CRUD, WebSocket, file upload
  • 0 TypeScript errors (tsc --noEmit)
  • Pre-release security audit — All v1.3 modules reviewed: 3 CRITICAL fixes, 2 HIGH fixes, 3 MEDIUM fixes

🤖 MCP — AI/LLM Integration

AsiJS supports the Model Context Protocol for AI assistant integration:

import { Asi, mcp, createMCPServer } from "asijs";

const app = new Asi();

// Add routes...
app.get("/users", () => users);

// Add MCP plugin for AI assistants
app.plugin(mcp({
  name: "my-api",
  version: "1.0.0",
  tools: [
    {
      name: "list_users",
      description: "List all users",
      inputSchema: { type: "object", properties: {} },
      handler: async () => ({
        content: [{ type: "text", text: JSON.stringify(users) }]
      }),
    },
  ],
}));

// Run as MCP server for Claude Desktop, Cursor, etc.
const mcpServer = createMCPServer(app);
await mcpServer.start();

📘 Documentation

Full documentation available at the VitePress docs site:

🤝 Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing)
  5. Open a Pull Request

📝 License

MIT License — see LICENSE file for details.

🙏 Credits