(API still subject to change - don't use this in production just yet)

A radically different (much simpler and lower level) approach to building text editors in the browser.

Join Zettel on Slack


Getting started with @zettel/core and @zettel/react

Right now we only have the packages core and react, you'll need those to get started.

yarn add @zettel/core @zettel/react

Now that you have them installed, here's a basic example of a plaintext editor:

import * as React from 'react';
import { useState } from 'react'
import { EditorState } from '@zettel/core'
import Editor from '@zettel/react'

const text = `[One 😅Line][And another line of text][And another line]`

const App = () => {
  const [editorState, setEditorState] = useState(() => EditorState.fromJSON({
    ranges: [],
    entityMap: {}

  return (
      htmlAttrs={{ spellCheck: false, autoFocus: true, className: 'editor'}}

export default App;

For more examples have a look here

Current Roadmap

This changes a lot. To focus as much as possible I'll keep this small.

  • Firefox, Safari, Chrome support
  • rendering text
  • render blocks
  • keeping selection in sync
  • All editing operations
  • render non-text media
  • react view layer
  • render text fragments
  • redo/undo
  • UTF-16 support for editing
  • IME Event handling
  • Android support (via Input Events Level 2) thanks Trix ❤️
  • IME support
  • rtl support
  • Support for parser integration
  • Prototype collaborative editing
  • Start writing docs and publishing exampples on codesandbox
  • Alternative view layers (Vuejs/svelte/angular)


This project wouldn't have come this far without the influence of open source projects such as: