LabHub

블로그

LSP & Tree-sitter 생태계 2026 — ast-grep / Biome / Helix / Zed / Neovim Treesitter / 언어별 LSP 심층 가이드

한국어English日本語

프롤로그 — 코드 도구의 양대 표준

2010년대의 에디터 전쟁은 단순했다. "어떤 앱을 쓰느냐" 가 거의 모든 것을 결정했다. VS Code인가, JetBrains인가, Vim인가, Emacs인가. 각자 자기만의 자동완성·정의 이동·리팩토링·문법 강조를 따로 구현했고, 새 언어가 나오면 에디터 x 언어 만큼의 작업이 매번 필요했다.

2026년의 그림은 완전히 다르다. 에디터·IDE의 진짜 무게중심은 두 개의 프로토콜·라이브러리로 옮겨갔다.

표준무엇을 표준화했나누가 만들었나
LSP (Language Server Protocol)코드 "지능" — 자동완성·정의 이동·리네임·진단·포맷Microsoft (2016)
Tree-sitter코드 "구조" — 증분 파서·문법 강조·구조 인식Max Brunsfeld (GitHub, 2018~)

지난 10년의 함의는 분명하다. 에디터를 만드는 것보다, 표준에 붙는 것이 압도적으로 싸다. 그래서 Helix와 Zed처럼 새로 등장한 에디터들은 처음부터 LSP + Tree-sitter를 빌트인으로 짠다. Neovim은 0.5부터 LSP 클라이언트를 코어에 내장했고, VS Code는 처음부터 LSP의 레퍼런스 클라이언트였다.

그리고 이 두 표준 위에 새로운 생태계가 폭발적으로 자라고 있다 — ast-grep(Tree-sitter 기반 구조 검색·리라이트), BiomeJS(Rust로 다시 짠 JS 툴체인), Marksman(Markdown LSP), Semgrep / CodeQL(보안·정책 검색), Comby(언어 중립 리라이트). 이 글은 그 전부를 한 권으로 정리한다.


1장 · LSP — Microsoft 표준의 자리

1.1 왜 LSP가 필요했나

2015년 이전: 새 언어를 지원하려면 에디터마다 따로 플러그인을 짜야 했다.

에디터언어결과
VS CodeTypeScript플러그인 A
VimTypeScript플러그인 B (재구현)
EmacsTypeScript플러그인 C (재구현)
AtomTypeScript플러그인 D (재구현)

언어가 M개, 에디터가 N개면 M x N개의 플러그인이 필요했다. 게다가 각 플러그인이 "정의 이동"이나 "리네임" 같은 기능을 다시 구현해야 했고, 품질은 천차만별이었다.

Microsoft의 통찰: 코드 분석 로직을 별도 프로세스(언어 서버) 로 분리하고, 에디터와 서버가 표준 JSON-RPC 메시지로 대화하게 하면, M + N으로 줄어든다.

1.2 LSP 핵심 메시지

메시지무엇을 묻나
textDocument/completion커서 위치의 자동완성 후보
textDocument/definition심볼의 정의 위치
textDocument/references심볼을 참조하는 모든 위치
textDocument/hover커서 위 심볼의 타입·문서
textDocument/rename심볼 이름 일괄 변경
textDocument/formatting코드 포맷
textDocument/codeAction빠른 수정·리팩토링 제안
textDocument/publishDiagnostics서버 -> 클라이언트 (에러·경고)

전송 계층은 기본적으로 stdin/stdout JSON-RPC 2.0이다. TCP·소켓도 가능하지만 stdio가 표준이다.

1.3 LSP의 한 줄 그림

       ┌──────────────┐           ┌─────────────────────┐
       │   에디터      │  JSON     │   언어 서버 (LSP)    │
       │  (클라이언트)  │◀────────▶│  rust-analyzer 등   │
       │  VS Code,    │   RPC     │  (별도 프로세스)     │
       │  Helix, Zed, │           │                     │
       │  Neovim ...   │           │  - 파싱             │
       └──────────────┘           │  - 타입 추론        │
                                  │  - 인덱싱           │
                                  └─────────────────────┘

