Building a roam-like, networked, heavily-customized realtime editor, part 1
namiwang.github.io
namiwang.github.io
Also, why is that all these note-taking apps see everything as a list item? As for me, most of my writings are loosely structured scattered across paragraphs, quotes and codeblocks. Why isn’t this mainstream? Why is “Everything is a list item” winning?
I like to write related paragraphs as a nested bullet item. It helps scanning the content later.
I found out that I end up using lists more often than not, but I like the flexibility it offers.
Obsidian is closed source, and I’d say its features do not justify choosing that over Zettlr (unlike something like Notion.so)
Your approach is also kind of similar to Joplin (joplinapp.org), another open source, privacy-focused, and cross-device app, but you have more features.
Should be noted that the Core-Application is closed Source. The plugins are at the moment open source, or at least source available. I think the long term goal is to build on a rich plugin-ecosystem with a sleak core.
Also closed source doesn't really matter in this case, because it's build on open data-formats and running local. There is no vendor lockin. If the app disappears some day, you can still continue to use it or use a different markdown-editor (which are already existing today).
Of course a lot of these systems don't support it because MarkDown doesn't support it. An indented block is a code block and that's it.
I started putting together a Tiptap editor project, which itself is based on ProseMirror, but got overloaded. I also tried building something with CKEditor but also ran into too much personal friction trying to get a simple project working. I have to learn Node and JS at the same time and it's a lot.
It's a bit of a harsh criticism, but we are spatial creatures who live in a world full of objects that are organized into different forms. The "list" is a very valuable organizational structure and convenient to implement digitally, but it is a rather simple structure, being a 1D-structure. We use "lists" (in the form of shelves and stacks) to store objects and give the collection order, but in order to interact with objects, we remove them from their list and interact with them in higher dimensions (spreading out on a desk, pinning to a wall, arranging in space, etc). The fact that we only have 1D structures in most software UIs may well be that higher-order structures are too complex to practically implement or are not viewed as necessary, but again, this is an argument out of "laziness", convenience to the developer who is implementing the UI. Or, designers and developers genuinely believe that we are most-suited to composing with 1D structures (eye-roll).
The cross-linking patriarch of this category, Lotus Agenda, can still be run via DOS emulation: https://lock.cmpxchg8b.com/lotusagenda.html
And tinderbox I guess: http://www.eastgate.com/Tinderbox/
https://github.com/athensresearch/athens/
https://www.notion.so/Athens-67e1c6068cb449ff935d10e882fd9b0...
While mighty impressive, looking at the tech stack[1] for both Athens and Roam I can't help thinking this is too much to support my note taking (if I want to self host).
[1] https://www.notion.so/Athens-67e1c6068cb449ff935d10e882fd9b0...
Did not, just followed the development. It seems like an extremely ambitious undertaking.
0: https://www.kickstarter.com/projects/sunnyhirai/add-android-...
1: https://kitemaker.co, a super fast issue tracker/product management tool with deep integrations to your team’s favorite tools
Personally I cannot really get the hang of linked editors like this that only use links or basic tags for structure. They require too much upkeep to keep things organized. I'm working on my own solution that goes a different way, but it's nice to see more open source implementations of these types of editors.
Instead of having pages that contain blocks inside of them (like Roam), I decided to have just one type of item. These items can have other items as children and parents, and they also contain text content which can link (bidirectionally) to other items.
The main advantage of this approach is that items can have multiple parents. So in practice, you never have to think about whether a note should be its own page or just a block inside a different page. This just feels more elegant than Roam's approach to me.
The main disadvantage is that you're now working with a graph rather than a tree. You can end up with funky situations like an item that's its own parent. Since I still want the user to interact with the app through a tree-based UI, I have to add an intermediary data structure representing what the user can actually see. This data structure needs to be built lazily as the user expands and collapses items, so we don't try to represent an infinite loop.
Whenever the user does something (adds an item, edits it, creates a link, etc.), we need to update both the intermediary data structure and the persistent data -- and ensure that these changes are kept in sync. For example, adding a link is a simple change in the graph, but it may require multiple updates to the tree.[1]
I also ended up going with ProseMirror for the editor component (after trying Quill, Slate, an input-based approach and using contenteditable directly). I'm really happy with ProseMirror, even though integrating it wasn't entirely pain-free.[2]
---
[1] You can see the code for the tree-representation here if you're interested, although it's not necessarily written for public consumption: https://github.com/c2d7fa/thinktool/blob/master/src/client/s...
[2] The editor code is here: https://github.com/c2d7fa/thinktool/blob/master/src/client/s... -- same disclaimer as above.