NIAOJoin Beta
Ecosystem

ahiru

available

HTTP • WebSocket • Migrations • Auth

Framework

Overview

ahiru is the backend framework for Niao. You define routes as regular functions, attach middleware, and start an HTTP or WebSocket server. Handlers compile to bytecode like any other Niao code; the networking stack itself is native (Tokio + Axum), so you're not paying for a slow interpreter on the hot path.

There's a CLI for scaffolding new services, routes, config, migration folders, the usual layout, so you don't reinvent project structure every time. It works with the Postgres, SQLite, and Mongo drivers if you need persistence.

  • Bytecode route handlers
  • Project scaffolding CLI
  • SQL migrations
  • /health and /ready probes

Import

import
import "std/ahiru/v3"

Quick start

quick start
import "std/ahiru/v3"
let app = ahiru.new()
app.get("/health", fn(req) { return ahiru.json({ status: "ok" }) })
app.listen(8080)

Capabilities

High-level overview of what ahiru is for.

Route handlers

Register GET, POST, PUT, PATCH, and DELETE endpoints. Each handler gets a request object with params, headers, and body already parsed. Return JSON, plain text, or build a custom response.

WebSocket support

Upgrade an HTTP connection and keep it open for bidirectional messages. Handy for chat, live feeds, or anything that needs push instead of polling.

Middleware pipeline

Run logging, CORS, auth checks, or rate limits before your handler sees the request. Middleware composes in order, same idea as Express or Axum layers.

SQL migrations

Keep schema changes in versioned up/down scripts. Tracks what's been applied so deploys stay repeatable across environments.

CLI scaffolding

Spin up a new service from the command line with routes, config stubs, and migration directories already laid out.

Multi-database support

Plug in npg, nsqlite, or nmongo using the same connection and migration patterns the framework expects.

API reference

106 functions and methods in ahiru. Grouped by category from the standard library docs.

CLI

SignatureDescription
niao ahiru create <name>Interactive wizard - DB, auth, WebSocket, security
niao ahiru serveRun project entry with VM bytecode (default)
niao ahiru serve --mode interpInterpreter mode (multi-file imports, dev side-effects)
niao ahiru serve --devAuto-reload on file changes
niao ahiru serve --netBind `0.0.0.0` and show LAN URL
niao ahiru serve --port 3000Use port 3000 (prompts if busy)
niao ahiru bench --routes health,pingHandler throughput micro-benchmark
niao ahiru migrateApply SQL migrations from `migrations/`
niao ahiru routesShow `ahiru.config.toml` server/DB/auth settings

ahiru v2 helpers (`stdlib/ahiru/v2.niao`)

SignatureDescription
ahiru_v2_create_app_from_config(path)Load `ahiru.config.toml`
ahiru_v2_use_dev_middleware(app)request_id + logging + CORS
ahiru_v2_use_standard_middleware(app)dev middleware + secure headers
ahiru_v2_use_quiet_middleware(app)request_id only, no access log
ahiru_v2_use_production_middleware(app)JSON logs + secure headers + skip health/ping
ahiru_v2_set_quiet(app, bool)Runtime toggle for logs and handler print()
ahiru_v2_mount_health(app, path)`GET /health` - native Rust handler when `native_routes` enabled
ahiru_v2_mount_ping(app, path)`GET /ping` - native Rust handler when `native_routes` enabled
ahiru_v2_ok_json(body)Response builders
ahiru_v2_error_json(...)Response builders
ahiru_v2_get/post(app, path, handler)Public routes shorthand
ahiru_v2_version()Returns `"2.2.0"` (matches ahiru lib 0.2.2)

Niao API (builtins)

SignatureDescription
ahiru_app_new()Create app handle
ahiru_app_from_config(path)Create app handle
ahiru_app_get/post/put/delete/patch(app, path, handler, opts?)Register routes
ahiru_app_ws(app, path, handler, opts?)WebSocket route
ahiru_app_use(app, middleware, opts?)Middleware: `cors`, `rate_limit`, `request_id`, `logging`, `secure_headers`
ahiru_app_set_logging(app, opts?)Runtime log control: `access_log`, `json_logs`, `quiet_handlers`, `skip_paths`
ahiru_app_init_db(app)Connect pools from config
ahiru_app_listen(app, host?, port?)Start server (blocking)
ahiru_app_routes(app)List registered routes
ahiru_native_routes()Whether native health/ping routes are enabled
ahiru_native_mount_health(app, path)Register native `GET /health`
ahiru_native_mount_ping(app, path)Register native `GET /ping`
ahiru_response(status, content_type, body)Build response object
ahiru_json_response(status, json)JSON response helper

Handler `ctx` object