에디터 쪽은 얇아진다. 언어 서버 쪽은 두꺼워진다. 그리고 한 번 잘 짠 서버는 모든 에디터에서 쓸 수 있다.

1.4 2026년 LSP의 위상


2장 · Tree-sitter — Max Brunsfeld의 증분 파서

2.1 정규식 강조의 한계

2010년대 중반까지, 거의 모든 에디터의 문법 강조는 정규식이었다. TextMate 문법 (.tmLanguage) 같은 형식이 사실상 표준이었다.

문제:

2.2 Tree-sitter의 답

Max Brunsfeld(Atom 출신, GitHub)가 만든 Tree-sitter는 다음을 동시에 푼다.

  1. 증분(incremental). 키 입력 한 번에 트리 전체를 다시 파싱하지 않고, 바뀐 부분만 재파싱한다.
  2. 에러 복구. 코드가 일시적으로 깨져도 가능한 만큼 파싱하고 나머지는 에러 노드로 둔다.
  3. 일반화된 LR(GLR) 알고리즘. 모호한 문법도 처리.
  4. 언어 중립. 문법은 DSL(JS 비슷한 문법 정의)로 쓰고, 파서는 C로 생성된다.
  5. 빠르다. 진짜 파서면서도 강조 용도로 충분히 빠르다.

2.3 어디에 쓰는가

2.4 누가 쓰나

도구Tree-sitter 사용처
Neovimnvim-treesitter 플러그인 — 강조·폴딩·구조 텍스트 객체
Helix빌트인. 강조·들여쓰기·구조 모션 전부 TS 기반
Zed빌트인. 강조·아웃라인·구조 검색
GitHub코드 검색·강조·심볼 추출
ast-grep구조 검색·리라이트 엔진
Difftastic구조 인식 diff

2.5 grammar의 분포

tree-sitter-rust, tree-sitter-python, tree-sitter-typescript ... 거의 모든 인기 언어가 별도 npm/crates 패키지로 grammar를 제공한다. 새 언어를 지원하려면 grammar만 새로 짜면 되고, 강조 쿼리(.scm)는 짧다.


3장 · ast-grep (sg) — 구조적 검색/리라이트

3.1 grep의 한계, ast-grep의 답

grep은 텍스트 매칭이다. "console.log를 호출하는 모든 곳" 을 찾으면, 주석·문자열·doc 안의 console.log도 같이 잡힌다. 게다가 "console.log의 첫 인자가 객체인 곳만" 같은 질문은 정규식으로는 사실상 불가능하다.

ast-grep(sg)는 다르다. Tree-sitter로 파싱한 AST 위에서 패턴을 매칭한다. 패턴 언어는 그 언어 자체의 코드처럼 보이고, $VAR로 메타변수를 둔다.

3.2 누가 만들었나, 무엇이 새로운가

3.3 패턴 예시

# console.log를 어떤 인자로든 호출한 모든 곳
sg --pattern 'console.log($A)' --lang typescript

# 첫 인자가 객체 리터럴인 호출만
sg --pattern 'console.log({ $$$ })' --lang typescript

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

$A는 임의의 표현식 하나, $$$는 임의의 노드 목록을 잡는 메타변수다.

3.4 sgconfig.yml — 코드베이스 정책

ast-grep은 YAML 룰셋으로 팀 정책을 저장할 수 있다. CI에서 룰셋을 돌리면 "이 패턴을 쓰지 마라" 같은 정책이 자동 검사된다.

id: no-direct-fetch
language: typescript
rule:
  pattern: fetch($URL)
message: "fetch 대신 apiClient.get을 쓰세요"
severity: warning

3.5 어디에 적합한가


4장 · BiomeJS — ESLint + Prettier 대체

4.1 JS 툴체인의 누적된 문제

2010년대 중반 이후 JS 개발자가 반드시 쓰던 두 도구:

둘 다 훌륭하지만:

4.2 Biome의 접근

Biome(원래 Rome 프로젝트에서 분리·재출범)은 다음을 묶었다.

4.3 한 줄로 보는 차이

# 전통적
eslint . --fix && prettier --write .

# Biome
biome check . --apply

4.4 한계

그래도 신규 JS/TS 프로젝트의 기본값은 빠르게 Biome로 이동하고 있다.


