A lightweight HTTP server framework for the Turbo programming language.
import { create, get, post, listen } from "./src/servo"
import { json, text } from "./src/response"
import { body, query } from "./src/request"
fn main() {
let app = create(3000)
get(app, "/", |req: str| -> str {
text(200, "Hello from TurboServo!")
})
get(app, "/greet", |req: str| -> str {
let name = query(req, "name")
json(200, "{\"hello\": \"" + name + "\"}")
})
post(app, "/echo", |req: str| -> str {
json(200, body(req))
})
print("Server running on http://localhost:3000")
listen(app)
}
turbolang run examples/hello/main.tb- HTTP server with route registration (GET, POST, PUT, DELETE, PATCH, OPTIONS)
create_public()for production deployment — binds to 0.0.0.0 instead of localhost- CORS preflight helper — explicit opt-in since Turbo 0.8.2 is secure-by-default (no wildcard CORS)
- Runtime header limit protection (8 KB/line, 64 KB total, 32 MB body) enforced by Turbo 0.8.2
- Request context: method, path, headers, query params, body
- Explicit JSON/text/HTML response helpers aligned to Turbo Lang 0.8.2
- 401/403/405 response helpers for auth and method-not-allowed flows
- Typed query/form parsing helpers for real request handling
- Path parameter extraction via router module
- Browser-facing hosted demo with live in-memory state
- Server-rendered HTML fragments for live status panels
- Real JSON workload endpoints for compute-heavy interactions
- Benchmark suite vs Hono (Bun) and Go
create(port: i64) -> i64-- create server on localhost (dev)create_public(port: i64) -> i64-- create server on 0.0.0.0 (production)get(app, path, handler)-- register GET routepost(app, path, handler)-- register POST routeput(app, path, handler)-- register PUT routedelete(app, path, handler)-- register DELETE routepatch(app, path, handler)-- register PATCH routeoptions(app, path, handler)-- register OPTIONS route (use with CORS preflight helper)listen(app)-- start server (blocks)
method(req) -> str-- HTTP methodpath(req) -> str-- request pathbody(req) -> str-- request bodyquery(req, key) -> str-- query parameterheader(req, name) -> str-- request headerquery_or(req, key, fallback) -> str-- query parameter with defaultquery_i64(req, key, fallback) -> i64-- typed integer query parameterform_value(body, key) -> str-- parseapplication/x-www-form-urlencodedstyle bodiesform_i64(body, key, fallback) -> i64-- typed integer form field
json(status, body) -> str-- JSON responsetext(status, body) -> str-- text responsehtml(status, body) -> str-- HTML responsecreated_json(body) -> str-- 201 JSON responseaccepted_json(body) -> str-- 202 JSON responseno_content() -> str-- 204 empty responsenot_found() -> str-- 404 responsebad_request(msg) -> str-- 400 responseunauthorized(msg) -> str-- 401 responseforbidden(msg) -> str-- 403 responsemethod_not_allowed() -> str-- 405 responsecors_preflight(origin) -> str-- CORS preflight 204 response (explicit opt-in required since v0.8.2)
match_path(pattern, path) -> str-- match with paramsparam(params, key) -> str-- extract named param
The showcase server demonstrates Turbo's native computation speed through five endpoints that process real data workloads. These are the endpoints we benchmark against Go and Bun.
turbolang run examples/showcase/main.tbAll example servers respect PORT when set, so you can avoid local port collisions:
PORT=3101 turbolang run examples/showcase/main.tbThe server starts on port 3001 with:
GET /-- hosted-demo style landing pageGET /health-- server readiness payloadGET /api/info-- project metadataGET /api/server-state-- live in-memory countersGET /fragment/status-- server-rendered live status panelGET /fragment/memory-- server-rendered memory boardPOST /fragment/arena-- server-owned workload comparison fragmentPOST /transformPOST /analyzePOST /searchGET /matrixPOST /pipeline
What the hosted demo now proves:
- Turbo can serve a real landing page directly as HTML
- the server can own live state in memory without a database
- the browser can ask Turbo for fresh HTML fragments for live panels
- heavy compute endpoints can remain JSON APIs while the page stays SSR-first
Open the dashboard in your browser:
open http://localhost:3001/Multi-stage processing of CSV records: parse, validate, normalize, aggregate, sort, paginate.
curl -X POST http://localhost:3001/transform -d '1,Alice,500,engineering
2,Bob,300,marketing
3,Carol,450,engineering
4,Dave,200,sales
5,Eve,600,engineering'Returns sorted records, category totals, and aggregate statistics.
Computes practical statistics on numerical data: mean, median, stddev, variance, percentiles (p50/p95/p99), histogram (10 bins), and outlier detection.
curl -X POST http://localhost:3001/analyze -d '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20'Fuzzy text search across 1000 in-memory product records with relevance scoring, category filtering, and pagination.
# Search all categories
curl -X POST http://localhost:3001/search -d 'query=premium'
# Filter by category + price range + pagination
curl -X POST http://localhost:3001/search -d 'query=gadget&category=electronics&page=2&limit=5&min_price=50&max_price=300'Matrix operations using tight nested loops. Supports multiply, transpose, and trace.
# 10x10 matrix multiply (returns full result)
curl 'http://localhost:3001/matrix?size=10&op=multiply'
# 100x100 matrix multiply (returns metadata + trace)
curl 'http://localhost:3001/matrix?size=100&op=multiply'
# Transpose
curl 'http://localhost:3001/matrix?size=10&op=transpose'
# Trace
curl 'http://localhost:3001/matrix?size=10&op=trace'Configurable multi-stage pipeline with stage-by-stage tracking. Stages: filter, map, sort, reduce, unique, reverse, take.
curl -X POST http://localhost:3001/pipeline -d '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
filter:even
map:double
sort:desc
reduce:sum'Available pipeline stages:
filter:even/filter:odd-- filter by parityfilter:gt:N/filter:lt:N-- filter by thresholdmap:double/map:square/map:negate/map:add:N-- transform valuessort:asc/sort:desc-- sort orderreduce:sum/reduce:product/reduce:min/reduce:max-- aggregate to single valueunique-- remove duplicatesreverse-- reverse arraytake:N-- keep first N elements
This repo now carries TURBO-LANG-AUDIT.md, which documents:
- the Turbo Lang release this project was aligned to
- the concrete bugs fixed during the upgrade
- gaps this real project still exposes in Turbo itself
That file is intended to make TurboServo a living feedback project for Turbo Lang, not just a demo.
TurboServo is now shaped like a realistic deployed reference app:
- SSR landing page from a single Turbo binary
- live server-memory counters exposed as HTML fragments + JSON
- progressive enhancement with tiny browser JavaScript
- compute APIs (
/analyze,/search,/matrix,/pipeline) still directly callable
For public hosting, keep following Turbo's current guidance:
- run the Turbo binary behind nginx or Caddy
- do not expose the built-in HTTP server directly to untrusted networks
./benchmarks/run_benchmarks.shCompares identical JSON API workloads across TurboServo, Hono/Bun, and Go net/http.
turboservo/
src/
servo.tb # Core server API
request.tb # Request helpers
response.tb # Response builders
router.tb # Path parameter extraction
showcase/
transform.tb # /transform endpoint
analyze.tb # /analyze endpoint
search.tb # /search endpoint
matrix.tb # /matrix endpoint
pipeline.tb # /pipeline endpoint
examples/
hello/main.tb # Simple hello world
showcase/main.tb # Performance showcase server
benchmarks/
api_bench.tb # TurboServo benchmark server
go_bench.go # Go comparison
hono_bench.ts # Bun/Hono comparison
run_benchmarks.sh # Benchmark runner
turbo.toml
README.md