CodeMirror Editor with Folding and Themes — Free JS Snippet

CodeMirror Code Editor with Line Numbers, Folding and Themes · Forms · Plain HTML, CSS & JS · Live preview

CategoryForms

What's included

Features

Syntax highlighting for JavaScript, CSS and HTML using separate language modes
Line numbers and a code-folding gutter with fold arrows
Bracket matching, auto-closing brackets and active-line highlighting
Ctrl+/ comment toggling that adapts to each language
Soft-tab override that inserts spaces and indents selections
Four themes loaded from CDN stylesheets and switched at runtime
Font-size control that calls refresh() to keep the cursor aligned
Live status bar showing line, column, selection length and line count

About this UI Snippet

CodeMirror Code Editor — HTML, CSS & JavaScript

Screenshot of the CodeMirror Code Editor with Line Numbers, Folding and Themes snippet rendered live

A textarea cannot be a code editor. It has no syntax colouring, no line numbers, no bracket matching, no sensible indentation and no way to fold a block, and every one of those omissions shows up the moment someone pastes twenty lines of code. CodeMirror is the long-standing answer: a small, embeddable editor component that turns a div into something that behaves like a real editing surface. This snippet uses CodeMirror 5, the classic version that loads from a single script tag with no build step — it is the historical workhorse behind countless in-page editors, and it remains one of the easiest ways to get a capable editor onto a page.

CodeMirror 5 is modular in a way that is easy to misunderstand. The core file only provides the editing engine; everything else is an add-on you load separately and then switch on with an option. Language modes (javascript, css, htmlmixed) supply syntax highlighting and indentation rules. Add-ons provide features: matchbrackets highlights the partner of the bracket under the cursor, closebrackets inserts the closing half as you type, active-line marks the current line, and foldgutter with brace-fold adds the fold arrows in the margin. Loading a script does nothing on its own — the matching option (matchBrackets: true, foldGutter: true) is what activates it, and the gutters array must list the fold gutter for the arrows to appear.

Key handling shows where CodeMirror's design pays off. The extraKeys map binds Ctrl-/ to the built-in toggleComment command, which comes from the comment add-on and knows the comment syntax of the current mode — so the same shortcut writes // in JavaScript, /* */ in CSS and <!-- --> in HTML. Tab is overridden to insert two spaces rather than a literal tab character, and to indent a whole selection when text is selected, which is what people expect from a code editor.

Two small details prevent frustrating bugs. When the language changes, the snippet calls clearHistory() after setValue, so pressing undo does not walk back into the previous language's sample. And when the font size changes it calls refresh(), because CodeMirror caches character measurements for cursor and selection placement; without the refresh, the cursor drifts out of alignment with the text. The status bar reads the cursor and selection from cursorActivity to show line, column and selection length.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant like Claude to add a Run button that executes the code in a sandboxed iframe, persist the content to local storage, or port the editor to CodeMirror 6 modules.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build an embeddable code editor with CodeMirror 5.65 loaded from cdnjs (core script and CSS, plus modes and add-ons).

Requirements:
- Load the javascript, css, xml and htmlmixed modes and the matchbrackets, closebrackets, active-line, comment, foldcode, foldgutter and brace-fold add-ons, and enable each with its option (foldGutter needs the gutters array).
- Use extraKeys for Ctrl-/ toggleComment, Ctrl-Q folding and a Tab handler that inserts spaces or indents a selection.
- Provide language tabs that call setOption('mode') and setValue(), followed by clearHistory().
- Add a theme switcher (dracula, monokai, material-darker, eclipse) and a font-size selector that calls refresh().
- Show a status bar with line, column, selection length and line count from the cursorActivity event.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="cm-app">
  <div class="cm-bar">
    <div class="cm-group" role="group" aria-label="Language">
      <button type="button" data-lang="js" class="on">JavaScript</button>
      <button type="button" data-lang="css">CSS</button>
      <button type="button" data-lang="html">HTML</button>
    </div>
    <label class="cm-sel">Theme
      <select id="cmTheme">
        <option value="dracula">Dracula</option>
        <option value="monokai">Monokai</option>
        <option value="material-darker">Material Darker</option>
        <option value="eclipse">Eclipse (light)</option>
      </select>
    </label>
    <label class="cm-sel">Size
      <select id="cmSize"><option>13</option><option selected>14</option><option>16</option><option>18</option></select>
    </label>
  </div>
  <div id="cmHost"></div>
  <div class="cm-status" aria-live="polite"><span id="cmPos">Ln 1, Col 1</span><span id="cmSel"></span><span id="cmLen"></span><span class="cm-keys"><kbd>Ctrl</kbd>+<kbd>/</kbd> comment &nbsp; <kbd>Ctrl</kbd>+<kbd>Q</kbd> fold</span></div>
</div>

Step by step

How to Use

  1. 1
    Type some codeClick in the editor and type. Brackets close automatically and the matching bracket is highlighted.
  2. 2
    Fold a blockClick a fold arrow in the gutter, or press Ctrl+Q inside a function, to collapse it.
  3. 3
    Comment a linePress Ctrl+/ on a line or a selection. The comment style changes with the language.
  4. 4
    Switch language and themeUse the language tabs and theme menu. Each language has its own sample and syntax rules.
  5. 5
    Change the font sizeChoose a different size; the editor refreshes so the cursor stays aligned with the text.

Real-world uses

Common Use Cases

Playgrounds and documentation
Embed editable examples in docs. For linting feedback in the margin, see the CodeMirror JSON editor with a validation gutter.
ADMIN
Admin config and template editors
Let staff edit CSS, HTML or script snippets with real editor ergonomics.
Snippet and note-taking tools
A lightweight editor for saving code without a heavy IDE dependency.
Learning modular editor design
A clear look at CodeMirror 5's modes, add-ons and options model.

Got questions?

Frequently Asked Questions

Loading the add-on script is not enough. You must also enable it with its option, such as matchBrackets: true or foldGutter: true, and list required gutters.

Load that language's mode script and set the mode option to its name, for example "python" or "text/x-java".

CodeMirror caches character measurements. Refreshing forces it to re-measure so the cursor and selections line up with the text.

It is stable and simple to load without a build step. CodeMirror 6 is the modern rewrite with a different, modular API and better accessibility, if you use a bundler.

Call editor.getValue(). Use editor.on("change", handler) to react to edits.

Bind Tab in extraKeys to a function that calls replaceSelection with spaces, or indentSelection when text is selected.

Yes. Use the JSX, Vue, Angular or Tailwind export buttons on this page to convert the markup and styles. The behaviour comes from CodeMirror, so in a framework project install it with npm install codemirror (v5) or use the modular CodeMirror 6 packages instead of the CDN tag, create it in useEffect / onMounted / ngAfterViewInit on a host element, and release it with toTextArea() or removing the wrapper element when the component unmounts.