boxlang-configuration — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited boxlang-configuration (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
BoxLang's runtime is configured through boxlang.json. The file is auto-created in the BoxLang home directory on first startup. All settings can be overridden via environment variables or Java system properties without modifying the file.
When configuration questions involve app-specific behavior in Application.bx (this.name, lifecycle callbacks, per-app schedulers/watchers, nested app isolation), pair this with the application-descriptor skill.
| Runtime | Default Location |
|---|---|
| OS / CLI / MiniServer | ~/.boxlang/config/boxlang.json |
| AWS Lambda | {lambdaRoot}/boxlang.json |
| Google Cloud Functions | {gcfRoot}/boxlang.json |
| CommandBox | ~/.commandbox/servers/{home}/WEB-INF/boxlang/config/boxlang.json |
Override the home directory at startup:
boxlang --home /path/to/custom-homeAny setting can be overridden via environment variable or JVM property using the BOXLANG_ prefix (snake_case) or boxlang. prefix (dot-notation):
# Enable debug mode
BOXLANG_DEBUGMODE=true
# Set log level for runtime logger
boxlang.logging.loggers.runtime.level=TRACE
# Set as JVM argument
java -Dboxlang.debugMode=true -jar boxlang.jarJSON values are supported for complex overrides:
BOXLANG_DATASOURCES='{"mainDB":{"driver":"postgresql","host":"db.example.com"}}'Use ${env.VAR:default} inside boxlang.json to reference env vars:
{
"datasources": {
"mainDB": {
"driver": "postgresql",
"host": "${env.DB_HOST:localhost}",
"port": "${env.DB_PORT:5432}",
"database": "${env.DB_NAME:myapp}",
"username": "${env.DB_USER:app}",
"password": "${env.DB_PASSWORD}"
}
}
}Built-in path substitution variables:
| Variable | Resolves to |
|---|---|
${boxlang-home} | BoxLang home directory |
${user-home} | OS user home directory |
${user-dir} | Current working directory |
${java-temp} | Java temp directory |
{
// Compiled class output directory
"classGenerationDirectory": "${boxlang-home}/classes",
// Compiler backend: "asm" (default, best performance) or "java"
"compiler": "asm",
// Store compiled classes on disk (recommended: true for production)
"storeClassFilesOnDisk": true,
// Never re-check class files (recommended: true for production)
"trustedCache": false,
// Cache class resolver lookups (recommended: true)
"classResolverCache": true,
// Clear class files on startup (use only for debugging)
"clearClassFilesOnStartup": false,
// Global class paths (.bx file discovery)
"classPaths": [
"${boxlang-home}/global/classes"
],
// Custom component directories
"customComponentsDirectory": [
"${boxlang-home}/global/components"
],
// Default datasource name
"defaultDatasource": "",
// Max completed threads tracked per request
"maxTrackedCompletedThreads": 1000,
// Enable debug output in responses
"debugMode": false
}{
"datasources": {
"mainDB": {
"driver": "postgresql",
"host": "${env.DB_HOST:localhost}",
"port": 5432,
"database": "myapp",
"username": "${env.DB_USER:app}",
"password": "${env.DB_PASSWORD}"
},
"legacyMySQL": {
"driver": "mysql",
"host": "db2.internal",
"port": 3306,
"database": "legacy",
"username": "${env.MYSQL_USER}",
"password": "${env.MYSQL_PASS}",
// Connection pool settings
"connectionTimeout": 30,
"maximumPoolSize": 10,
"minimumIdle": 2
}
}
}Supported drivers: postgresql, mysql, mssql, oracle, derby, h2, sqlite.
{
"caches": {
// Default cache (used when no cache name specified)
"default": {
"provider": "BoxCacheProvider",
"properties": {
"maxObjects": 1000,
"defaultTimeout": 60,
"defaultLastAccessTimeout": 0,
"objectStore": "ConcurrentStore"
}
},
// Named cache for templates
"templates": {
"provider": "BoxCacheProvider",
"properties": {
"maxObjects": 500,
"defaultTimeout": 120
}
}
}
}{
"executors": {
// Default executor for runAsync() — virtual threads
"boxlang-tasks": {
"type": "virtual",
"coreThreads": 20
},
// CPU-bound work pool
"cpu-work": {
"type": "fixed",
"coreThreads": 8
},
// Elastic pool for bursty I/O
"io-tasks": {
"type": "cached"
},
// Scheduler pool
"scheduler": {
"type": "scheduled",
"coreThreads": 5
}
}
}Executor types: virtual (default, Project Loom), fixed, cached, scheduled, work_stealing.
{
"logging": {
"logsDirectory": "${boxlang-home}/logs",
"level": "WARN", // Global default: TRACE, DEBUG, INFO, WARN, ERROR
"loggers": {
"runtime": { "level": "INFO" },
"scheduler": { "level": "INFO", "async": true },
"datasource": { "level": "WARN" },
"cache": { "level": "WARN" },
"modules": { "level": "INFO" }
}
}
}{
"security": {
// Regex patterns for blocked Java class imports
"disallowedImports": [],
// Blocked BIF names
"disallowedBifs": [],
// Blocked component names
"disallowedComponents": [],
// Whether Java system props/env are in server.system scope
"populateServerSystemScope": true,
// Explicit upload extension whitelist (overrides disallowed list)
"allowedFileOperationExtensions": [],
// Blocked file upload/move extensions
"disallowedFileOperationExtensions": []
}
}Configure modules loaded at startup and module-specific settings:
{
"modules": {
// Modules to load on startup (in addition to auto-discovered modules)
"load": [ "bx-compat-cfml", "bx-orm" ],
// Modules to skip loading even if present
"exclude": [],
// Per-module settings
"settings": {
"bx-orm": {
"autoManageSession": true,
"dialect": "PostgreSQLDialect"
}
}
}
}{
"scheduler": {
// Default task timeout (0 = no timeout)
"defaultTimeout": 0,
// How long to wait for scheduled tasks to complete on shutdown
"shutdownTimeout": 30,
// Executor to use for scheduled tasks
"executor": "scheduler"
}
}Configure the built-in WatcherService for filesystem monitoring. Watchers react to file/directory changes and can trigger hot-reload, asset builds, or custom automation.
{
"watcher": {
// Recurse into subdirectories by default
"recursive": true,
// Hold events until no new event arrives within this window (ms); 0 = off
"debounce": 300,
// Emit at most one event per window and drop the rest (ms); 0 = off
"throttle": 0,
// Suppress noisy intermediate events from atomic save patterns (temp + rename)
"atomicWrites": true,
// Startup delay before watchers begin processing events (ms)
"delay": 0,
// Auto-stop watcher after this many consecutive listener errors (0 = disabled)
"errorThreshold": 10,
// Named watcher definitions auto-started at runtime startup
"definitions": {
"hot-reload": {
"paths": "${user-dir}/src",
"listener": "app.listeners.HotReloadListener"
},
"assets": {
"paths": [ "${user-dir}/resources/css", "${user-dir}/resources/js" ],
"recursive": false,
"throttle": 500,
"listener": "app.listeners.AssetPipelineListener"
}
}
}
}| Property | Required | Description |
|---|---|---|
paths | Yes | Directory path or array of paths to watch |
listener | Yes | BoxLang class path with listener behavior |
recursive | No | Override global recursive setting |
debounce | No | Per-watcher debounce override (ms) |
throttle | No | Per-watcher throttle override (ms) |
atomicWrites | No | Per-watcher atomic write filtering override |
delay | No | Per-watcher startup delay override (ms) |
errorThreshold | No | Per-watcher error threshold override |
For closures and struct-based listeners, create watchers programmatically withwatcherNew()at runtime instead of inboxlang.json.
watcherNew(), watcherStart(), watcherStop(), watcherRestart(), watcherList(), watcherGet(), watcherExists(), watcherShutdown(), watcherStopAll(), watcherShutdownAll()
Feature flags for in-progress BoxLang capabilities. These settings may change or be removed.
{
"experimental": {
// Compiler backend: "asm" (default, direct bytecode) or "java" (transpile to Java first)
"compiler": "asm",
// Capture AST JSON to /grapher/data on each parse (for tooling/debugging only)
"ASTCapture": false
}
}| Flag | Default | Description |
|---|---|---|
compiler | "asm" | "asm" compiles directly to bytecode (production default); "java" transpiles to Java source first |
ASTCapture | false | Writes AST JSON to /grapher/data on every parse — for tooling and debugging only, never production |
Application.bx)Application-level settings override the runtime config for a specific app:
class {
// Application identity
this.name = "MyApp"
this.sessionManagement = true
this.sessionTimeout = createTimeSpan( 0, 2, 0, 0 )
// Datasource
this.datasource = "mainDB"
// Per-application datasource definition
this.datasources = {
localDB: {
driver: "h2",
database: expandPath( "/db/local.h2" )
}
}
// Java library paths
this.javaSettings = {
loadPaths: [ expandPath( "/lib/" ) ]
}
// Cache mappings
this.caches = {
objects: { provider: "BoxCacheProvider" }
}
// Directory mappings
this.mappings = {
"/models": expandPath( "/app/models/" ),
"/services": expandPath( "/app/services/" )
}
}trustedCache: true — no disk checks on every requestclassResolverCache: true — cached class resolutiondebugMode: false — no debug output to responseslogging.level: "WARN" — suppress verbose logs${env.VAR} — never hardcoded in boxlang.jsonclassGenerationDirectory on a fast disk (SSD/tmpfs)security.populateServerSystemScope: false if system env not needed~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.