Here’s “Why?”, “How?”, and other questions answered!
In software development, Markdown is basically omnipresent. You can find it in READMEs, powering software blogs, and serving as one of the primary content formatting methods when Rich Text Editing (RTE) is required.
Markdown is awesome! But, when writing 1000 words+ articles, I quickly feel the need for a better experience. For years, I’ve used StackEdit — an open-source, in-browser Markdown editor — for editing all kinds of long-format Markdown text. That said, given my recent experience with WYSIWYG editors, I thought I could do something better.
That’s how I created Vrite Editor — an open-source Rich Text Editor, focused on good user experience and technical writing.
No good tool is built without using good tools, and Vrite Editor is no different. Before getting into WYSIWYG editors, I extensively researched available RTE frameworks, that could provide the tooling and functionality I was looking for. Ultimately, I picked TipTap and underlying ProseMirror — IMO, the best tools currently available for all kinds of WYSIWYG editors.
Aside from that, I used:
Solid.js — the super-fast UI framework;
UnoCSS — for styling with Tailwind-like atomic CSS;
Vite — build tool for putting it all together;
The results came out pretty nicely! 🌟
Features & Behind the Scenes
Vrite Editor comes with many features to make editing a breeze! You can check them all out in the official documentation. That said, there are a few unique ones that I feel are worth diving deeper into.
Something that I always felt was lacking in WYSIWYG editors (even the top ones, like Notion) is good support for code editing. Granted, technical writing is a niche use-case and you can get by with simple syntax highlighting and some copy-pasting. That said, I wanted to try something else — I wanted to integrate a full-blown code editor.
By referencing the ProseMirror docs, forwarding the editor state back and forth, and adjusting the layout, I managed to integrate Monaco Editor — the web editor extracted from VS Code — together with Prettier (for code formatting) right into the Vrite Editor (I know, that’s a lot of editors in one place 😅).
The “whole grail of WYSIWYG editing” (as stated in the TipTap docs) took a while to get right. While TipTap provides extensions for supporting Table formatting, the UI is a different story. Table formatting UIs are notoriously difficult to get right. That’s why I was quite happy when I finally felt like I built something that was… alright.
When your cursor is inside the table, you’ll see a bottom menu appear, which you can use e.g. insert and remove rows, columns, and headers. On the other hand, when you select some cells, you’ll see a menu to e.g. merge, split, or delete them. It’s not Excel-level but, for an inline table, I think it’s pretty good.
Handling Markdown pasting was a surprising challenge. Naturally, you’d expect an editor that works with Markdown to be able to parse and properly load the Markdown you pasted, so some work had to go into that.
TipTap provides input rules to handle so-called “Markdown shortcuts” while typing, and paste rules for offering the same parsing functionality while pasting. The problem is, paste rules work line-by-line, which means parsing something like a blockquote, codeblock, or a list, just isn’t possible.
To handle pasting block Markdown content like this, I had to tap into ProseMirror and implement a custom mechanism (though somewhat based on TipTap’s paste rules), detecting starting and ending points of the blocks and parsing them with Marked.js.
Thankfully, with this done, most Markdown can be pasted freely into the editor and should be parsed just fine!
The other thing that's quite hard to get right in a web-based WYSIWYG editor, is mobile support.
Initially, I thought that a good editing experience on the mobile platform can only be achieved with a native mobile app, so why bother trying to get it right on the mobile web?
Well, ultimately I tried to add mobile support to Vrite Editor anyway, and, to my surprise, it turned out pretty good!
There were many things that needed optimization — and some that still do. From the general layout, toolbar, and the UI of block elements to formatting and block content menus — everything had to be in some way optimized or completely changed for mobile.
Now, there’s still some work to be done here. Monaco editor doesn’t work well for mobile, and some “optional” features weren’t yet optimized (like link previews or comments).
Still, with the work already done, Vrite Editor is usable and actually quite comfortable on mobile.
By the way, I did write this section on my phone. 😊
Now, with the editor working, the last important part was to output Markdown. TipTap provides methods to retrieve both HTML and ProseMirror JSON representations of the content. I decided to use the JSON (since it’s easier to work with) and created functions to transform it into various outputs. I called these “Content Transformers”.
Using Content Transformers I created an “Export” menu, outputting the content in HTML, GitHub Flavored Markdown (GFM), and ProseMirror JSON (e.g. for custom processing) to a Monaco Editor, with options to download or copy it.
While there might be better ways to do this, this one provides a lot of flexibility and makes sure your content can be properly processed to Markdown or any other format you need.
In case you enjoy using Vrite Editor, you might be interested in a larger project that it’s a part of — “Vrite CMS”, or simply “Vrite”.
Vrite is a headless CMS for technical content, providing editing and management tools to work with content like technical product documentation, programming blogs, etc. Basically, it’s my answer to (what I consider) a lack of good tooling focused on this kind of content.
Beyond just the Vrite Editor, you get additional features, like:
Kanban dashboard for content management;
API and Webhooks;
Extension system for easy publishing to popular platforms;
Since Vrite (and Vrite Editor for that matter) is currently in Public Beta, new features and improvements are in active development. The best way to try it out right now is through the hosted version at app.vrite.io (free while in Beta) with better self-hosting support in the works.
In any case, if you’re interested in technical writing, definitely check out Vrite Editor and Vrite as a whole. Also, leave a 🌟 on GitHub, as well as any feature requests or issues you may have, to support the project. ❤️