I am returning to Crystal-lang. I have not used it seriously since the all-in-one Asterisk shard days. For some recent VoIP and CLI projects I want a language that compiles to a small static binary and has Ruby-like syntax — Crystal still fits.
The editor support has not aged well. vim-crystal is regex-based and has not had a real update in years. On the Neovim side, there is no plugin that wires the modern crystal-lang-tools/tree-sitter-crystal parser into a complete editing experience — filetype detection, indent, text objects, commands, LSP. A few repositories cover one or two pieces; none cover everything.
So I have authored one: andrius/crystal.nvim.
What’s Included
- Targets Neovim 0.11+.
- Registers the upstream tree-sitter parser. Works with both the classic
masterand the newmain(rewrite) branches ofnvim-treesitter, which now expose incompatible APIs. - Ships three gap-filler queries —
indents.scm,locals.scm,textobjects.scm— verified against the live grammar (the upstream parser already provideshighlights,folds,injections). - Filetype detection for
.cr,.ecr, andshard.{yml,lock,override.yml}. - Five commands you actually use day-to-day:
:CrystalRun,:CrystalSpec,:CrystalFormat,:CrystalDocs,:CrystalExpandMacro. - Opt-in Crystalline LSP via the native
vim.lsp.enable(). Nonvim-lspconfigdependency. :checkhealth crystal,:help crystal, CI, MIT licence.
Built with Claude Code
The whole thing — design specification, implementation plan, twenty commits, debugging tree-sitter node names against the actual grammar, README, CI, tagged release on GitHub — was built end-to-end in one afternoon session with Claude Code doing the typing. I made the design decisions; Claude Code wrote the code, ran the smoke tests, and caught its own mistakes through review subagents.
The interesting part was not the speed. It was that I never had to context-switch from “what should this plugin do” to “how do I express this in Lua”.
Install
With lazy.nvim:
{
'andrius/crystal.nvim',
dependencies = { 'nvim-treesitter/nvim-treesitter' },
lazy = false,
build = ':TSInstall! crystal',
opts = {},
}
The full installation, configuration and command reference is in the README. Issues and PRs are welcome.