The documentation is a Work in Progress and will be continuously improved and extended. We'd love to hear your feedback in our documentation repository.

Software Architecture and Philosophy is designed along several guiding principles: should work with nearly every technology stack.

The only assumption we make regarding your technology stack: the part of your app that integrates the editor needs to be able to render React components and users editing the content need to have JavaScript activated.

For rendering the content, you can work around those assumptions if they do not fit your use case (see also The overhead cost of rendering documents should be minimal compared to a barebone approach.).

Apart from that, you should be able to integrate into any app. We make no assumptions about how and where you persist your data.

The overhead cost of rendering documents should be minimal compared to a barebone approach.

We provide a lightweight React component that renders documents using the plugins you provide. This already enables you to adapt the integration to your specific use case, e.g.:

  • You can use a rendering approach that suits your use case the best (utilizing the existing React ecosystem).
  • You can optimize the bundle size for your end users (that view the content) by removing the parts that are only needed in the editor (e.g. toolbars).

If you need more customization, you can also write your own custom renderer for pretty much any output format. Since the document format is easy to traverse, you would only need to define how your plugins are rendered in that specific output format (see also The document format should be easy to work with).

It should be easy to develop plugins for existing React components.

An plugin is a React component that receives some props via

  • A state prop that allows you to save data to the document.
  • Some props containing runtime information, e.g. focused.
  • Some props that allow you to work with's UI, e.g. renderIntoToolbar.

Apart from that, your React component can do whatever it likes and utilize the existing React ecosystem. And as long as you tell when your state changes (via the state prop), it will behave as any other plugin (e.g. provide global undo/redo history).

Most of the's UI and behavior should be customizable.

You can customize nearly every aspect of if necessary, e.g.

  • @edtr-io/plugin-rows is an plugin that provides the Drag'n'Drop behavior. You can replace that with your own plugin if you want a different behavior.
  • The Editor component allows you to pass your own custom DocumentEditor. With this, you can replace the default UI we provide (e.g. by moving the toolbar somewhere else).

The document format should be easy to work with.

The serialized format of documents created by is a light-weight tree structure in JSON. It is also intended to be used/created outside of if necessary. This enables various use cases, for example:

  • You can convert your existing content that was not created with to's document format.
  • You can convert your content created by to some other format.
  • You can dynamically create a single document from multiple entities in your persistence layer.