skip to content
Edmund Miller

Setting up Doom Emacs for Astro Development

/ 4 min read

Astro is the new hot new web framework on the block. All the cool kids are using it. I’ve recently given up, drank the Kool-Aid, and gone all in on it.

I’ve rewritten this website, my partner’s website, my university rugby club’s website. I’m moving my Applied Genomics course website to Starlight, the Astro team’s documentation framework. The nf-core site has been rewritten in Astro and Svelte from PHP. I’m all in.

The beauty of Astro is it’s the Nextflow of web frameworks.1 It allows you to wrap other UI Frameworks in a web framework rather than forcing you to pick one so you don’t just have to pick React, Vue, or Svelte. You can have them all in the same application. You can just use HTML components. That’s the beauty. That’s why it’s exciting. That’s why I think it’ll stick around.

So anyways, I wanted to hook up Emacs with Astro support. For now, I’ve just been roughing it out there and running Prettier by itself and turning off save on format and auto-complete. It’s been scary.

What I’m seeking from Emacs is multifaceted: Tree-sitter support, LSP (Language Server Protocol) support—to alert me of any missteps—and a fully functional formatter. A frustrating hour was lost to Prettier mangling my Astro templates by wrapping them in quotes—a bug I could have done without. And while we’re at it, add Tailwind CSS LSP support into the mix for good measure.

Astro Tree-sitter Support

Tree-sitter is an incremental parsing system for programming tools. Find out more about it on the project’s website!

As the old saying goes, there’s an Emacs package for everything. So, of course, someone’s already written one for Astro and Tree-sitter.

Setup for astro-ts-mode appears simple:

package.el
(package! astro-ts-mode)
config.el
(use-package! astro-ts-mode
:after treesit-auto)

But wait there’s more!

Because this major mode is powered by Tree-sitter, it depends on an external grammar to provide a syntax tree for Astro templates. To set it up, you’ll need to set treesit-language-source-alist to point to the correct repositories for each language.

You can choose to set it up and run treesit-install-language-grammar for astro tsx and css.

Or you can take the red pill and use treesit-auto and automatically install the language grammar.

In case this your first Edmund experience, two things you should know. I love to automate things and I love a good rabbit hole.

treesit-auto

There was a tip from Ian S. Pringle(Who owns both a farm and a digital garden!).

Ruby Juric(the author of astro-ts-mode) converted the snippet to use let to avoid creating a global variable.

config.el
(use-package! astro-ts-mode
:config
(global-treesit-auto-mode)
(let ((astro-recipe (make-treesit-auto-recipe
:lang 'astro
:ts-mode 'astro-ts-mode
:url "https://github.com/virchau13/tree-sitter-astro"
:revision "master"
:source-dir "src")))
(add-to-list 'treesit-auto-recipe-list astro-recipe)))

I think this worked for me. I had built it manually with treesit-auto before.

Oh by the way

!NOTE Make sure you have a working C compiler as cc in your PATH, since this needs to compile the grammars.

Emacs lsp-mode and Astro Language-server

The official Astro editor docs link to an article with instructions to configure eglot, but there’s no equivalent one for lsp-mode.

Terminal window
npm i -g @astrojs/language-server

I just had to add a hook to astro-ts-mode and it pulled right up.

config.el
(use-package! astro-ts-mode
:after treesit-auto
:init
(when (modulep! +lsp)
(add-hook 'astro-ts-mode-hook #'lsp! 'append))
:config
;; ...

prettier-plugin-astro in Emacs with Apheleia

From Sorixelle’s Emacs config I found the magic snippet that had prettier use --parser=astro in .astro files. ✨

config.el
(set-formatter! 'prettier-astro
'("npx" "prettier" "--parser=astro"
(apheleia-formatters-indent "--use-tabs" "--tab-width" 'astro-ts-mode-indent-offset))
:modes '(astro-ts-mode))

Tailwind CSS IntelliSense in Emacs

Of course there’s already a package for TailwindCSS using LSP. With Doom Emacs installation instructions as well!

config.el
(use-package! lsp-tailwindcss
:when (modulep! +lsp)
:init
(setq! lsp-tailwindcss-add-on-mode t)
:config
(add-to-list 'lsp-tailwindcss-major-modes 'astro-ts-mode))

Conclusion

You can find all of the code in my Doom Emacs config. It’s got everything, Tree-sitter, LSP, Prettier, and Tailwind CSS IntelliSense.

Footnotes

  1. Did I really just compare a very niche DSL to describe a niche programming language?