boxlang-runtime-miniserver
BoxLang MiniServer
Overview
BoxLang MiniServer is the official lightweight web server for BoxLang applications. It is built on Undertow and is NOT a servlet container — it is a purpose-built, fast web runtime for BoxLang. Use it for development servers and production deployments where a full Java EE container is not needed.
Binary: boxlang-miniserver (Windows: boxlang-miniserver.bat)
Default behavior: binds 0.0.0.0:8080, uses current working directory as webroot.
Quick Start
# Start in current directory on default port 8080
boxlang-miniserver
# Custom port and webroot
boxlang-miniserver --port 9000 --webroot ./public
# Enable URL rewrites (SPA or front-controller pattern)
boxlang-miniserver --rewrites
# Production with health checks
boxlang-miniserver --port 8080 --health-check --health-check-secure
CLI Flags
| Flag | Short | Description |
|---|---|---|
--port <n> |
-p |
Port to bind (default: 8080) |
--host <ip> |
Host/IP to bind (default: 0.0.0.0) |
|
--webroot <path> |
-w |
Webroot directory (default: CWD) |
--debug |
-d |
Enable debug mode |
--rewrites |
-r |
Enable URL rewrites to index.bxm |
--configPath <path> |
-c |
Path to JSON config file |
--serverHome <path> |
-s |
Override server home directory |
--health-check |
Enable health check endpoints | |
--health-check-secure |
Secure health checks (details localhost-only) | |
--version |
Print version | |
--help |
Print help |
Environment Variables
Environment variables are scanned before CLI arguments; CLI args take precedence.
| Variable | Description |
|---|---|
BOXLANG_CONFIG |
Override boxlang.json path |
BOXLANG_DEBUG |
Enable/disable debug mode |
BOXLANG_HOME |
Override server HOME directory |
BOXLANG_HOST |
Override bind host |
BOXLANG_PORT |
Override bind port |
BOXLANG_REWRITES |
Enable/disable URL rewrites |
BOXLANG_REWRITE_FILE |
Rewrite target file (default: index.bxm) |
BOXLANG_WEBROOT |
Override webroot path |
BOXLANG_HEALTH_CHECK |
Enable health check endpoints |
BOXLANG_HEALTH_CHECK_SECURE |
Enable secure health checks |
BOXLANG_MINISERVER_OPTS |
Extra JVM options for startup |
JSON Configuration (miniserver.json)
Create a miniserver.json file and pass it with --configPath (or use .boxlang.json project convention):
{
"port": 8080,
"host": "0.0.0.0",
"webRoot": "./www",
"debug": false,
"configPath": "./.boxlang.json",
"serverHome": "./.engine/boxlang",
"rewrites": true,
"rewriteFileName": "index.bxm",
"healthCheck": true,
"healthCheckSecure": true,
"envFile": "./.env",
"warmupURLs": ["/api/warmup", "/health/ready"],
"undertow": {
"ioThreads": 4,
"workerThreads": 32,
"bufferSize": 16384
},
"socket": {
"tcpNoDelay": true,
"reuseAddress": true
},
"websocket": {
"maxFrameSize": 65536,
"maxTextMessageSize": 65536
}
}
Config Priority (high → low)
- CLI arguments
- JSON config file
- Environment variables
- Defaults
.boxlang.json Project Convention
Place a .boxlang.json in your webroot for project-level BoxLang configuration. It is automatically merged with the global boxlang.json at startup — commit it to source control for portable config.
{
"modules": {
"bx-mysql": { "enabled": true },
"bx-mail": { "enabled": true }
},
"debugMode": false,
"timezone": "UTC"
}
Pair with a miniserver.json that points to it:
{
"port": 8080,
"webRoot": "./www",
"configPath": "./.boxlang.json"
}
Example Configurations
Development
{
"port": 8080,
"webRoot": "./public",
"debug": true,
"rewrites": true
}
Production
{
"port": 8080,
"host": "0.0.0.0",
"webRoot": "/var/www/myapp",
"rewrites": true,
"healthCheck": true,
"healthCheckSecure": true,
"warmupURLs": ["/api/warmup/database", "/health/ready"],
"undertow": {
"ioThreads": 8,
"workerThreads": 64
}
}
Full Options
{
"port": 8080,
"host": "0.0.0.0",
"webRoot": "./www",
"debug": false,
"rewrites": true,
"rewriteFileName": "index.bxm",
"serverHome": "./.engine/boxlang",
"configPath": "./.boxlang.json",
"envFile": ".env",
"healthCheck": true,
"healthCheckSecure": true,
"warmupURLs": ["/api/warmup"],
"undertow": { "ioThreads": 4, "workerThreads": 32, "bufferSize": 16384 },
"socket": { "tcpNoDelay": true, "reuseAddress": true },
"websocket": { "maxFrameSize": 65536, "maxTextMessageSize": 65536 }
}
Health Check Endpoints
Enable with --health-check. With --health-check-secure, remote callers get minimal info only.
| Endpoint | Description |
|---|---|
/health |
Full JSON health info (status, uptime, JVM, memory) |
/health/ready |
Readiness probe — simple UP/DOWN |
/health/live |
Liveness probe — simple UP/DOWN |
{
"status": "UP",
"timestamp": "2025-08-01T17:05:47Z",
"uptime": "1m 47s",
"uptimeMs": 107245,
"version": "1.4.0",
"javaVersion": "17.0.2",
"memoryUsed": 152093696,
"memoryMax": 4294967296
}
Environment Files (.env)
The MiniServer auto-loads .env from the webroot at startup. Variables are added to Java System Properties and accessible via getSystemSetting():
# .env
DATABASE_URL=jdbc:mysql://localhost:3306/mydb
API_KEY=secret
DEBUG_MODE=true
// Works in both local (.env) and production (real env var)
var apiKey = getSystemSetting( "API_KEY" )
var dbUrl = getSystemSetting( "DATABASE_URL" )
Note: Use
getSystemSetting()rather thanserver.system.environment— it works for both.env(system properties) and real environment variables.
Warmup URLs
Pre-request URLs on startup to warm caches and connections before serving traffic:
{
"warmupURLs": [
"/api/warmup/database",
"/api/warmup/cache",
"/health/ready"
]
}
Warmup runs sequentially after server init. Failures are logged but do not abort startup.
Security Features
- Hidden file protection — any file or directory starting with
.returns404automatically and cannot be disabled .envfiles are blocked from HTTP access even whenhealthCheckis enabled- Health check endpoints never expose environment values
Undertow Tuning
| Setting | Default | Description |
|---|---|---|
undertow.ioThreads |
CPU count | I/O event threads |
undertow.workerThreads |
ioThreads * 8 |
Worker thread pool size |
undertow.bufferSize |
16384 | Buffer size in bytes |
socket.tcpNoDelay |
true |
Disable Nagle algorithm |
socket.reuseAddress |
true |
Allow address reuse on restart |
websocket.maxFrameSize |
65536 | Max WebSocket frame size |
websocket.maxTextMessageSize |
65536 | Max text message size |
Checklist
- Use
.boxlang.jsonin webroot for portable project-level config - Enable
--rewritesfor SPA or front-controller apps (routes toindex.bxm) - Use
getSystemSetting()to read env vars (works with both.envand real env vars) - Enable
--health-check --health-check-securefor container/load-balancer readiness probes - Add
warmupURLsfor production to pre-load DB connections and caches - Tune
undertow.workerThreadsbased on expected concurrency - Never rely on direct env var access for
.env-sourced values
More from ortus-boxlang/skills
boxlang-functional-programming
Use this skill when working with BoxLang lambdas, closures, arrow functions, higher-order functions, functional array/struct pipelines (map, filter, reduce, flatMap, groupBy, etc.), destructuring, or spread syntax.
10boxlang-code-reviewer
Use this skill when reviewing BoxLang code for quality, correctness, security vulnerabilities, performance issues, style violations, or when providing structured code review feedback following BoxLang best practices and security guidelines.
9boxlang-best-practices
Use this skill when writing, reviewing, or improving BoxLang code to ensure it follows community best practices for naming, structure, scoping, error handling, performance, and maintainability.
9boxlang-classes-and-oop
Use this skill when writing BoxLang classes, components, interfaces, inheritance hierarchies, annotations, properties, constructors, or applying object-oriented design patterns in BoxLang.
9boxlang-web-development
Use this skill when building BoxLang web applications: Application.bx lifecycle, request/response handling, sessions, forms, REST APIs, HTTP clients, routing, CSRF protection, Server-Sent Events, or configuring CommandBox/MiniServer.
8boxlang-configuration
Use this skill when configuring BoxLang runtime settings via boxlang.json, setting environment variables for config overrides, configuring datasources, caches, executors, modules, logging, security, or schedulers — or when helping someone understand the BoxLang configuration system.
8