Music IDE: Lilypond in Visual Studio Code

I’ve previously done quite a bit of music composition using LilyPond. For the people who have never heard of it, it’s a text-based way of writing music and then having a program typeset it nicely for you. As an analogy: LilyPond:Finale :: LaTeX:Word. Even though I haven’t done any personal work with it for a while, I do have a spouse who’s a musicologist who often wants musical examples nicely typeset and readable.

Previously I’ve used a combination of vim, a terminal to run the command-line typesetting process, and a PDF viewer to accomplish this work. However, with a new laptop and new operating system came new ways of working; while all of the tools I just listed work fine in Windows too, I’ve been using Visual Studio Code recently for programming (with a vim key mapping, of course!) and thought I could probably apply it here too:

Basic LilyPond setup

And indeed you can. I added a few extensions to get started:

With just these two you already have most of the experience there if you can trigger the typesetting process somehow. If the PDF viewer is in an active tab, it doesn’t refresh when the file changes on disk, but if it’s in another tab, as above, it will refresh each time you switch back to it. This means you can’t use split tabs to have the input and PDF showing and refreshing at the same time, but you can use split tabs very nicely for transcription and comparing output with the original:

Comparing typeset results with a scanned PDF

Since you’re working in an IDE, you get a bunch of nice features built in for free: a file tree for your workspace, source control integration (nice if you use Git or similar on your scores – and why not, since they’re just plain text!), easy document switching, and more. In fact, one of the built-in concepts, Tasks, can be used to easily run the LilyPond typesetting process. To do so, you’ll need to add a custom task with a definition something like this:

	// See
	// for the documentation about the tasks.json format
	"version": "2.0.0",
	"tasks": [
			"taskName": "lilypond",
			"type": "shell",
			"options": {
				"cwd": "${fileDirname}"
			"command": "\"C:\\Program Files (x86)\\LilyPond\\usr\\bin\\lilypond.exe\" ${fileBasename}",
			"group": "build",
			"presentation": {
				"echo": true,
				"reveal": "always",
				"focus": false,
				"panel": "dedicated"
			"problemMatcher": []

This example is Windows specific, but easy to adapt to other platforms. Note that if you’ve set your integrated terminal shell to bash on Windows, you’ll need to override that for your LilyPond workspace with:

	"": "C:\\WINDOWS\\Sysnative\\cmd.exe"

Once you have that set up, Ctrl-Shift-B can be used to trigger typesetting the currently open LilyPond file, with the output in a dedicated terminal. With a bit more work, it would probably be possible to write a problem matcher for the output to detect warnings and errors, and mark the task as failed.

Running LilyPond from within VS Code

All in all, I’m very happy with this setup for now, and look forward to working with it more.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s