# Generalized State Architecture

**URL:** <https://discuss.prosemirror.net/t/generalized-state-architecture/3908>\
**Category:** Uncategorized\
**Created:** [July 20, 2021, 8:28am UTC](https://discuss.prosemirror.net/t/generalized-state-architecture/3908 "2021-07-20T08:28:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ccorcos](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/ccorcos/32/1786_2.png) [@ccorcos](https://discuss.prosemirror.net/u/ccorcos)\
**Post date:** [July 20, 2021, 8:28am UTC](https://discuss.prosemirror.net/t/generalized-state-architecture/3908/1 "2021-07-20T08:28:42Z")

</div>

I’m working on a ProseMirror application that’s starting to get reasonably complex outside of ProseMirror.

I realized that I really liked the architecture of ProseMirror (the plugin system is awesome) and I wanted to see if I could generalize an entire React frontend state management with a similar structure and actually route all transactions through a global state system.

I ended up building 3 different prototypes ([live demo here](https://ccorcos.github.io/prosemirror-architecture/), just a text editor with multiple tabs):

- [Using ProseMirror architecture with state classes](https://github.com/ccorcos/prosemirror-architecture/blob/master/src/components/App.tsx)
- [Using Elm Architecture with plain JSON state](https://github.com/ccorcos/prosemirror-architecture/blob/pure-elm/src/components/App.tsx)
- [Using ProseMirror architecture for the editor and Elm Architecture (pure functional) for the rest](https://github.com/ccorcos/prosemirror-architecture/blob/elm-pm/src/components/App.tsx)

The reason I’m posting here is because I’m trying to understand:

> **why is `EditorState` a class as opposed to a plain JSON object?**

This decision seems to run pretty deep, all the way down to the Node and Selection classes. It seems like the only reason to use a class is to add helper methods to the classes for syntactic convenience. Is that correct?

To give you some context: in the first example, I model every state object as a class like:

```auto
class SomeState {
  apply(action): SomeState
  toJSON(): any
  static fromJSON(json): SomeState
}

```

In the second example, there are no classes and everything is pure-functional.

```auto
type StateMachine<S, A> = {
	init: () => S
	update: (state: S, action: A) => S
}

```

The first one needed 458 lines of code whereas the second needed 364 lines of code: 20% less. This can be accounted for by the fact that the pure functional example doesn’t need any serialization/deserialization.

In practice, I can imagine that using classes is really convenient when the state model is really complicated. Methods like `node.childAfter()` would need to be functions like `childAfter(node)` meaning you have to import a bunch of methods all of the time. Also `state.tr` would need to be `new Transaction(state)`…

In any case, I was hoping maybe you (@marijn) could share some of your thoughts on these trade-offs. Did you consider a pure-functional approach and if so, what led you to your decision to use classes?

Thanks,

Chet

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [July 20, 2021, 2:36pm UTC](https://discuss.prosemirror.net/t/generalized-state-architecture/3908/2 "2021-07-20T14:36:16Z")

</div>

> [@ccorcos](#):
>
> It seems like the only reason to use a class is to add helper methods to the classes for syntactic convenience. Is that correct?

No, it is also so that we can control the internal data structures used in order to optimize functional updates and possibly other things. See for example the use of [rope-sequence](https://github.com/marijnh/rope-sequence) in the undo history, and at one point I was planning to use a representation other than a flat array for very long fragments (though that turned out to not be enough of a win to justify the complexity).

---

<div class="post-metadata">

**Author:** ![ccorcos](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/ccorcos/32/1786_2.png) [@ccorcos](https://discuss.prosemirror.net/u/ccorcos)\
**Post date:** [July 21, 2021, 12:23am UTC](https://discuss.prosemirror.net/t/generalized-state-architecture/3908/3 "2021-07-21T00:23:34Z")

</div>

I see. So you things like serializing to a JSON array but but using a LinkedList internally… That makes sense!
