MatchBox includes a native web runtime for building small, fast BoxLang web applications without requiring a JVM or a traditional servlet container. You can follow the MatchBox open beta at https://github.com/ortus-boxlang/matchbox. There are two related pieces in the beta today: a webroot server for .bxm templates and static assets, and a routed app server built around web.server(). Both are early, but they show the direction clearly: BoxLang should be able to serve HTTP from a compact native runtime when the application does not need the full JVM stack.
ποΈ Two Ways to Serve
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MatchBox Native Web Runtime β
β β
β βββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β Webroot Mode β β App Server Mode β β
β β matchbox --serve β β web.server() β β
β β β β β β
β β - .bxm template files β β - Explicit routing β β
β β - Static asset serving β β - Middleware pipeline β β
β β - Familiar request scopes β β - JSON APIs β β
β β - Quick start, no config β β - WebSockets β β
β β β β - Webhook helpers β β
β βββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β
β Built on: matchbox-server crate (Axum + Tokio) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Webroot and BXM Templates
The webroot server is the quickest path to get BoxLang serving HTTP. Point MatchBox at a directory and it serves .bxm files plus static assets:
matchbox --serve --port 8080 --webroot ./www
BXM files are HTML-like templates that MatchBox transpiles ahead of time into BoxLang bytecode. A template such as:
<bx:output>Hello #user.name#!</bx:output>
is lowered into normal output calls that the VM executes efficiently. The same .bxm templating language you know from BoxLang JVM works here - interpolation with #, <bx:output>, <bx:if>, <bx:loop>, includes, and all the standard template tags.
The webroot runtime injects familiar request scopes into each request:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Injected Request Scopes β
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ€
β url β Query string parameters β
β form β POST body fields β
β cookie β Request cookies β
β session β In-memory session state β
β cgi β Server and request metadata β
ββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββ
The repo includes a web server example with the following pages:
index.bxm- session persistence and dynamic outputabout.bxm- CGI scope and loopscontact.bxm- URL parameters and conditional logicstyles.css- served as a static asset alongside templates
There is also a starter template to scaffold a new project:
https://github.com/ortus-boxlang/matchbox-web-server-template
π£οΈ Routed Apps with web.server()
For applications that need explicit routing, middleware, APIs, or webhooks, the app server exposes a clean BoxLang API:
import boxlang.web
app = web.server()
app.get( "/api/hello/:name", ( event, rc, prc ) -> {
event.renderJson( {
"message": "Hello " & rc.name
} )
} )
app.listen( 8090 )
The Request Collections
Every route handler receives three arguments:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Handler Arguments β
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β event β Request and response helpers (render, redirect...) β
ββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β rc β Public request collection: β
β β - Route params (:name, :id, etc.) β
β β - Query string params β
β β - Form fields β
β β - Top-level JSON body keys β
ββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β prc β Private request collection: β
β β - Middleware-set values β
β β - Internal state not exposed to the client β
ββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Middleware
Middleware uses a fourth next argument to build request pipelines:
app.use( ( event, rc, prc, next ) -> {
prc.requestStarted = true
next.run()
} )
What the App Server Supports Today
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Native App Server Capabilities (Beta) β
ββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ€
β Route groups β β
β
β Middleware pipeline β β
β
β Cookies β β
β
β In-memory sessions β β
β
β JSON responses (renderJson) β β
β
β HTML responses (renderHtml) β β
β
β Static asset mounts β β
β
β Explicit template rendering β β
β
β Signed webhook helpers β β
β
β WebSocket listeners β β
β
ββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
π WebSockets
The beta also includes a WebSocket listener model built around lifecycle methods. Listener classes define:
class MySocketListener {
function onConnect( channel ) {
channel.sendText( "Welcome!" )
}
function onMessage( message, channel ) {
channel.broadcast( "Echo: " & message )
}
function onClose( channel ) {
// cleanup
}
}
Channels support sending text, JSON, bytes, broadcasting to all connected clients, and explicit close operations. That gives MatchBox a path for small real-time apps, live dashboards, and collaborative experiments - without pulling in a large server stack.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β WebSocket Channel API β
β β
β channel.sendText( message ) - Send a text frame β
β channel.sendJson( struct ) - Serialize and send JSON β
β channel.sendBytes( binary ) - Send raw bytes β
β channel.broadcast( message ) - Send to all connected clients β
β channel.close() - Close the connection β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π§± Under the Hood
The native web server is powered by the matchbox-server crate, which is built on Axum and Tokio - Rust's most battle-tested async web infrastructure. Your BoxLang application code runs on top of that, with the fiber scheduler handling concurrency at the VM level.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MatchBox Server Stack β
β β
β BoxLang Application Code (.bxs / .bxm) β
β β β
β βΌ β
β MatchBox VM (fiber scheduler, bytecode execution) β
β β β
β βΌ β
β matchbox-server crate β
β β β
β βΌ β
β Axum (HTTP routing, middleware, WebSockets) β
β β β
β βΌ β
β Tokio (async I/O runtime) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
No JVM. No servlet container. No Undertow or Jetty. The whole stack ships as a single compact binary.
π Where This Fits
MatchBox web is not trying to replace the BoxLang JVM ecosystem. ColdBox, CommandBox, servlet containers, and the JVM runtime remain the mature path for full-stack production applications that need the complete ecosystem.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Which Runtime for Which Use Case? β
ββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ€
β MatchBox Native Web β BoxLang JVM (ColdBox / MiniServer)β
ββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ€
β Small APIs β Full-stack MVC applications β
β Lightweight microservices β Enterprise apps with Java interop β
β Webhook receivers β ColdFusion CFML compatibility β
β Edge-style apps β Full module ecosystem (ForgeBox) β
β Static + dynamic pages β Complex ORM / datasources β
β WebSocket experiments β Production-hardened deployments β
β Native binary deployment β Servlet container integrations β
β Tiny container images β β
ββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββ
β οΈ Beta Boundaries
This is open beta software. Some APIs may change as the app-server surface hardens.
One important distinction from the ESP32 embedded web profile: the native server has significantly more capability than what is available on a microcontroller. On ESP32, MatchBox intentionally supports a smaller route-driven profile and rejects heavier features at compile time. A web app that works on the native server may need to be simplified before it can run on a device.
π Where to Start
Option 1: Webroot with BXM templates
# Scaffold from the starter template
git clone https://github.com/ortus-boxlang/matchbox-web-server-template myapp
cd myapp
# Serve it
matchbox --serve --port 8080 --webroot ./www
Option 2: Explicit routes with web.server()
// app.bxs
import boxlang.web
app = web.server()
app.get( "/", ( event, rc, prc ) -> {
event.renderHtml( "<h1>Hello from MatchBox</h1>" )
} )
app.get( "/api/status", ( event, rc, prc ) -> {
event.renderJson( { "ok": true, "runtime": "matchbox" } )
} )
app.listen( 8080 )
matchbox app.bxs
Use the webroot mode for dynamic BXM pages and server-rendered content. Use web.server() when you want explicit routes, JSON endpoints, middleware, or WebSockets.
The interesting part is not just that MatchBox can serve HTTP. It is that BoxLang can now target a compact native web runtime, with the same language moving between scripts, CLI tools, servers, browser bundles, and devices.
π The Bigger Picture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BoxLang Runtime Landscape β
β β
β βββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ β
β β BoxLang JVM Runtime β β MatchBox (Rust VM) β β
β β β β β β
β β - Web Servers β β - Native Web βββ Here β β
β β - AWS Lambda β β - Browser (WASM/JS) β β
β β - Google Cloud Fns β β - WASI Containers β β
β β - Desktop (Electron) β β - Edge Runtimes β β
β β - Full Java interop β β - Native CLI β β
β β - All BL modules β β - ESP32 / IoT β β
β βββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ β
β β
β Same BoxLang language. Different runtimes. β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Explore the project and open issues at https://github.com/ortus-boxlang/matchbox.
Read the full MatchBox docs at https://boxlang.ortusbooks.com/boxlang-framework/matchbox.
Join the Ortus Community
Be part of the movement shaping the future of web development. Stay connected and receive the latest updates on product launches, tool updates, promo services and much more.
Subscribe to our newsletter for exclusive content.
Follow Us on Social media and don't miss any news and updates:
Add Your Comment