DEV Community

Cover image for I built a code editor library because Monaco frustrated me
PFMCODES
PFMCODES

Posted on

I built a code editor library because Monaco frustrated me

I built a code editor library because Monaco frustrated me

Monaco was slow, buggy, and the syntax highlighting wasn't even that good. So I built my own.

Caret is a lightweight code editor library built on the EditContext API. 605 lines of code. ~32KB. Loads in ~25ms.


Why not CodeMirror or Monaco?

Monaco was my go-to for other projects. But after dealing with slow load times, sync bugs, and unreliable highlighting, I decided to start from scratch. The first version shipped in a few days. The current version is a complete rewrite — cleaner, faster, and a fraction of the size.

Here's how it compares:

Caret Monaco CodeMirror 6
Bundle size ~32KB ~5MB ~400KB
Load time ~25ms ~2-3s ~500ms
Lines of code 650 ~300,000 ~50,000
Architecture EditContext textarea contenteditable

Load time on Chrome

~25ms load

Load time on Edge

~27ms load


The architecture

Previous versions used a textarea-based input model, which caused constant caret synchronization issues. The current version (v0.3+) is built entirely on the EditContext API — a browser API designed specifically for custom editors. It gives direct control over text input with no hacks.

How it works under the hood:

  1. EditContext receives all keyboard input, IME, and clipboard events
  2. A single string text is the source of truth — no dual-layer sync issues
  3. render() calls hljs.highlight() and updates the DOM
  4. The caret is positioned via Range.getBoundingClientRect() — no canvas math
  5. Undo/redo is a pure string stack storing both content and cursor offset

The codebase is split into five focused modules:

  • textEditor.js — core editor logic (400 lines)
  • caret.js — pixel-perfect caret positioning via Range API
  • lineCounter.js — line number tracking
  • font.js — custom font loading
  • languages.js — Highlight.js language registration

Features

  • Live syntax highlighting via Highlight.js
  • Custom caret rendering via Range API
  • Smart indentation — Tab/Shift+Tab for code blocks
  • Full undo/redo stack with cursor position restoration
  • Arrow key navigation with column preservation
  • Read-only lock mode
  • Multiple editor instances on the same page
  • Custom font support
  • Plain text paste — no rich HTML bleed
  • Browser detection with a friendly error for unsupported browsers

Themes supported: Tokyo Night, Monokai, GitHub Dark, Atom One Dark, Nord, Night Owl, VS2015, and more.

Languages supported: JavaScript, Python, HTML, and anything Highlight.js covers.


Quick start

Quick Start.gif

npm install @pfmcodes/caret
Enter fullscreen mode Exit fullscreen mode
<!DOCTYPE html>
<html>
<head></head>
<body>
  <div id="editor"></div>
  <script type="module">
    import Caret from 'https://esm.sh/@pfmcodes/caret';

    const editor = await Caret.createEditor(
      document.getElementById('editor'),
      '// Start coding...',
      {
        id: 'my-editor',
        dark: true,
        language: 'javascript',
        hlTheme: 'tokyo-night-dark'
      }
    );
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Browser support

Caret v0.3+ uses the EditContext API, which is currently only available in Chromium-based browsers (Chrome, Edge). Firefox and Safari are not supported yet — Firefox tracking issue here.


Links

Top comments (3)

Collapse
 
adelodunpeter profile image
Adelodun Peter • Edited

monaco editor is not just syntax highlighting, it fully powers vscode, all line formatting, code issues highlight
but i get where you are coming from and this is a very nice project, some of us don't actually need full monaco

Collapse
 
pfmcodes profile image
PFMCODES

i built it out of frustation of complexity, i admire speed and small bundle size, that's why i built caret. vs code uses extra modules for better syntax highlighting, i simply used highlight.js, strip of all that extra modules and code you have base monaco, and its syntax highlighting is not that good as they showcase on their demo website

Collapse
 
adelodunpeter profile image
Adelodun Peter

It works