LabHub

Blog

LSP & Tree-sitter Ecosystem 2026 — ast-grep / Biome / Helix / Zed / Neovim Treesitter / Per-Language LSPs Deep Dive

한국어English日本語

Prologue — The two standards of code tooling

The editor wars of the 2010s were simple. "Which app you use" decided almost everything. VS Code vs JetBrains vs Vim vs Emacs. Each one re-implemented its own completion, go-to-definition, refactoring, and syntax highlighting; every new language meant editors x languages worth of work.

The 2026 picture is completely different. The true center of gravity of editors and IDEs has shifted to two protocols/libraries.

StandardWhat it standardizedWho built it
LSP (Language Server Protocol)Code "intelligence" — completion, go-to-def, rename, diagnostics, formatMicrosoft (2016)
Tree-sitterCode "structure" — incremental parsing, highlighting, structure-aware opsMax Brunsfeld (GitHub, 2018+)

The lesson of the last ten years is clear. Hooking into the standards is far cheaper than building a new editor. That is why new editors like Helix and Zed bake in LSP + Tree-sitter from day one. Neovim shipped an LSP client in the core starting 0.5; VS Code was the reference LSP client from the start.

And a new ecosystem is exploding on top of these two standards — ast-grep (Tree-sitter based structural search/rewrite), BiomeJS (a Rust-rewritten JS toolchain), Marksman (Markdown LSP), Semgrep / CodeQL (security and policy search), Comby (language-neutral rewriting). This post is one volume on all of it.


1. LSP — Microsoft's standard

1.1 Why LSP was needed

Before 2015: every editor needed its own plugin per language.

EditorLanguageResult
VS CodeTypeScriptPlugin A
VimTypeScriptPlugin B (re-implemented)
EmacsTypeScriptPlugin C (re-implemented)
AtomTypeScriptPlugin D (re-implemented)

With M languages and N editors, you needed M x N plugins. Each plugin re-implemented features like "go to definition" or "rename," with wildly varying quality.

Microsoft's insight: split the code analysis logic into a separate process (the language server), and have the editor and server talk over standard JSON-RPC messages. The math collapses to M + N.

1.2 Core LSP messages

MessageWhat it asks
textDocument/completionCompletion candidates at the cursor
textDocument/definitionWhere a symbol is defined
textDocument/referencesAll places that reference a symbol
textDocument/hoverType and docs for a symbol under the cursor
textDocument/renameBulk-rename a symbol
textDocument/formattingFormat the document
textDocument/codeActionQuick fixes and refactorings
textDocument/publishDiagnosticsServer -> client (errors and warnings)

The default transport is JSON-RPC 2.0 over stdin/stdout. TCP/socket is supported, but stdio is the norm.

1.3 One-line diagram

       ┌──────────────┐           ┌─────────────────────┐
       │   Editor     │  JSON     │   Language Server   │
       │  (client)    │◀────────▶│   rust-analyzer,    │
       │  VS Code,    │   RPC     │   etc.              │
       │  Helix, Zed, │           │                     │
       │  Neovim ...  │           │  - Parsing          │
       └──────────────┘           │  - Type inference   │
                                  │  - Indexing         │
                                  └─────────────────────┘

The editor side gets thinner. The server side gets thicker. And once you write the server well, every editor benefits.

1.4 LSP's standing in 2026


2. Tree-sitter — Max Brunsfeld's incremental parser

2.1 The limits of regex highlighting

Until the mid-2010s, almost every editor implemented syntax highlighting with regular expressions. TextMate grammars (.tmLanguage) were the de facto standard.

Problems:

2.2 What Tree-sitter answered

Tree-sitter, built by Max Brunsfeld (formerly of Atom, then GitHub), solves all of these at once.

  1. Incremental. A keystroke re-parses only the changed region, not the entire tree.
  2. Error recovery. When code is temporarily broken, it parses as much as it can and leaves error nodes.
  3. Generalized LR (GLR) — handles ambiguous grammars.
  4. Language-neutral. Grammars are written in a small DSL; parsers are generated in C.
  5. Fast. A real parser, but fast enough for live highlighting.

2.3 Uses

2.4 Who uses it

ToolTree-sitter use
Neovimnvim-treesitter — highlight, fold, structural text objects
HelixBuilt-in. Highlight, indent, structural motions all on TS
ZedBuilt-in. Highlight, outline, structural search
GitHubCode search, highlight, symbol extraction
ast-grepStructural search/rewrite engine
DifftasticStructure-aware diff

2.5 Grammar distribution

tree-sitter-rust, tree-sitter-python, tree-sitter-typescript, and so on — almost every popular language ships its grammar as a separate npm/crates package. Supporting a new language means writing a grammar; the highlight queries (.scm) are short.


