Using plugin as a store?

My editor is used in three different domains and has to receive the color scheme from each domain. Then the editor will show the nodes in each domain’s colors.

In order to do that, I had to make it receive the color scheme when the editor view is initiated. So I decided to create a colorPlugin that does nothing more than just holding the colors object as its state.

export const colorsPluginKey = new PluginKey('colorsPlugin')

export const colorPlugin = (colors) => new Plugin({
    state: {
        init() {
            return {
        apply() {
            return colors
    key: colorsPluginKey

I wonder if this approach is suggested or are there any better ways to make this work. I initially tried to remove apply() to prevent meaningless update but the error said to add it.

You could also add this as a ‘prop’, I guess (though TypeScript might need some convincing to allow it, the library supports props beyond the ones defined in the core—you can access them with someProp).

Lovely! Do you mean I can just add my own properties to the DirectEditorProps? I was looking for the ways to do something like that before I decided to use the Plugin as a state holder, but I couldn’t find the documentation on it.

You said that I can access my custom props via someProp, which is cool. But what is the suggested way to pass my custom props from outside to the EditorView?

Below is my snippet for initiating the editor view.

 * @param {{
 *  ref: HTMLElement,
 *  editorState: import('prosemirror-state').EditorState
 *  onTransaction: undefined | (tr: import('prosemirror-state').Transaction) => void
 * }}
export const buildEditorView = ({ ref, editorState, onTransaction }) => {
   * @type {import('prosemirror-view').DirectEditorProps}
  const directEditorProps = {
    state: editorState,
    attributes: {
    nodeViews: {
      image: imageNodeView,
      iframe: iframeNodeView,
      horizontal_rule: hrNodeView,
      custom_template: customTemplateNodeView
    handleDOMEvents: {
      mouseup: handlePMMouseup
    handleClick: handlePMClick,
    handleKeyDown: handlePMKeyDown,
    handlePaste: handlePMPaste,

  if (onTransaction) {
    directEditorProps.dispatchTransaction = onTransaction
  return new EditorView(ref, directEditorProps)

Exactly where your comment is in that code. Wouldn’t it have been faster to try that out, than to ask again here? Put foo: "bar" there, and then view.someProp("foo") will give you "bar".

Yeah I tried it out and saw it running right after I posted it. Sorry for bothering you.