๐Ÿ”ท Core

boxlang-runtime-cli-scripting

Use this skill when writing BoxLang CLI scripts and classes, handling command-line arguments, using the BoxLang REPL, running action commands (compile, cftranspile, featureaudit), detecting runtime context, and leveraging CLI-specific built-in functions.

$ npx skills add ortus-boxlang/skills/boxlang-developer/runtime-cli-scripting
$ coldbox ai skills install ortus-boxlang/skills/boxlang-developer/runtime-cli-scripting
๐Ÿ”— https://skills.boxlang.io/skills/raw/ortus-boxlang/skills/boxlang-developer~runtime-cli-scripting

BoxLang CLI Scripting

BoxLang is the AI-native software productivity platform for building, modernizing and running applications, with developers and AI agents working together.

Overview

The boxlang binary can run scripts, classes, templates, and inline code directly from the command line. It supports multiple file types, shebang lines, structured argument parsing, and a built-in REPL.


Supported File Types

ExtensionTypeEntry Point
.bxBoxLang classmain(args=[]) method
.bxsBoxLang scripttop-level code
.bxmBoxLang templatetop-level markup/code
.cfs / .cfmCFML (via bx-compat-cfml)top-level code
.shShell script with shebangshebang #!/usr/bin/env boxlang

Running Files

# Class with main() method
boxlang MyApp.bx

# Script file
boxlang process.bxs --config=prod.json --debug

# Template file
boxlang render.bxm

# Inline code
boxlang --bx-code "println( 'Hello!' )"

# From stdin
echo "println( 'piped!' )" | boxlang

# REPL (no arguments)
boxlang

Class Entry Point (main)

Use .bx files with a main() method for structured CLI applications:

class MyApp {
    static function main( args = [] ) {
        var parsed = CLIGetArgs()
        println( "Options: " & parsed.options.toString() )
        println( "Positionals: " & parsed.positionals.toString() )
    }
}

Argument Parsing

BoxLang parses CLI arguments automatically. Access them via CLIGetArgs() or server.cli.parsed:

// In a .bxs script
var args = CLIGetArgs()
// args = { options: { debug: true, config: "prod.json" }, positionals: [ "file.txt" ] }

var debug = args.options.debug ?: false
var config = args.options.config ?: "default.json"

Argument Formats

FormatParsed AsExample
--optionoptions.option = true--debug
--option=valueoptions.option = "value"--config=prod.json
--option="value"options.option = "value"--message="Hello"
-o=valueoptions.o = "value"-c=config.json
-ooptions.o = true-v
--!optionoptions.option = false--!verbose
--no-optionoptions.option = false--no-debug
-abca=true,b=true,c=true-vdx

Example

boxlang myscript.bxs --debug --!verbose --config=prod.json -o='/tmp/out' report.txt

Results in:

{
    "options": {
        "debug": true,
        "verbose": false,
        "config": "prod.json",
        "o": "/tmp/out"
    },
    "positionals": [ "report.txt" ]
}

Shebang Scripts

Make scripts directly executable with a shebang line:

#!/usr/bin/env boxlang
println( "I run directly!" )
var args = CLIGetArgs()
println( args.toString() )
chmod +x myscript.bxs
./myscript.bxs --name=World

CLI Built-In Functions

BIFReturnsDescription
CLIGetArgs()structParsed options + positionals
CLIRead( [prompt] )anyRead a line of input from stdin
CLIClear()voidClear the console screen
CLIExit( [exitCode=0] )โ€”Exit with given code (System.exit())
// Interactive prompt
var name = CLIRead( "Enter your name: " )
println( "Hello, " & name )

// Exit with error code
if ( !fileExists( configFile ) ) {
    println( "Error: config not found" )
    CLIExit( 1 )
}

CLI Flags

FlagEnv VariableDescription
--bx-debugBOXLANG_DEBUGEnable debug output
--bx-config <path>BOXLANG_CONFIGPath to boxlang.json config file. If omitted, a .boxlang.json in the current working directory is auto-discovered (v1.18+). The flag or env var always wins.
--bx-home <path>BOXLANG_HOMEOverride BoxLang home directory
--bx-code <code>โ€”Execute inline BoxLang code string
--bx-printASTBOXLANG_PRINTASTPrint the AST for the script
--bx-transpileBOXLANG_TRANSPILETranspile BoxLang to Java source
# Run with custom config and debug
boxlang --bx-debug --bx-config ./config/boxlang.json myapp.bxs