3. ast-grep (sg) — structural search and rewrite

3.1 Why grep falls short and what ast-grep answers

grep matches text. "All callers of console.log" also catches comments, strings, and docs containing console.log. And "only calls where the first argument is an object" is effectively impossible with regex.

ast-grep (sg) is different. It matches patterns on the AST parsed by Tree-sitter. Patterns look like code in the same language, with $VAR for metavariables.

3.2 Who built it, what is new

3.3 Pattern examples

# Every call to console.log with any argument
sg --pattern 'console.log($A)' --lang typescript

# Only calls whose first arg is an object literal
sg --pattern 'console.log({ $$$ })' --lang typescript

# Rewrite: console.log(x) -> logger.debug(x)
sg --pattern 'console.log($A)' --rewrite 'logger.debug($A)' --lang typescript --update-all

$A matches one arbitrary expression; $$$ matches an arbitrary list of nodes.

3.4 sgconfig.yml — codebase policy

ast-grep can store team policies as YAML rulesets. Running the ruleset in CI automatically checks rules like "do not use this pattern."

id: no-direct-fetch
language: typescript
rule:
  pattern: fetch($URL)
message: "Use apiClient.get instead of fetch"
severity: warning

3.5 What it is best for


4. BiomeJS — replacing ESLint + Prettier

4.1 Accumulated pain in the JS toolchain

Since the mid-2010s, two tools every JS dev used:

Both are excellent, but:

4.2 Biome's approach

Biome (split off from the original Rome project) bundles:

4.3 One-line difference

# Traditional
eslint . --fix && prettier --write .

# Biome
biome check . --apply

4.4 Limits

Still, the default for new JS/TS projects is rapidly moving to Biome.


5. Marksman — Markdown LSP

5.1 Does Markdown really need an LSP?

It seems odd at first — isn't Markdown just text? But for any wiki, note system, blog, or documentation site that takes Markdown seriously, you need:

That is exactly what LSP is for.

5.2 Marksman's place

