CFML Keywords
CFML Keywords
Editors, syntax highlighters, linters and other tooling often need a list of the CFML keywords. This recipe lists what the Lucee compiler itself handles, grouped by purpose.
CFML has no single "reserved words" table. The keywords come from three different places in the compiler:
- Hard coded in the expression and script parsers. These are the operators, literals, scopes, modifiers and statements (
if,for,returnand so on). - Data driven by the tag definitions (TLD files). Every tag that can be used in script, like
abort,breakorlock, is declared there. Extensions add more tags, so this part is open ended. - Data driven by the function definitions (FLD files). The built-in functions are not keywords, they are only names in the function library. Use the runtime lookups below for both lists.
The groups below only contain what the compiler handles. Where something is not a compiler keyword but is often mistaken for one, that is noted.
All keywords are case-insensitive.
Statements without arguments
These can be written in script as a single word followed by a semicolon.
| Keyword | Notes |
|---|---|
return |
Hard coded in the script parser. With or without an expression. |
break |
Defined as a tag with the script type single. Takes an optional label. |
continue |
Defined as a tag with the script type single. Takes an optional label. |
abort |
Defined as a tag with the script type single. |
exit |
Defined as a tag with the script type single. |
rethrow |
Defined as a tag with the script type single. |
retry |
Defined as a tag with the script type single. |
silent |
Defined as a tag with the script type single. |
return is the only one of these built into the script parser itself. The others are ordinary tags that happen to need no attributes. See <cfscript> for how tags are written in script.
Control flow
Hard coded in the script parser:
if, else if, else, switch, case, default, for, in (inside for ( x in y )), while, do ... while, try, catch, finally
Notes:
else ifis written as two words in script.elseifexists only as a tag.caseanddefaultonly have meaning inside aswitchbody.catch ( type name )takes an exception type and a variable name. The type, likeany, is not a keyword.breakandcontinue(see above) are used inside loops andswitch.
Declarations
| Keyword | Where | Notes |
|---|---|---|
component |
script and tag | Starts a component. Can be preceded by abstract or final. |
interface |
script and tag | Starts an interface. |
function |
script and tag | Named functions, and closures when used as an expression. |
property |
inside components | Declares a component property. |
param |
script and tag | Declares a variable with a default value. |
import |
script and tag | Imports a component or Java package for the current file. |
static |
inside components | static { } block, and also a function modifier. |
var |
inside functions | Declares a local variable. It is handled as a scope (see below). |
Arrow functions (=>) are written with the same rules as function, they only have a shorter body syntax.
extends, implements, output, persistent and similar words are attributes of component and interface, not keywords of their own.
Modifiers
| Keyword | Applies to | Source of truth |
|---|---|---|
public, private, package, remote |
functions, and variables inside components (remote is only valid on functions) |
access modifiers |
abstract, final |
components and functions | component modifier |
final |
variables inside components, arguments | variable modifier |
static |
functions | static function |
required |
arguments | argument modifier |
Creating objects
| Keyword | Notes |
|---|---|
new |
new Foo() and new java:java.util.ArrayList(). Only recognised when followed by a component path and (. |
java:, class: |
Prefix that selects a Java class, for example new java:java.lang.StringBuilder(). |
cfml:, cfc: |
Prefix that selects a CFML component, for example new cfc:Foo(). |
:: |
Static scope access, for example Foo::bar() or super::bar(). |
Use new and the :: operator in new code. The createObject() function is not needed for any of this.
Literals
| Keyword | Notes |
|---|---|
true, false |
Boolean literals. |
null |
The null literal. Not treated as a literal when followed by . or [, so null.foo is a variable access. |
yes and no are not literals in the expression parser. They are only converted to booleans when they are cast, for example when used as an attribute value.
Word operators
These are written as words instead of symbols. Several have more than one spelling.
| Operator | Spellings |
|---|---|
| Logical | and, or, not, xor, eqv, imp |
| Equality | eq, equal, is |
| Inequality | neq, not equal, is not |
| Comparison | gt, greater than, gte, ge, greater than or equal to, lt, less than, lte, le, less than or equal to |
| String search | contains, ct, does not contain, nct |
| Math | mod, exp |
The symbol operators (&&, ||, ==, !=, <, >, +, -, *, /, %, ^, \, &, ?:, ?., ++, --, +=, -= and so on) are not keywords, so they are not listed here.
Scopes
The expression parser treats these names specially when they start a variable:
var, local, variables, arguments, request, server, thread, cgi, url, form, session, application, client, cookie
this and static are handled separately when the variable is compiled, and super is handled in super::.
A few scopes are only recognised when the compiler is not told to ignore scopes (cgi, url, form, session, application, client, cookie). Names that exist as scopes at runtime but are not in the list above, such as caller, are not matched by the expression parser's scope handling.
Tags in script
Any tag that is flagged for script use in its tag definition can be written without angle brackets. Each such tag is flagged as one of:
single, a statement with attributes, for exampleabort,include,throw,sleep,importmultiple, a statement with named attributes and an optional body, for examplelock,loop,query,transaction,thread,http,file,componentnone, tag only, no script form
There is also the generic prefix form cfname( attr=value ); which works for any core tag with a script definition.
A plain cf tag name like cfloop is not a keyword in script. The list of script capable tags depends on the installed extensions, so it should be read at runtime and not copied into an editor definition.
Use the runtime lookups below to get the authoritative list for the engine you are talking to.
Getting tag and function lists at runtime
The built-in functions and tags are not hard coded in the compiler. They are loaded from definition files, and extensions can add more. These functions expose the same data the compiler uses.
| Function | Returns |
|---|---|
| GetTagList() | Struct with one key per tag library. Each value is a struct whose keys are the tag names. Hidden and unimplemented tags are skipped. |
| GetTagData() | Details for one tag, such as attributes, body type, description and script ( type, rtexpr ). |
| GetFunctionList() | Struct whose keys are the function names. Hidden and unimplemented functions are skipped. |
| GetFunctionData() | Details for one function, such as arguments, return type, description and status. |
<cfscript>
// every tag in the core tag library, which flags are set for script use
tags = getTagList();
for ( name in structKeyArray( tags.cf ) ) {
data = getTagData( "cf", name );
if ( data.script.type != "none" ) {
systemOutput( name & " : " & data.script.type, true );
}
}
// every function name
functionNames = structKeyArray( getFunctionList() );
// everything about one function
systemOutput( getFunctionData( "arrayAppend" ), true );
</cfscript>
What about getFunctionKeywords()?
GetFunctionKeywords() is not a list of reserved words. It returns the search keywords that the function definitions are tagged with, and is meant for finding functions by topic. Do not use it to get keywords for syntax highlighting.
Version information
The tag and function definitions can carry an introduced value, which getTagData() and getFunctionData() return when it is set. That field is only filled in for some items, so it can not be used to tell when every tag or function was added. If a key introduced is missing, it means the information was not recorded, it does not mean the item has always existed.
The same applies to the compiler keywords on this page. There is no version metadata for them.
Lucee MCP service
Lucee runs a public MCP service at https://mcp.lucee-services.com/ that gives AI tools and scripts the same function and tag definitions, full-text search over the documentation, and CFML AST parsing. The tools are get_lucee_function, get_lucee_tag, search_lucee_docs, parse_cfml_ast and query_cfml_ast. See Model Context Protocol (MCP) for how to connect a client.
AST functions
If a tool needs to understand the structure of CFML code and not only list its keywords, the compiler can produce an AST for it:
- astFromPath() parses a file.
- astFromString() parses a string, as tag or script code.
See AST (Abstract Syntax Tree) for the node types, and Language Server Protocol (LSP) for Lucee for how editors can use that.
Configuration schema and environment variables
The Lucee build publishes machine-readable descriptions of the server configuration next to the main org.lucee:lucee artifact on Maven Central:
| File | Content |
|---|---|
lucee-<version>-config-schema.json |
JSON schema for the .CFConfig.json file |
lucee-<version>-env-vars.json |
The environment variables and system properties Lucee reads |
These files are only attached to the more recent release lines, so check the version directory on Maven Central before relying on them. They describe configuration, not language keywords, but editors can use them to offer completion and validation for the config file.
Using this list
A syntax definition for an editor typically needs:
- the fixed groups on this page (statements, control flow, declarations, modifiers, literals, operators, scopes)
- the tag names from
getTagList(), optionally marked by the script type fromgetTagData() - the function names from
getFunctionList()
Items 2 and 3 can change with the Lucee version and the installed extensions, so generate them from a running server and do not copy them by hand.