Running Modules
Modules are reusable CFML commands that live under your LuCLI home directory and can be run like first‑class commands.
Module Components
By convention a module is:
- A directory under
~/.lucli/modules/<module-name>/ - With an entrypoint
Module.cfc(usuallycomponent extends="modules.BaseModule") - Optionally a
module.jsonmetadata file andREADME.md
You normally create this structure with:
lucli modules init my-awesome-module
# edits files under ~/.lucli/modules/my-awesome-module/
Once created, modules can be listed, installed, updated and removed via the modules commands (see Module Management below).
Module Commands
Modules let you package CFML into named commands you can run with either the explicit modules run syntax or handy shortcuts.
Full syntax
lucli modules run <module-name> [arguments...]
This works in both one‑shot CLI mode and the interactive terminal.
Shortcut syntax
lucli <module-name> [arguments...]
The shortcut form is equivalent to:
lucli modules run <module-name> [arguments...]
so you can think of lucli <module-name> as sugar for lucli modules run <module-name>.
Examples
Full syntax
lucli modules run hello-world
lucli modules run cfformat file1.cfs file2.cfs
Shortcut syntax (equivalent)
lucli hello-world
lucli cfformat file1.cfs file2.cfs
With global flags
lucli --verbose test-module arg1 arg2
lucli --debug midnight
(Global flags like --verbose, --debug, --timing are handled by LuCLI itself before your module runs.)
Passing arguments to modules
Under the hood, LuCLI normalizes module arguments into a subcommand plus a named argument collection.
Subcommands
If the first argument does not contain = and does not start with - or --, it is treated as a subcommand name; otherwise the subcommand defaults to main.
# Calls main()
lucli my-module
# Calls cleanup() subcommand inside Module.cfc
lucli my-module cleanup
# Subcommand with additional arguments
lucli my-module cleanup target=/tmp keepDays=7
Inside your module this is exposed as the subCommand variable and you can implement matching functions like function main(), function cleanup(), etc.
Positional arguments
Any argument that doesn’t contain = after the (optional) subcommand is treated as a positional value:
lucli my-module arg1 arg2 arg3
These are made available as arg1, arg2, arg3, … in the argument collection, so your CFML can access them via the arguments struct or the argCollection map.
Named arguments: arg=1 vs --arg
Named arguments are passed with key=value syntax. LuCLI also understands flag-style arguments and normalizes them for you:
# Plain key=value
lucli reports generate year=2025 format=csv
# Long flags with values (equivalent to the above)
lucli reports generate --year=2025 --format=csv
# Boolean flags
lucli my-module --force # force=true
lucli my-module --no-force # force=false
Rules:
arg=1→ keyarg, value"1"--arg=1or-a=1→ keyarg, value"1"--arg→ keyarg, value"true"--no-arg→ keyarg, value"false"- bare values (no
=) after the subcommand becomearg1,arg2, …
Inside your Module.cfc, these end up as normal CFML arguments. For example:
function main(required string year, string format="json", boolean force=false) {
// year, format, force populated from CLI
}
will be populated by any of the CLI forms shown above (year=2025, --year=2025, --force, etc.).
Module Management
# List available modules (installed under ~/.lucli/modules)
lucli modules list
# Create a new module from the template
lucli modules init my-awesome-module
# Install from a git/HTTP URL or known repository entry
lucli modules install my-awesome-module --url=https://github.com/example/my-awesome-module.git
# Update or uninstall a module
lucli modules update my-awesome-module
lucli modules uninstall my-awesome-module
# Get detailed help
lucli modules --help
How Shortcuts Work
When you run an unrecognized command, LuCLI uses smart detection:
- First, it checks if it's a known built‑in subcommand (like
server,modules,terminal). - Next, it checks if it's an existing CFML file (
.cfs,.cfm,.cfc). - Then it tries to run it as a module shortcut (looking under
~/.lucli/modules/<name>/Module.cfc). - If nothing matches, it shows you what’s available.
This means you can just type lucli hello-world instead of the longer lucli modules run hello-world—the shortcut form is usually what you’ll use day‑to‑day.