5장 · Marksman — Markdown LSP

5.1 Markdown도 LSP가 필요한가

처음엔 의외다. 마크다운은 그냥 텍스트인데? 하지만 마크다운을 본격적으로 쓰는 위키·노트·블로그·문서 사이트에서는 다음이 필요하다.

이게 LSP의 정확한 사용처다.

5.2 Marksman의 자리

Marksman(F# 작성)은 마크다운 전용 LSP 서버다. Helix·Zed·Neovim·VS Code 모두에서 동작한다.

5.3 비슷한 도구


6장 · Helix 에디터 — built-in LSP + Tree-sitter

6.1 Helix의 디자인 결정

Helix는 Rust로 짠 모달 에디터다. Vim/Kakoune의 후예이지만 결정적인 차이가 있다.

6.2 왜 매력적인가

항목Vim/NeovimHelix
LSP 통합플러그인 (nvim-lspconfig)빌트인
Tree-sitter플러그인 (nvim-treesitter)빌트인
설정수십~수백 줄거의 제로
첫 사용 경험가팔라짐즉시 작동
확장성무제한 (Lua)제한적

"한 시간 안에 IDE급 환경"이 Helix의 약속이다. 트레이드오프는 분명하다 — 깊은 커스터마이즈는 Neovim이 여전히 왕이다.

6.3 languages.toml 예시

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

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

이게 거의 전부다.


7장 · Zed 에디터 — Tree-sitter + LSP + 실시간 협업

7.1 Zed의 출신과 야망

Zed는 Atom·Electron 시절의 공동저자(Nathan Sobo 등)가 다시 만든 에디터다. 핵심은 Rust로 처음부터 다시 짠 네이티브 에디터 + 공동 편집(collab) + AI 통합.

7.2 누구에게 맞나

7.3 트레이드오프


8장 · Neovim 통합 — nvim-treesitter / lsp-zero / nvim-lspconfig

8.1 Neovim의 자리

Neovim은 Vim에서 포크되어 빌트인 LSP 클라이언트(0.5+)와 Lua 런타임, Tree-sitter 지원(0.8+)을 코어에 넣었다. 결과적으로 무한 커스터마이즈가 가능한 에디터로 남았다.

대표 플러그인:

플러그인역할
nvim-treesitterTree-sitter 통합 — 강조·들여쓰기·텍스트 객체
nvim-lspconfig잘 알려진 LSP 서버 설정 모음
lsp-zeronvim-lspconfig + mason + cmp의 사전 통합 — "한 줄로 LSP 켜기"
mason.nvimLSP 서버·포맷터·린터·디버거 설치 관리자
nvim-cmp자동완성 UI 엔진
none-ls / null-lsLSP가 아닌 도구(eslint, prettier, ...)를 LSP처럼 노출
telescope.nvim퍼지 파인더 (파일·심볼·LSP 결과)

8.2 lsp-zero의 가치

Neovim의 LSP 셋업은 강력하지만 처음엔 가파르다. 1) lspconfig로 서버 등록, 2) mason으로 설치, 3) cmp로 자동완성 연결, 4) 키맵 설정. lsp-zero는 이 네 단계를 합리적인 기본값으로 한 번에 한다.

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 },
})

이걸 켜는 순간 정규식 강조와는 비교가 안 되는 정확성이 들어온다.


9장 · 언어별 LSP 카탈로그

9.1 Rust — rust-analyzer

9.2 Go — gopls

9.3 Python — pyright / basedpyright / jedi / pylyzer

서버특징
pyrightMicrosoft가 만든 빠른 타입 체커 기반 LSP
basedpyrightpyright 포크. 오픈소스 친화·기본 엄격성 강화
jedi-language-serverjedi 기반. 타입 어노테이션 부족한 코드에 강함
pylyzerRust로 작성된 빠른 정적 분석기 + LSP. 초기 단계지만 약속 큼

2026년 기준: 새 코드베이스에 권장은 basedpyright. 레거시 untyped 코드에는 jedi.

9.4 TypeScript / JavaScript

9.5 C/C++ — clangd

9.6 Java — jdtls

9.7 그 외

