minu

minu

Reason for switching from Monaco to CodeMirror?

I’ve noticed Livebook switched from Monaco to CodeMirror some time recently. That must’ve taken a non-trivial amount of work, I wonder what was the reason?

I’m asking because I’m implementing an app that has code editor for some features. It seems Monaco is easier to get started with, but has less options for customizing, perhaps that was the reason?

Marked As Solved

jonatanklosko

jonatanklosko

Creator of Livebook

When we first started Livebook, CodeMirror was in the process of a complete rewrite (v5 → v6), so Monaco was a clear choice at the time. It’s been some time since the rewrite happened and I run into some articles regarding CodeMirror, so reevaluated and decided it’s worth migrating. It was definitely work, though a major part was adding the parser for Elixir for good highlighting, and the collaborative editing bits, which we had to implement for Monaco in the past as well.

Monaco definitely has a ton of features that you would need when building a mini IDE, however it’s not that modular, so even with cherry-picked imports the bundle ends up being quite huge. Over time, there were quite a few cases where had to do hacky workarounds. There are APIs for adding custom features/elements, but it’s not the same level of power that CodeMirror gives you.

The CodeMirror extensible design is extremely thoughtful, it may require a bit to wrap your head around the abstractions, but once you do it is actually much fun to extend the editor. We successfully implemented all the features we needed, including collaborative editing, user cursors, completion, hover documentation, signature preview, diagnostics, and doctests indicators. Styling and theming with CodeMirror is also much easier, you can just write CSS for a bunch of classes. With Monaco it’s much harder, you end up overriding certain built-in styles with important rules, and themes specify colors for certain attributes, instead of using CSS freely.

I would give CodeMirror extra points for beautiful, extensive documentation covering all the options, conceptual guides, and examples. Monaco, even though it’s a massive project, basically exposes an auto generated API docs, with many of the options having little to no explanation. The CodeMirror author is also attentive to issues and questions posted on the forum.

So in summary, with CodeMirror you may need to put some extra work to get to the initial point you need, but it also gives you more power to make it into whatever you want. It also depends on the use case, for a simpler editor it may be that setting up CodeMirror is actually less work.

Here you can find the full configuration of the editor in Livebook.

I hope this clarifies the tradeoffs a bit, if you have specific questions let me know!

19
Post #3

Also Liked

sbuttgereit

sbuttgereit

The PR that implements the change offers some insights…

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

We're in Beta

About us Mission Statement