eglot-python-preset and eglot-typescript-preset: Now on MELPA
Contents
Introduction
A quick follow-up to my earlier posts on eglot-python-preset and the beta multi-LSP release: both packages are now available on MELPA with full rassumfrassum↗ (rass) support included.
When I wrote the beta post in March, eglot-typescript-preset wasn’t on MELPA
at all, and eglot-python-preset’s MELPA version didn’t include rass support.
That’s no longer the case. You can install both with a standard use-package
:ensure t and get multi-LSP out of the box.
What Changed
The main thing that landed since the beta: MELPA now ships the rass backend for
both packages. This means the rass LSP server option and all the preset
generation machinery are available without cloning repos or managing load paths
manually.
Both packages also now set up Eglot integration automatically when Eglot loads,
so you no longer need an explicit (eglot-python-preset-setup) or
(eglot-typescript-preset-setup) call in your config. Just install and go.
Installation
Python
(use-package eglot-python-preset
:ensure t
:custom
(eglot-python-preset-lsp-server 'ty)) ; or 'basedpyright or 'rass
With the default ty backend, this gives you type checking for standard Python
projects and PEP-723 scripts with no further configuration. Switch to rass to
run ty and Ruff simultaneously:
(use-package eglot-python-preset
:ensure t
:custom
(eglot-python-preset-lsp-server 'rass)
(eglot-python-preset-rass-tools '(ty ruff)))
TypeScript
(use-package eglot-typescript-preset
:ensure t)
That’s it. The defaults configure typescript-language-server for TS/JS files
and use rass to combine language servers with Tailwind CSS support for CSS,
Astro, Vue, and Svelte buffers. If your project uses any of those frameworks,
the corresponding language server starts automatically when you open a file in
that mode.
To add linting alongside the TypeScript language server, switch the TS/JS backend to rass:
(use-package eglot-typescript-preset
:ensure t
:custom
(eglot-typescript-preset-lsp-server 'rass)
(eglot-typescript-preset-rass-tools
'(typescript-language-server eslint)))
Out-of-the-Box Multi-LSP
The part I’m most pleased with is how much works without any rass-specific configuration on the TypeScript side. The default settings for CSS, Astro, Vue, and Svelte all use rass, combining each framework’s language server with Tailwind CSS support automatically.
For Astro, this means astro-ls runs alongside ESLint and
tailwindcss-language-server in a single Eglot session. Vue gets hybrid mode
where vue-language-server handles template features and
typescript-language-server with @vue/typescript-plugin provides type
checking, plus Tailwind. Svelte works similarly.
On the Python side, the rass backend lets you run ty for type checking and
Ruff for linting in the same buffer. PEP-723 scripts work too: the generated
rass preset includes the script’s cached uv environment so both tools resolve
imports.
All of this resolves executables from project-local directories first
(node_modules/.bin for JS/TS, .venv for Python), falling back to your PATH.
Per-Project Configuration
Both packages support per-project overrides via .dir-locals.el or
dir-locals-set-directory-class. The preset variables are declared as safe
local variables, so Emacs applies them without prompting. For example, if one
project uses Biome instead of ESLint:
;;; .dir-locals.el
((typescript-ts-mode
. ((eglot-typescript-preset-lsp-server . rass)
(eglot-typescript-preset-rass-tools
. (typescript-language-server biome)))))
Links
- eglot-python-preset↗ on GitHub
- eglot-typescript-preset↗ on GitHub
- rassumfrassum↗, the LSP multiplexer by Eglot’s author
- Announcing eglot-python-preset, covering the initial release
- Beta: Multi-LSP support, covering the rass integration and eglot-typescript-preset introduction