SignatureDescription
methodHTTP method
pathRequest path
bodyRequest body
queryQuery parameters
paramsPath parameters (`:id` routes)
headersLowercase header names
userAuthenticated user (when auth enabled)
request_idRequest correlation ID

CLI

SignatureDescription
niao ahiru db migrateApply migrations
niao ahiru db statusApplied vs pending
niao ahiru db seedRun `seeds/*.sql`
niao ahiru db rollbackRoll back last migration (`.down.sql`)
niao ahiru db reset --forceDrop SQLite + re-migrate
niao ahiru doctorConfig + DB + port checks
niao ahiru add <feature>auth, db, websocket, cache
niao ahiru generate resource <name>Handler + migration scaffold
niao ahiru openapiEmit `public/openapi.json`
niao ahiru testRun `tests//*.niao`
niao ahiru consoleProject REPL stub
niao ahiru workerJob worker entry

Project commands

SignatureDescription
niao ahiru create <name>Interactive project wizard
niao ahiru create <name> --yesDefaults, no prompts
niao ahiru serveRun project (VM mode, default)
niao ahiru serve --mode vmExplicit VM (same as default)
niao ahiru serve --mode interpInterpreter fallback
niao ahiru serve --devAuto-reload on `.niao` / config changes
niao ahiru serve --netBind `0.0.0.0`, show LAN URL
niao ahiru serve --port 3000Fixed port (prompts if busy when explicit)
niao ahiru serve --project .Project root (default `.`)
niao ahiru serve --file path.niaoOverride entry file
niao ahiru migrateRun SQL migrations from `migrations/`
niao ahiru routesShow config summary

App lifecycle

SignatureDescription
ahiru_app_new(config?)Create app handle
ahiru_app_from_config(path)Load from `ahiru.config.toml`
ahiru_app_listen(app, host?, port?)Start server (blocking)
ahiru_app_routes(app)List registered routes
ahiru_app_init_db(app)Connect DB pools from config

Routes

SignatureDescription
ahiru_app_get(app, path, handler, opts?)GET route
ahiru_app_post(app, path, handler, opts?)POST route
ahiru_app_put(app, path, handler, opts?)PUT route
ahiru_app_delete(app, path, handler, opts?)DELETE route
ahiru_app_patch(app, path, handler, opts?)PATCH route
ahiru_app_ws(app, path, handler, opts?)WebSocket route

Middleware and logging

SignatureDescription
ahiru_app_use(app, name, opts?)`cors`, `rate_limit`, `request_id`, `logging`, `secure_headers`
ahiru_app_set_logging(app, opts?)Runtime log control

Native routes (new in 0.2.2)

SignatureDescription
ahiru_native_routes()Returns whether native health/ping is enabled
ahiru_native_mount_health(app, path)Native `GET /health` → `{"status":"ok"}`
ahiru_native_mount_ping(app, path)Native `GET /ping` → `{"pong":true}`

Responses and database

SignatureDescription
ahiru_response(status, content_type, body)Build response object
ahiru_json_response(status, json)JSON response helper
ahiru_db_exec(app, db_name, sql, params?)Run SQL on named pool

v2 helpers (`stdlib/ahiru/v2.niao`)

SignatureDescription
ahiru_v2_version()Returns `"2.2.0"`
ahiru_v2_create_app_from_config(path)Load `ahiru.config.toml`
ahiru_v2_use_dev_middleware(app)request_id + logging + CORS
ahiru_v2_use_standard_middleware(app)dev middleware + secure headers
ahiru_v2_use_quiet_middleware(app)request_id only, no access log
ahiru_v2_use_production_middleware(app)JSON logs + secure headers + skip health/ping
ahiru_v2_set_quiet(app, bool)Runtime toggle for logs and handler `print()`
ahiru_v2_mount_health(app, path)Native or Niao `GET /health`
ahiru_v2_mount_ping(app, path)Native or Niao `GET /ping`
ahiru_v2_get(app, path, handler)Public GET shorthand
ahiru_v2_post(app, path, handler)Public POST shorthand
ahiru_v2_listen(app)Start server
ahiru_v2_listen_on(app, host, port)Start on host/port
ahiru_v2_ok_json(body)200 JSON response
ahiru_v2_error_json(status, message, code)Error JSON response
ahiru_v2_health_ok()Standard health response object
ahiru_v2_not_found(ctx)404 JSON response
ahiru_v2_ctx_query(ctx, key, default)Query param with default
ahiru_v2_ctx_param(ctx, key, default)Path param with default
ahiru_v2_rate_limit(app, rps)Rate limit middleware

Notes

  • Route handlers compile to .niaobc, on a warm start you skip lex/parse/IR and go straight to the VM.
  • /health and /ready are built in for k8s and Docker health checks.