For the complete documentation index, see llms.txt. This page is also available as Markdown.

BoxLang Formatter

Format BoxLang and CFML code with deterministic, team-wide style enforcement and CI-ready check mode

The BoxLang Formatter is the canonical tool for enforcing consistent code style across BoxLang and CFML codebases.

Use this page as your one-stop technical reference for:

  • local formatting workflows

  • lint-like enforcement in CI/CD pipelines

  • formatter configuration precedence

  • cfformat migration and conversion strategy

🚀 Command Overview

The formatter is exposed as a BoxLang action command:

boxlang format [OPTIONS]

This command routes through the BoxLang runtime action pipeline, so it can be used consistently in local development, pre-commit checks, and CI runners.

Supported File Types

The formatter can process these extensions:

  • .bx

  • .bxs

  • .bxm

  • .cfm

  • .cfc

  • .cfs

📋 CLI Options

BoxLang v1.14+ — The --source flag now accepts a comma-delimited list of paths, and the new --excludes flag lets you skip specific files or directories during formatting.

Use boxlang format --help to view the complete option set available in your installed version.

Option
Description
Typical Usage

-h, --help

Show formatter help and exit

boxlang format --help

--source <PATH[,PATH,...]>

Comma-delimited list of files or directories to process (BoxLang v1.14+). Defaults to current directory if omitted

boxlang format --source ./src or boxlang format --source commands,models,services

--excludes <PATH[,PATH,...]>

Comma-delimited list of files or directories to skip (BoxLang v1.14+)

boxlang format --source . --excludes generated,vendor

--target <PATH>

Output path (optional). If omitted, source files are overwritten. Must be a directory when processing multiple source files

boxlang format --source ./src --target ./formatted

--check

Check-only mode; exits non-zero when formatting drift exists

boxlang format --check

--overwrite <BOOL>

When false, write formatted output to stdout instead of rewriting files

boxlang format --overwrite false --source ./models/User.cfc

-c, --config <PATH>

Explicit .bxformat.json or .cfformat.json path

boxlang format --config ./.bxformat.json --source ./

--initConfig

Create starter formatter config in current workspace

boxlang format --initConfig

--convertConfig

Convert legacy .cfformat.json into .bxformat.json

boxlang format --convertConfig

Behavior Notes

  • Directory formatting processes supported files recursively

  • --source defaults to the current directory when omitted

  • --target must be a directory when multiple source files are being processed

  • Missing or unset configuration falls back to built-in default formatter settings

🧪 Core Workflows

Format In Place (Default Directory)

This is the simplest invocation — it processes all supported files in the current directory and its subdirectories using the default settings.

Format In Place (Explicit Path)

Use this when you want to be explicit about the source path, or when formatting a different directory.

Format a Single File

Useful for editor tasks, pre-commit hooks, and targeted refactors.

This is useful when integrating with custom tooling that captures formatter output.

CI Gate / Lint-Style Enforcement

In --check mode, the command behaves as a lint-style quality gate:

  • exits successfully when all files already match formatter rules

  • exits non-zero when any file requires formatting

This allows direct integration with CI jobs that should fail on style drift.

🚫 Ignore Comments

BoxLang v1.14+ — Three styles of formatter-ignore comments are supported, matching the most popular conventions from the CFML and wider ecosystems.

When the formatter encounters an ignore directive, it emits the enclosed code exactly as written — no reformatting, no re-indentation, no quote normalization.

@formatter:off / @formatter:on

The universal formatter directive, recognized by many language tooling ecosystems:

bxformat-ignore-start / bxformat-ignore-end

BoxLang-native ignore markers:

cfformat-ignore-start / cfformat-ignore-end

Legacy cfformat compatibility — existing ignore blocks from cfformat projects work out of the box:

How Ignore Blocks Work

  • The start marker must appear as a comment on the line immediately before the code to skip

  • The end marker must appear as a comment on the line immediately after the code to skip

  • Everything between the markers — including indentation, spacing, and quote style — is preserved verbatim

  • Ignore blocks can span multiple statements, not just single lines

  • Nested ignore blocks are not supported; the first start marker opens the region and the first end marker closes it

⚙️ Configuration Model

The formatter auto-discovers configuration using this precedence order:

  1. .bxformat.json

  2. .cfformat.json (converted into formatter config model)

  3. built-in defaults

This design gives teams a safe migration path:

  • BoxLang-native projects can adopt .bxformat.json

  • mixed/legacy projects can continue using .cfformat.json while migrating incrementally

Bootstrap New Config

Use this to generate a baseline .bxformat.json in your workspace.

🧾 Full Rules Reference (.bxformat.json)

