Home InternationalBuilding Emacs Major Modes with TreeSitter: Lesson...
International⭐ Featured

Building Emacs Major Modes with TreeSitter: Lessons Learned

Over the past year I’ve been spending a lot of time building TreeSitter-powered major modes for Emacs – clojure-ts-mode (as co-maintainer), neocaml (from scratch), and asciidoc-mode (also from scratch). Between the three projects I’ve accumulated enough battle scars to write about the experience. This post distills the key lessons for anyone thinking about writing a TreeSitter-based major mode, or curious about what it’s actually like.

7 April 2026 at 08:42 am
1 views
Building Emacs Major Modes with TreeSitter: Lessons Learned

Over the past year, I’ve been deeply involved in building TreeSitter-powered major modes for Emacs, including clojure-ts-mode (as a co-maintainer), neocaml (from scratch), and asciidoc-mode (also from scratch). These projects have provided valuable insights into the process of creating a TreeSitter-based major mode, and I’ve learned a lot along the way. In this article, I’ll distill the key lessons for anyone considering writing a TreeSitter-based major mode or those curious about the experience.

First and foremost, understanding the TreeSitter ecosystem is crucial. TreeSitter is a language server that provides robust parsing, semantic analysis, and code navigation capabilities. It’s designed to be language-agnostic, meaning it can be configured to support any programming language. For Emacs users, integrating TreeSitter into major modes allows for enhanced editing experiences, including real-time syntax highlighting, autocompletion, and error highlighting.

One of the initial challenges I faced was setting up the TreeSitter environment. TreeSitter requires a language definition file (a .g.ts file) that specifies the grammar and semantics of the language. These files are generated using the TreeSitter Generator, which is a Ruby-based tool. The process involves writing a grammar in a domain-specific language (DSL) that describes the syntax of the language. For example, when working on clojure-ts-mode, I had to collaborate with the existing maintainers to ensure our grammar was accurate and up-to-date with Clojure’s evolving syntax.

Another significant learning point was the integration of TreeSitter with Emacs. Emacs provides the `tree-sitter-mode` package, which simplifies the setup process. However, there are nuances to consider. For instance, the `tree-sitter-mode` package requires the `company-mode` for autocompletion, which can be customized to enhance the user experience. Additionally, ensuring that the major mode correctly initializes the language server and handles language-specific settings was essential.

When developing a major mode from scratch, such as neocaml and asciidoc-mode, the process involved more than just writing the TreeSitter grammar. I had to create the necessary Emacs Lisp code to define the major mode, syntax highlighting, and key bindings. This required a solid understanding of Emacs Lisp and its extensibility model. For example, in asciidoc-mode, I had to define a custom parser to handle the unique syntax of AsciiDoc, which includes special characters like backticks and pipes.

A key lesson I learned was the importance of testing. Testing the TreeSitter grammar and the Emacs integration thoroughly was critical. The TreeSitter Generator provides a test suite that validates the grammar against a set of test cases. Similarly, testing the Emacs major mode with various files and edge cases helped identify and fix issues early on. For instance, when working on neocaml-mode, I encountered unexpected behavior with certain Caml constructs, which were resolved by refining the grammar and adjusting the Emacs code accordingly.

Documentation and community collaboration proved to be invaluable. Maintaining clear and concise documentation for the major mode, including setup instructions and usage examples, is essential for users. Additionally, engaging with the TreeSitter and Emacs communities helped identify best practices and potential pitfalls. For example, the TreeSitter community provided valuable feedback on my grammar files, ensuring they were accurate and efficient.

In conclusion, building TreeSitter-powered major modes for Emacs has been a rewarding experience, albeit with its share of challenges. The key takeaways include the importance of a solid understanding of the TreeSitter ecosystem, careful setup and integration, thorough testing, and leveraging community support. Whether you’re a seasoned developer or new to the world of Emacs and TreeSitter, these lessons can guide you in creating powerful and efficient major modes. As the landscape of programming languages continues to evolve, TreeSitter’s flexibility and Emacs’ extensibility make it a compelling choice for enhancing the editing experience.

Source: OCaml Planet
📰 Related News
Ollama 0.2.6 Released with Native Gemma 4 Support and Enhanced Performance
Ollama 0.2.6 Released with Native Gemma 4 Support and Enhanced Performance
Ollama 0.2.6 is now live, featuring native support for Google's Gemma 4 models and improved local inference performance for Windows, macOS, and Linux.
14 Apr
Weekly news roundup: Shortages spread to MLCCs; SK Hynix reportedly in talks with Microsoft and Google
Weekly news roundup: Shortages spread to MLCCs; SK Hynix reportedly in talks with Microsoft and Google
Below are the most-read DIGITIMES Asia stories from the week of April 6-April 13, 2026:
14 Apr
cutile-stencil 0.2.0
cutile-stencil 0.2.0
An xDSL-based stencil compiler that generates optimized GPU kernels via NVIDIA cuTile
14 Apr
merlin-llm added to PyPI
merlin-llm added to PyPI
Merlin — a fast local LLM for agentic coding on Apple Silicon
14 Apr
Fluent Cut - Craft and compose videos programmatically in PHP with an elegant fluent API
Fluent Cut - Craft and compose videos programmatically in PHP with an elegant fluent API
Craft and compose videos programmatically in PHP with an elegant fluent API - b7s/fluentcut
14 Apr
Crypto Investor at Center of Trump Corruption Allegations Now Sees Himself as ‘Victim’
Crypto Investor at Center of Trump Corruption Allegations Now Sees Himself as ‘Victim’
Justin Sun has accused Trump-affiliated World Liberty Financial of misconduct and a general lack of transparency.
14 Apr
nvidia-nat-weave 1.7.0a20260413
nvidia-nat-weave 1.7.0a20260413
Subpackage for Weave integration in NeMo Agent Toolkit
14 Apr
nvidia-nat-s3 1.7.0a20260413
nvidia-nat-s3 1.7.0a20260413
Subpackage for S3-compatible integration in NeMo Agent Toolkit
14 Apr
Social Security Trust Fund to Run Dry in 2032: Just 6 Years From Now
Social Security Trust Fund to Run Dry in 2032: Just 6 Years From Now
Six years. That is how much time separates retirees from a Social Security system that, by its own projections, runs out of money. If you are 56 years old...
14 Apr
cane-gpu-perf added to PyPI
cane-gpu-perf added to PyPI
GPU inference benchmarking with opinionated diagnostics
13 Apr