언어LSP
RubySolargraph (전통), ruby-lsp (신흥, Shopify)
Elixirelixir-ls, next-ls
Haskellhls (haskell-language-server)
Nimnimlsp
OCamlocaml-lsp
Luasumneko-lua / lua-language-server (Neovim 설정에 필수)
Zigzls
Kotlinkotlin-language-server
Swiftsourcekit-lsp
Erlangerlang_ls
Bashbash-language-server
YAMLyaml-language-server (Red Hat)
JSONvscode-json-languageserver
Terraformterraform-ls
MarkdownMarksman

9.8 한 가지 패턴


10장 · 구조적 검색 — Comby / Semgrep / CodeQL

ast-grep과 가까운 동네에 있는 세 도구. 각자 약간 다른 자리를 차지한다.

10.1 Comby

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

10.2 Semgrep

10.3 CodeQL

10.4 셋 비교

도구패러다임강점진입장벽
ast-grepTree-sitter AST 매칭·리라이트빠르고 직관적, 모든 TS 언어낮음
Comby균형 구조 매칭·리라이트새 언어 지원 저렴, 일회성 강함낮음
SemgrepAST 패턴 + 정책 룰셋거대 보안 룰셋·CI 친화중간
CodeQL데이터 흐름 쿼리 언어가장 강력한 분석, taint tracking높음

선택 가이드:


11장 · Tabnine vs 언어별 자동완성

11.1 두 갈래

자동완성은 두 가지가 섞여 있다.

종류출처
언어 기반LSP 서버. 타입·심볼 인덱스pyright, rust-analyzer
확률 기반LLM·로컬 모델Tabnine, Copilot, Codeium, Cursor Tab

11.2 Tabnine의 자리

11.3 LSP 완성과 LLM 완성은 같이 가야 한다

자동완성 = LSP + LLM의 하이브리드가 2026년의 표준이다.


12장 · 한국·일본 현장

12.1 한국 — 토스의 LSP·내부 도구 활용

토스는 사내 도구·플랫폼팀 글에서 자주 LSP·Tree-sitter 기반 도구를 언급한다.

요점은 에디터 자유다. 누구는 IntelliJ, 누구는 Cursor, 누구는 Neovim을 쓰지만, LSP·Tree-sitter·Biome·ast-grep 같은 표준 위에 있으면 팀의 룰셋이 모두에게 동일하게 적용된다.

12.2 일본 — メルカリ의 Tree-sitter 활용

メルカリ(Mercari)는 사내 기술 블로그에서 Tree-sitter 기반 도구로 다음을 자주 언급한다.

일본의 다른 회사들 — DeNA·CyberAgent·SmartHR·LINE — 도 비슷한 그림이다. LSP·Tree-sitter는 2026년의 "당연한 인프라"로 자리잡았다.


13장 · 누가 무엇을 골라야 하나

13.1 시나리오별 추천

"VS Code를 그대로 쓰고 싶다"

"VS Code가 무겁다, 빠른 네이티브 에디터로"

"무한 커스터마이즈와 키보드 워크플로"

"거대 모노레포 리팩토링·정책"

"마크다운 위주 작업(노트·문서·블로그)"

13.2 모든 경우의 공통점

항목권장
자동완성LSP(언어 기반) + LLM(확률 기반) 둘 다
강조Tree-sitter
포맷언어 공식 포맷터 (rustfmt, gofmt, ruff format, biome)
린트언어별 표준 + Semgrep으로 회사 정책
검색정확도가 필요하면 ast-grep

14장 · 함정과 안티패턴

14.1 흔한 함정

14.2 안티패턴


15장 · 정리 — 표준 위에 사는 법

2026년의 코드 도구 생태계는 두 개의 표준 위에 서 있다.

이 두 표준 덕분에:

그 위에 자라난 생태계 — ast-grep, Biome, Marksman, Helix, Zed, Neovim의 lsp-zero/treesitter 체인, 그리고 언어별로 잘 만들어진 LSP들 — 는 모두 이 두 축의 직접적인 후예다.

선택할 때 기억할 것 하나: 도구가 LSP·Tree-sitter 같은 표준 위에 있다면, 잘못된 선택이 거의 없다. 언제든 옮길 수 있고, 팀 룰셋이 이주를 따라간다.


참고 / References

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다