This section lists all currently supported formatter configuration keys and how to configure them.

Some keys may not appear in the generated --initConfig scaffold but are still supported by the formatter config model.

Root-Level Rules

Key
Type
Default
Allowed / Notes

indentSize

number

4

Indentation width unit

tabIndent

boolean

true

Use tabs instead of spaces

maxLineLength

number

115

Line length target for wrapping decisions

newLine

string

"\n"

"os", "\n", "\r\n"

singleQuote

boolean

false

Prefer single quotes for strings/keys

preserveStringQuotes

boolean

false

Preserve original quote style in source

alignConsecutiveAssignments

boolean

true

Vertical align for consecutive assignment-like separators

alignConsecutiveProperties

boolean

true

Vertical align for consecutive property declarations

bracketPadding

boolean

true

Global default for array bracket padding

parensPadding

boolean

true

Global default for parentheses padding

binaryOperatorsPadding

boolean

true

Spaces around binary operators

semicolons

boolean

true

Append semicolons where applicable

cfFormatCompatibility

boolean

false

Internal compatibility mode (normally set by cfformat conversion path)

sourceType

string/null

null

BOXSCRIPT, BOXTEMPLATE, CFSCRIPT, CFTEMPLATE; null = auto-detect

struct Rules

Key
Type
Default
Allowed / Notes

struct.padding

boolean

true

Spaces/newlines inside non-empty struct braces

struct.empty_padding

boolean

false

Space in empty structs/ordered markers

struct.quote_keys

boolean

false

Force quoting of struct keys

struct.separator

string

" : "

":", "=", ": ", " : ", "= ", " = "

struct.multiline.element_count

number

2

Break threshold by number of entries

struct.multiline.comma_dangle

boolean

false

Trailing comma when multiline

struct.multiline.leading_comma.enabled

boolean

false

Leading comma style

struct.multiline.leading_comma.padding

boolean

true

Space after leading comma

struct.multiline.min_length

number

60

Break threshold by flattened text length

array Rules

Key
Type
Default
Allowed / Notes

array.padding

boolean

true

Spaces/newlines inside non-empty array brackets

array.empty_padding

boolean

false

Space in empty arrays

array.multiline.element_count

number

2

Break threshold by number of elements

array.multiline.comma_dangle

boolean

false

Trailing comma when multiline

array.multiline.leading_comma.enabled

boolean

false

Leading comma style

array.multiline.leading_comma.padding

boolean

true

Space after leading comma

array.multiline.min_length

number

50

Break threshold by flattened text length

property Rules

Key
Type
Default
Allowed / Notes

property.multiline.element_count

number

3

Break threshold by number of attributes

property.multiline.comma_dangle

boolean

false

Trailing comma in multiline attribute lists

property.multiline.leading_comma.enabled

boolean

false

Leading comma style

property.multiline.leading_comma.padding

boolean

true

Space after leading comma

property.multiline.min_length

number

30

Break threshold by flattened text length

property.key_value.padding

boolean

false

Spaces around = in property attributes

for_loop_semicolons Rules

Key
Type
Default
Allowed / Notes

for_loop_semicolons.padding

boolean

true

Space after ; in for ( ;; ) header

function Rules

Key
Type
Default
Allowed / Notes

function.style

string

"preserve"

Currently preserve-first style control

function.parameters.padding

boolean

true

Spaces in non-empty parameter list

function.parameters.empty_padding

boolean

false

Space in empty parameter list

function.parameters.comma_dangle

boolean

false

Trailing comma in multiline parameters

function.parameters.multiline_count

number

3

Break threshold by parameter count

function.parameters.multiline_length

number

50

Break threshold by flattened length

function.arrow.parens

string

"always"

"always" or "avoid"

arguments Rules

Key
Type
Default
Allowed / Notes

arguments.padding

boolean

true

Spaces in non-empty call argument lists

arguments.empty_padding

boolean

false

Space in empty argument lists

arguments.comma_dangle

boolean

false

Trailing comma in multiline arguments

arguments.multiline_count

number

3

Break threshold by argument count

arguments.multiline_length

number

50

Break threshold by flattened length

arguments.separator

string

" = "

"=" or ":"

braces Rules

Key
Type
Default
Allowed / Notes

braces.style

string

"same-line"

"same-line", "new-line", "preserve"

braces.require_for_single_statement

boolean

true

Require braces for single statement control blocks

braces.else.style

string

"same-line"

"same-line" or "new-line"

operators Rules

Key
Type
Default
Allowed / Notes

operators.position

string

"end"

Binary operator position on wrapped expressions: "end" or "start"