# Print the AST
boxlang --bx-printAST myscript.bxs

# Inline execution
boxlang --bx-code "println( now() )"

Action Commands

Run via boxlang <action> [options] โ€” these compile, convert, or audit code.

compile โ€” Compile to bytecode

boxlang compile --source ./src --target ./compiled

Options: --source <path>, --target <path>, --recurse true/false

cftranspile โ€” Transpile CFML to BoxLang

boxlang cftranspile --source ./legacy-cfml --target ./bx-src

Options: --source <path>, --target <path>, --recurse true/false

featureaudit โ€” Audit CFML compatibility

boxlang featureaudit --source ./legacy-cfml

Reports unsupported or incompatible CFML patterns.

schedule โ€” Run a scheduler file

boxlang schedule ./schedulers/MainScheduler.bx

Runs continuously until Ctrl+C. File must be a .bx class with scheduler definitions.

Since v1.18, run with no arguments to print a report of scheduling configuration, loaded schedulers and their tasks, and persisted tasks. Add --json for a machine-readable document (credentials are stripped), ideal for jq, scripts and AI agents:

boxlang schedule
boxlang schedule --json | jq '.tasks'

Runtime Detection

Detect the execution context in BoxLang code:

// CLI mode vs web server vs JAR mode
if ( server.boxlang.cliMode ) {
    println( "Running in CLI mode" )
} else if ( server.boxlang.jarMode ) {
    println( "Running as embedded JAR" )
}

// Access parsed CLI arguments
var parsed = server.cli.parsed
// { options: {}, positionals: [] }

// Runtime info
println( server.boxlang.runtimeHome )
println( server.coldfusion.productVersion )  // BoxLang version

Available Scopes in CLI Mode

ScopeDescription
applicationApplication-level shared state
requestCurrent request/execution context
serverServer/runtime information
server.cliCLI-specific runtime metadata
server.cli.parsedEquivalent to CLIGetArgs() return

REPL Mode

Start with no arguments for an interactive session:

boxlang
# BoxLang> println( "Hello!" )
# Hello!
# BoxLang> 1 + 1
# 2
# BoxLang> :history    (show history)
# BoxLang> :clear      (clear screen)
# BoxLang> Ctrl+C      (exit)
  • Supports multi-line input (continues on unbalanced braces)
  • !! repeats last command; !n repeats command n
  • :dark / :light switch color themes

Example Script Patterns

Script with validation

// validate-args.bxs
var args = CLIGetArgs()

if ( args.positionals.isEmpty() ) {
    println( "Usage: boxlang validate-args.bxs <filename> [--verbose]" )
    CLIExit( 1 )
}

var file = args.positionals[1]
var verbose = args.options.verbose ?: false

if ( !fileExists( file ) ) {
    println( "Error: File not found: " & file )
    CLIExit( 2 )
}

println( "Processing: " & file )

Class with structured main

// DataProcessor.bx
class DataProcessor {
    static function main( args = [] ) {
        var opts = CLIGetArgs().options
        var inputFile  = opts.input  ?: throw( "--input is required" )
        var outputFile = opts.output ?: "output.json"
        var debug      = opts.debug  ?: false

        if ( debug ) println( "Input:  " & inputFile )
        if ( debug ) println( "Output: " & outputFile )

        // process...
    }
}

Checklist

  •  Use CLIGetArgs() for all argument access (not raw args array)
  •  Validate required arguments and call CLIExit( 1 ) on error
  •  Use --bx-config / BOXLANG_CONFIG (or a project .boxlang.json, v1.18+) to separate config from code
  •  Use server.boxlang.cliMode for runtime-aware conditional logic
  •  Prefer .bx classes with main() for reusable, testable entry points
  •  Use #!/usr/bin/env boxlang shebang for directly executable scripts
  •  Use CLIRead() for interactive prompts; CLIClear() for UI scripts