Marksman (written in F#) is a dedicated Markdown LSP server. It works in Helix, Zed, Neovim, and VS Code.

5.3 Neighbors


6. Helix editor — built-in LSP + Tree-sitter

6.1 Helix's design choices

Helix is a modal editor in Rust. A descendant of Vim/Kakoune, with decisive differences.

6.2 What makes it attractive

ItemVim/NeovimHelix
LSP integrationPlugin (nvim-lspconfig)Built-in
Tree-sitterPlugin (nvim-treesitter)Built-in
ConfigurationDozens to hundreds of linesNear zero
First-use experienceSteepWorks immediately
ExtensibilityUnlimited (Lua)Limited

"IDE-grade environment in an hour" is Helix's promise. The trade-off is clear — deep customization still belongs to Neovim.

6.3 languages.toml example

[[language]]
name = "rust"
language-servers = ["rust-analyzer"]
auto-format = true

[[language]]
name = "python"
language-servers = ["basedpyright"]

That is nearly all of it.


7. Zed editor — Tree-sitter + LSP + real-time collaboration

7.1 Zed's roots and ambition

Zed is the editor a group of Atom and Electron-era co-authors (Nathan Sobo and others) rebuilt from scratch. The core is a native editor written in Rust + collaborative editing + AI integration.

7.2 Who fits

7.3 Trade-offs


8. Neovim integration — nvim-treesitter / lsp-zero / nvim-lspconfig

8.1 Neovim's place

Neovim forked from Vim and brought a built-in LSP client (0.5+), a Lua runtime, and Tree-sitter support (0.8+) into the core. The result is an editor that allows endless customization.

Key plugins:

PluginRole
nvim-treesitterTree-sitter integration — highlight, indent, text objects
nvim-lspconfigCollected configurations for well-known LSP servers
lsp-zeronvim-lspconfig + mason + cmp pre-integrated — "LSP in one line"
mason.nvimInstaller for LSP servers, formatters, linters, debuggers
nvim-cmpCompletion UI engine
none-ls / null-lsExposes non-LSP tools (eslint, prettier, ...) as if they were LSPs
telescope.nvimFuzzy finder (files, symbols, LSP results)

8.2 The value of lsp-zero

Neovim's LSP setup is powerful but initially steep. 1) Register the server with lspconfig, 2) install via mason, 3) wire up cmp for completion, 4) set keymaps. lsp-zero does all four with sensible defaults.

local lsp_zero = require('lsp-zero')
lsp_zero.on_attach(function(client, bufnr)
  lsp_zero.default_keymaps({buffer = bufnr})
end)

require('mason').setup({})
require('mason-lspconfig').setup({
  ensure_installed = { 'rust_analyzer', 'gopls', 'basedpyright', 'tsserver' },
  handlers = { lsp_zero.default_setup },
})

8.3 nvim-treesitter

require('nvim-treesitter.configs').setup({
  ensure_installed = { 'rust', 'go', 'python', 'typescript', 'tsx', 'lua' },
  highlight = { enable = true },
  indent = { enable = true },
})

Turning this on brings a level of accuracy regex highlighting cannot match.


9. Per-language LSP catalog

9.1 Rust — rust-analyzer

9.2 Go — gopls

9.3 Python — pyright / basedpyright / jedi / pylyzer

ServerNotes
pyrightA fast type checker by Microsoft, wrapped as LSP
basedpyrightA pyright fork. OSS-friendly with stricter defaults
jedi-language-serverjedi-based. Strong on code with limited type annotations
pylyzerA fast Rust-written static analyzer + LSP. Early, but promising

In 2026: the recommendation for new codebases is basedpyright. For legacy untyped code, jedi.

9.4 TypeScript / JavaScript

9.5 C/C++ — clangd

9.6 Java — jdtls

9.7 Others

LanguageLSP
RubySolargraph (traditional), ruby-lsp (newer, Shopify)
Elixirelixir-ls, next-ls
Haskellhls (haskell-language-server)
Nimnimlsp
OCamlocaml-lsp
Luasumneko-lua / lua-language-server (essential for Neovim configs)
Zigzls
Kotlinkotlin-language-server
Swiftsourcekit-lsp
Erlangerlang_ls
Bashbash-language-server
YAMLyaml-language-server (Red Hat)
JSONvscode-json-languageserver
Terraformterraform-ls
MarkdownMarksman

9.8 A pattern


10. Structural search — Comby / Semgrep / CodeQL

Three tools in ast-grep's neighborhood, each in a slightly different niche.

10.1 Comby

comby 'foo(:[x])' 'bar(:[x])' file.py

10.2 Semgrep

10.3 CodeQL

10.4 Side-by-side

ToolParadigmStrengthBarrier
ast-grepTree-sitter AST match/rewriteFast, intuitive, every TS languageLow
CombyBalanced-structure match/rewriteCheap new-language support, one-offLow
SemgrepAST patterns + policy rulesetsBig security rulesets, CI-friendlyMedium
CodeQLData-flow query languageMost powerful analysis, taint trackingHigh

Picking guide:


11. Tabnine vs language-specific completion

11.1 Two streams

Completion is a blend of two things.

KindSourceExamples
Language-basedLSP servers. Types and symbol indexespyright, rust-analyzer
ProbabilisticLLMs / local modelsTabnine, Copilot, Codeium, Cursor Tab

11.2 Tabnine's place

11.3 LSP and LLM completion should run together

Completion = LSP + LLM hybrid is the 2026 default.


12. The field in Korea and Japan

12.1 Korea — Toss's use of LSP and internal tooling

Toss's blog and platform team frequently mention LSP and Tree-sitter-based tools.

The point is editor freedom. Some pick IntelliJ, some Cursor, some Neovim. As long as they sit on standards — LSP, Tree-sitter, Biome, ast-grep — the team's rulesets apply uniformly to all of them.

12.2 Japan — Mercari's Tree-sitter usage

Mercari (メルカリ) frequently mentions Tree-sitter-based tools in its engineering blog.

Other Japanese companies — DeNA, CyberAgent, SmartHR, LINE — show a similar picture. LSP and Tree-sitter have settled in as "obvious infrastructure" in 2026.


13. Who should pick what

13.1 Scenarios

"I want to keep using VS Code."

"VS Code is too heavy. I want a fast native editor."

"I want endless customization and a keyboard-first workflow."

"Large monorepo refactors and policy enforcement."

"Markdown-heavy work — notes, docs, blogs."

13.2 What everyone should share

ItemRecommendation
CompletionBoth LSP (language-based) and LLM (probabilistic)
HighlightingTree-sitter
FormattingThe language's official formatter (rustfmt, gofmt, ruff format, biome)
LintingPer-language standard + Semgrep for company policy
Searchast-grep when precision matters

14. Pitfalls and anti-patterns

14.1 Common pitfalls

14.2 Anti-patterns


15. Closing — living on top of standards

The 2026 code-tooling ecosystem stands on two standards.

Because of these two:

The ecosystem that grew on top — ast-grep, Biome, Marksman, Helix, Zed, Neovim's lsp-zero/treesitter chain, and the well-built per-language LSPs — is all a direct descendant of these two axes.

One thing to remember when picking: if the tool sits on standards like LSP and Tree-sitter, you can hardly pick wrong. You can move anytime, and your team's rulesets follow you.


References

Comments

No comments yet.

Sign in to leave a comment