SvelteKit with the Monaco Editor (2023)
What is the Monaco Editor?
The editor features built-in support for multiple languages, editing, linting, theming, diff mode, and much more. Check out Microsoft's interactive playground to learn more.
How-to: Integrating the Monaco Editor with SvelteKit
Importing the Monaco Editor into a project can be tricky, because the library is very large and comes with special trades like internal Web Workers that need to be dealt with.
Let's see how we can integrate the Monaco editor into a SvelteKit project.
As a first step, let's install the Monaco editor itself:
pnpm install -D monaco-editor
With this done, there are two ways we can integrate the editor into our SvelteKit app.
❎ Alternative 1: Directly using Vite (recommended)
We can integrate the Monaco editor directly using Vite and some glue code. I recommend this approach, as it gives you full control and isn't relying on additional dependencies. If this is not an issue to use, alternative 2 might be for you, too.
First, let's create a new file
monaco.ts in our project that contains the setup logic for the Monaco editor.
As you can see, the Monaco editor comes with several web workers to keep its UI fast. As required by the editor, we define
getWorker() so that the web workers will be loaded correctly (both in development and in production mode).
The special import syntax (the
?worker suffix) is described in Vite's documentation and seems to be the only way to avoid some ugly errors on the console later (although everything seems to be working).
Now we can define our page in Svelte:
And that's it 🙌🏼
Compared to alternative 2 (see below), this offers the following advantages:
- No additional dependencies in addition to the editor itself. Thus, you can update the
monaco-editorpackage whenever you want to
- Full control over what gets loaded when and how
- No reliance on external systems (no CDN)
❎ Alternative 2: Using
As an alternative to the aforementioned alternative 1 (which I recommend), you can also load the Monaco editor using the dedicated
This is less flexible and means an additional dependency for our project, but it is less notchy and requires less code on our side.
Lets install the loader library:
pnpm install -D @monaco-editor/loader
I guess your editor is only truly "powerful" if there is a separate library to load it 😉
Without further ado, lets create our Svelte page. The main difference compared to alternative 1 is in the
And that's it 🙌🏼
Compared to alternative 1, this approach offers the following advantages:
- Less code that you have to write yourself
- The possibility to use a content delivery network (CDN), which can reduce your bandwidth requirements (see comment in
A couple of points I want to note:
- in the
onMount()method, we load the monaco library when our page is initialized in the browser. We load our local version of the editor and don't use the default CDN that the monaco-loader library uses internally (which is jsdelivr).
- Note that setting the editor up in
onMount()also means that there is no server-side rendering (SSR) for the editor.
- in the
onDestroy()method, we clean up the monaco editor state by calling
dispose()on all editor models (think: files)
- The setup described in this post was tested with the following versions:
Thanks for reading. Happy coding!