Editor setup

Type-checked JavaScript in Emacs

  • GNU Emacs
  • Eglot (built in) or lsp-mode

Emacs has two common LSP clients. Eglot has been part of Emacs since version 29, and its default server list runs typescript-language-server --stdio for js-mode, js-ts-mode and the TypeScript modes. lsp-mode is a separate package whose ts-ls client runs the same server. Either way TypeScript's own server checks the file, with the nearest jsconfig.json, so the errors are tsc's errors.

Install the server with npm (npm install -g typescript-language-server typescript, per its README), then start the client in JavaScript buffers.

At a glance

EditorGNU Emacs
What to installEglot (built in) or lsp-mode
What checks the codeEglot (built in since Emacs 29) or lsp-mode, each running typescript-language-server
Where its TypeScript comes fromDecided by typescript-language-server; with lsp-mode, lsp-clients-typescript-prefer-use-project-ts-server asks for the project's copy
Readsjsconfig.json, tsconfig.json
How this page was checkedNot run in Emacs for this page. The configuration is from Eglot's source and README and lsp-mode's TypeScript page linked below; what the server reports comes from TypeScript's language service, which the site's tests run.

Eglot

M-x eglot in a JavaScript buffer starts the server Eglot guesses for the mode. To start it automatically, add eglot-ensure to the mode hooks. Eglot passes the server's diagnostics to Flymake, which underlines them in the buffer.

init.el
;; Start Eglot (built in since Emacs 29) in JavaScript buffers
(add-hook 'js-mode-hook #'eglot-ensure)
(add-hook 'js-ts-mode-hook #'eglot-ensure)

lsp-mode, and the project's TypeScript

With lsp-mode, M-x lsp-install-server RET ts-ls installs the server. Per its documentation lsp-mode does not prefer the project's tsserver by default; set lsp-clients-typescript-prefer-use-project-ts-server so the editor runs the same TypeScript version as npm run lint.

init.el
;; lsp-mode: use node_modules/typescript, the version npm run lint uses
(setq lsp-clients-typescript-prefer-use-project-ts-server t)
(add-hook 'js-mode-hook #'lsp-deferred)

What differs from tsc

Diagnostics are reported for the buffers the server has open. Eglot also shows the diagnostic under point through ElDoc. TypeScript's suggestions (unused names with noUnusedLocals off, @deprecated names) come through as well; tsc never prints them.

Make sure it matches tsc

M-x compile with npx tsc -p jsconfig.json --pretty false runs the same check as CI in a compilation buffer. Open a file it reports and compare the codes with what Flymake shows.

Gotchas

  • When Eglot manages a buffer it turns off the other Flymake backends, per its README; eglot-stay-out-of changes that if you also run ESLint through Flymake.
  • Recent development versions of Eglot try another program before typescript-language-server for these modes; eglot-server-programs shows what your version uses.

Sources

Last reviewed 20 October 2026.