operators.comparison_style

string

"symbols"

"symbols", "keywords", or "preserve"

operators.ternary.style

string

"flat"

"flat", "always-multiline", or "preserve"

operators.ternary.question_position

string

"start"

"start" or "end"

chain Rules

Key
Type
Default
Allowed / Notes

chain.break_count

number

3

Break chain when call count reaches threshold

chain.break_length

number

60

Break chain when flattened length reaches threshold

template Rules

BoxLang v1.14+ — The template.enabled flag gates template (.bxm / .cfm) formatting. It defaults to false until template formatting exits experimental mode. Set it to true to enable.

Key
Type
Default
Allowed / Notes

template.enabled

boolean

false

Enable/disable template (.bxm / .cfm) formatting (BoxLang v1.14+)

template.component_prefix

string

"bx"

Commonly "bx" or "cf"

template.indent_content

boolean

true

Indent tag body content

template.single_attribute_per_line

boolean

false

One attribute per line in tags

template.self_closing

boolean

true

Use /> for self-closing tags

import Rules

Key
Type
Default
Allowed / Notes

import.sort

boolean

false

Sort imports alphabetically

import.group

boolean

false

Group imports by package with blank lines

comments Rules

Key
Type
Default
Allowed / Notes

comments.preserve_blank_lines

boolean

true

Keep blank lines around comments

comments.wrap

boolean

false

Wrap long comments based on maxLineLength

class Rules

BoxLang v1.14+ — The class.property_spacing rule controls blank lines between property declarations in class bodies. Default is 1 (single blank line), matching Ortus coding standards.

Key
Type
Default
Allowed / Notes

class.member_order

string

"preserve"

Member ordering strategy

class.member_spacing

number

1

Blank lines between members

class.property_order

string

"preserve"

"preserve", "alphabetical", "length", "type"

class.property_spacing

number

1

Blank lines between property declarations (BoxLang v1.14+)

class.method_order

string

"preserve"

"preserve" or "alphabetical"

class.method_grouping

boolean

false

Group methods by modifier/type before ordering

sql Rules

Key
Type
Default
Allowed / Notes

sql.uppercase_keywords

boolean

true

Uppercase SQL keywords

sql.indent_clauses

boolean

true

Indent SQL clauses in query blocks

🛠️ Configuration Examples

Minimal Starter

Strict CI-Friendly Layout

🔄 Migration from cfformat

If your team currently relies on cfformat conventions, migrate with a controlled two-phase approach.

Phase 1: Convert Existing Config

This creates a BoxLang formatter config from legacy cfformat configuration so existing style intent is preserved as much as possible.

Phase 2: Validate with Check Mode

Run this in CI to detect any unexpected drift while your team validates behavior.

  1. Convert config using --convertConfig.

  2. Run formatter once in a dedicated normalization commit.

  3. Enable --check in CI to prevent future drift.

  4. Refine .bxformat.json as project standards evolve.

Compatibility mode for .cfformat.json is designed for migration safety. For long-term BoxLang-first teams, prefer .bxformat.json as the canonical source of formatting policy.

🧷 CI/CD Integration Patterns

Minimal CI Step

  1. Developers run boxlang format --source ./ before pushing changes.

  2. CI enforces boxlang format --check --source ./.

  3. Pull requests that fail check mode must be reformatted before merge.

This gives deterministic formatting without requiring a separate linter for stylistic concerns.

🧠 IDE Auto-Formatting (VS Code / BoxLang IDE)

For editor-on-save workflows and IDE formatter setup, the BoxLang LSP supports experimental formatting. Because this feature is still in beta, you need to explicitly enable it with a few steps.

Enabling Experimental Formatting in VS Code

1

Enable formatting in .bxlint.json

Add the following to your project's .bxlint.json:

2

Enable format-on-save in VS Code

Add this override to your VS Code settings.json (Workspace or User):

3

Update BoxLang & LSP versions

Open the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and run:

  • BoxLang: Select BoxLang Version — choose the latest available version

  • BoxLang: Select LSP Version — choose the latest available version

  • Developer: Reload Window — to pick up the changes

Once these steps are completed, the formatter will run automatically when you save .bx, .bxs, .bxm, .cfc, .cfm, or .cfs files.

  • IDE format-on-save for fast local feedback

  • CLI --check mode for authoritative CI enforcement

🧩 Complete .bxformat.json Schema Template

Copy this file to your project root as .bxformat.json and remove or adjust only the keys you want to override. All values shown are the Ortus gold-standard defaults.

Run boxlang format --initConfig to generate this file automatically in your current directory instead of copy-pasting.

Last updated

Was this helpful?