npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cfmleditor/tree-sitter-cfml

v0.26.2

Published

CFML grammar for tree-sitter

Readme

tree-sitter-cfml

npm crates.io "Buy Me A Coffee"

Tree-sitter grammars for ColdFusion Markup Language (CFML).

Three grammars are provided to cover the different ways CFML is written, plus an embedded SQL dialect for cfquery:

| Grammar | Scope | File types | Description | |----------|----------------|------------|-------------| | cfml | source.cfml | .cfc | ColdFusion components — CFScript inside a component {} block or tag-based component files | | cfhtml | source.cfhtml| .cfm | CFML template files — HTML with embedded CF tags and hash expressions | | cfscript | source.cfscript | .cfs | Pure CFScript files | | cfquery | source.cfquery | (embedded) | SQL dialect used inside <cfquery> bodies (and compatible with QueryExecute-style usage) with CF-style #hash# interpolation and CF tags in the body |

Playground

Try the grammars in the browser: cfmleditor.github.io/tree-sitter-cfml

Installation

Node.js

npm install @cfmleditor/tree-sitter-cfml
const { cfml, cfhtml, cfscript, cfquery } = require('@cfmleditor/tree-sitter-cfml');
const Parser = require('tree-sitter');

const parser = new Parser();
parser.setLanguage(cfhtml.language);

const tree = parser.parse('<cfif condition>#value#</cfif>');
console.log(tree.rootNode.toString());

Rust

Add to your Cargo.toml:

[dependencies]
tree-sitter = "0.25"
tree-sitter-cfml = "0.26"
use tree_sitter_cfml::{LANGUAGE_CFML, LANGUAGE_CFHTML, LANGUAGE_CFSCRIPT, LANGUAGE_CFQUERY};

// cfml for .cfc component files
let mut parser = tree_sitter::Parser::new();
parser.set_language(&LANGUAGE_CFML.into())
    .expect("Error loading CFML grammar");

// cfhtml for .cfm template files
parser.set_language(&LANGUAGE_CFHTML.into())
    .expect("Error loading CFHTML grammar");

// cfscript for .cfs pure script files
parser.set_language(&LANGUAGE_CFSCRIPT.into())
    .expect("Error loading CFSCRIPT grammar");

Python

pip install tree-sitter-cfml
import tree_sitter_cfml as ts_cfml
from tree_sitter import Language, Parser

# cfhtml for .cfm template files
parser = Parser(Language(ts_cfml.language_cfhtml()))
tree = parser.parse(b'<cfif x GT 0>#x#</cfif>')

# cfml for .cfc component files
parser = Parser(Language(ts_cfml.language_cfml()))

# cfscript for .cfs pure script files
parser = Parser(Language(ts_cfml.language_cfscript()))

# cfquery SQL dialect (embedded)
parser = Parser(Language(ts_cfml.language_cfquery()))

Go

import (
    tree_sitter_cfml "github.com/cfmleditor/tree-sitter-cfml/bindings/go"
    sitter "github.com/tree-sitter/go-tree-sitter"
)

// cfml for .cfc component files
parser := sitter.NewParser()
parser.SetLanguage(sitter.NewLanguage(tree_sitter_cfml.LanguageCfml()))

// cfhtml for .cfm template files
parser.SetLanguage(sitter.NewLanguage(tree_sitter_cfml.LanguageCfhtml()))

// cfscript for .cfs pure script files
parser.SetLanguage(sitter.NewLanguage(tree_sitter_cfml.LanguageCfscript()))

// cfquery SQL dialect (embedded)
parser.SetLanguage(sitter.NewLanguage(tree_sitter_cfml.LanguageCfquery()))

Development

Requirements

Building

Each grammar is built independently from its subdirectory:

cd cfml && make
cd cfhtml && make
cd cfscript && make

Or build all three plus the Node.js bindings:

npm run build

Note on build warnings When running npm run build, you may see tree-sitter warnings about “unnecessary conflicts” such as binary_expression, call_expression, switch_case, or assignment_expression versus _property_name, and hash-related conflicts for the cfquery dialect. These conflicts are intentionally declared in common/define-grammar.js to resolve real ambiguities in CFML/CFHTML/cfquery syntax; attempts to remove them cause tree-sitter generate to fail with unresolved conflicts. It is safe to ignore these warnings as long as the build and tests succeed.

Generating the parser

After editing common/define-grammar.js:

cd cfml && tree-sitter generate
cd cfhtml && tree-sitter generate
cd cfscript && tree-sitter generate

Testing

# Test a single grammar
cd cfml && tree-sitter test

# Test all grammars
npm test

Parsing a file

cd cfml && tree-sitter parse path/to/file.cfc

Playground

npm run playground

Grammar structure

All four grammars share a common base defined in common/define-grammar.js, with an external scanner in common/scanner.h that handles context-sensitive tokenisation (implicit end tags, CF tag names, hash expressions, raw text, etc.).

common/
  define-grammar.js   # shared grammar rules for all three dialects
  scanner.h           # external scanner (C)
  tag.h               # HTML/CF tag type definitions

cfml/                 # .cfc grammar
cfhtml/               # .cfm grammar
cfscript/             # .cfs grammar
cfquery/              # cfquery SQL dialect (embedded)
  grammar.js          # entry point (calls defineGrammar with dialect name)
  src/                # generated parser (do not edit)
  queries/
    highlights.scm    # syntax highlighting
    indents.scm       # indentation
    injections.scm    # language injections
    tags.scm          # symbol navigation

Queries

Each grammar ships with query files for editor integration:

  • highlights.scm — syntax highlighting captures
  • indents.scm — indentation rules
  • injections.scm — embedded language injections (e.g. SQL inside <cfquery>)
  • tags.scm — function/method definitions and call references for go-to-definition and symbol search

License

MIT