# Real-Time Collaboration on a Note - Project

**URL:** <https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486>\
**Category:** Real-Time Collaboration\
**Created:** [20 May 2021 16:45 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486 "2021-05-20T16:45:25Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [20 May 2021 16:45 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/1 "2021-05-20T16:45:25Z")

</div>

# Collaboration on a Note: Project Details.

## Summary:

This project aims to develop a plugin that generates a link to collaborate for a selected note, along with a web app consisting of a real-time collaborative editor. The web app has 2 main routes containing the owner app(for the one who has the note) and a peer app (for other users). the owner app should run on the desktop where the note resides. The owner app fetches the note and also saves the changes using the Joplin Data API.

## Implementation Details:

#### The key features that are added to Joplin through this project:

- **A web application using ReactJS and YJS.** Where these collaborative notes can be handled or viewed. The Editors implemented in Joplin (using CodeMirror) will be the base for the UI. The changes and Conflicts in the note are handled by YJS. YJS perfectly fits Joplin, as YJS provides libraries that handle editor libraries like CodeMirror. YJS also handles the server-less model for clients to edit the note and sync with other users(peer-to-peer connection through WebRTC). This web app will be served by Joplin Server.Reference Link: [Yjs · GitHub](https://github.com/yjs)Reference Blog: [[Tutorial]How to build a real-time collaborative app using CRDT in angular? | by Alen George | BlockSurvey | Medium](https://medium.com/blocksurvey/tutorial-how-to-build-a-real-time-collaborative-app-using-crdt-in-angular-44098525d5b)
- **A Signalling Server.** This is a simple WebSocket Server for signaling. Signaling is basically the procedure to establish a WebRTC connection(peer-to-peer connection) between the clients.  
Read more on Signalling [here](https://www.tutorialspoint.com/webrtc/webrtc_signaling.htm)
- **Plugin: Collaborate on a Note.** The plugin adds options to collaborate on a note. When the option is clicked, The plugin generates a link for the owner - attached with the auth token for the Joplin Data API and the selected note's id. The owner gets a share option in the web app to get the peer URL for the collaborative session. Which can be shared and used by other users to join the particular session.

## Flow Diagram:

![CommunicationFlow.jpeg](https://media.discordapp.net/attachments/844398267819098142/849357586888654848/CommunicationFlow.jpeg?width=1440&height=635)

## Project Timeline:

#### Week 1 - 3

Creating a react app with a basic structure setup.

1. Setup the basic structure of the web app
2. Implementation:

- Initial redux store.
- Routes in the web app.
- A basic UI with CodeMirror.
- Utils related to Data API, YJS WebRTC connections, and Editor bindings.

1. Write tests and Document the code developed.

#### Week 4 - 5

Creating a Signalling Server and a Plugin.

1. Implementing a basic signaling server.
2. Implementing Collaboration on a Note Plugin which:

- Adds UI components for the Plugin.
- Adds Handlers for the added UI Components.

1. Test and Document the code developed.

#### Week 6

Testing, debugging and handling edge cases for the current stack.

#### Week 7 - 8

Adding toolbar for the editor.

1. Implementing toolbar related code:

- Utils
- UI component
- Handlers for the toolbar functions

1. Write tests and Document the code developed.

#### Week 9 - 10

Adding persistence (to store offline changes in browser), testing, and cleanup.

**note:** In our use-case, Implementing persistence is a bit tricky and I'm researching more on it.

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [20 May 2021 16:48 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/2 "2021-05-20T16:48:42Z")

</div>

reserved for future content 1

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [20 May 2021 16:48 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/3 "2021-05-20T16:48:49Z")

</div>

reserved for future content 2

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [20 May 2021 16:48 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/4 "2021-05-20T16:48:55Z")

</div>

reserved for future content 3

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [20 May 2021 16:49 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/5 "2021-05-20T16:49:03Z")

</div>

reserved for future content 4

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [21 May 2021 21:25 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/6 "2021-05-21T21:25:32Z")

</div>

> [@Aksh-Konda](#):
>
> **API endpoints added to Joplin Server API.** The endpoints that are used by the real-time collaboration on a note feature will be added to the Joplin server API.

Could you describe what kind of end point you have a in mind? The server can already read and write notes so maybe you don't need to do anything for this. As long as you have the note ID you can update a note or read it back.

Also I think what's missing from your plan is what you plan to release and when. I think this project can be split into smaller parts that can be released independently, which will allow users to test your project earlier.

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [22 May 2021 04:58 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/7 "2021-05-22T04:58:52Z")

</div>

> [@laurent](#):
>
> The server can already read and write notes so maybe you don't need to do anything for this.

yes, but I think there should be a server route that handles the WebSocket communication which is used by the client web app to collaborate in real-time. like changes in one client application are sent to the server and the server should emit those changes to other client applications that are connected to the current collaborative session.

> [@laurent](#):
>
> Also I think what's missing from your plan is what you plan to release and when.

Thanks for pointing it out! I will add them.

> [@laurent](#):
>
> I think this project can be split into smaller parts that can be released independently, which will allow users to test your project earlier.

Like developing a basic functional feature and adding more functionality over it?

> [@laurent](#):
>
> project can be split into smaller parts that can be released independently

Sorry, I didn't really get this.

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [22 May 2021 05:03 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/8 "2021-05-22T05:03:30Z")

</div>

> [@Aksh-Konda](#):
>
> yes, but I think there should be a server route that handles the WebSocket communication which is used by the client web app to collaborate in real-time.

or I think it should be a separate server which is both serving up the client app and handling the communication between clients using websockets.

---

<div class="post-metadata">

**Author:** ![roman\_r\_m](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/roman_r_m/32/3297_2.png) [@roman\_r\_m](https://discourse.joplinapp.org/u/roman_r_m)\
**Post date:** [22 May 2021 05:47 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/9 "2021-05-22T05:47:40Z")

</div>

Isn't Yjs and CRDT in general use direct p2p communication? In this case introducing a server might be additional overhead both in terms of dev time and at runtime.

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [22 May 2021 06:28 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/10 "2021-05-22T06:28:59Z")

</div>

> [@roman\_r\_m](#):
>
> Isn't Yjs and CRDT in general use direct p2p communication

yes, but I think it needs a server that can trigger it... I'll do some more research on this and update it!

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [22 May 2021 07:42 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/11 "2021-05-22T07:42:50Z")

</div>

> [@Aksh-Konda](#):
>
> Like developing a basic functional feature and adding more functionality over it?

Indeed that's what I meant.

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [22 May 2021 10:04 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/12 "2021-05-22T10:04:24Z")

</div>

> [@roman\_r\_m](#):
>
> Isn't Yjs and CRDT in general use direct p2p communication?

yes, there is a library provided by yjs: [y-webrtc](https://github.com/yjs/y-webrtc)

> [@Aksh-Konda](#):
>
> yes, but I think it needs a server that can trigger it

also, as I said earlier it needs a signaling server for a new client to connect to other clients in a room. It is a basic server that doesn't have too much load as it is only pointing a new client to clients who are already in the room.

There are public signaling servers available for this. But there are issues reported by users of y-webrtc that the signaling isn't working over different networks.

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [22 May 2021 10:21 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/13 "2021-05-22T10:21:27Z")

</div>

> [@Aksh-Konda](#):
>
> also, as I said earlier it needs a signaling server for a new client to connect to other clients in a room. It is a basic server that doesn't have too much load as it is only pointing a new client to clients who are already in the room.

Ok that makes sense. If this server really is necessary, I think your best option is to create a separate one so that it can be installed and managed separately from Joplin Server.

---

<div class="post-metadata">

**Author:** ![roman\_r\_m](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/roman_r_m/32/3297_2.png) [@roman\_r\_m](https://discourse.joplinapp.org/u/roman_r_m)\
**Post date:** [22 May 2021 11:01 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/14 "2021-05-22T11:01:30Z")

</div>

I'm actually not convinced that a server is needed and if it is, it should be separate from the Joplin server.

Consider this - to initiate a shared editing session you probably won't just press a button and expect the other person to accept; instead you will most likely agree on specific time and so you might as well send them a direct link to connect to your Joplin via some other channel, e.g. email or whatsapp. In this scenario a server is not needed thus reducing the scope, which I think it very important for this project as it's already huge.

Now, if we are going to have a server maybe it should be part of Joplin server to fully leverage its sharing functions. Suppose you and I are editing a document together and you insert a picture, I am going to see just the id which isn't very helpful.  
With the Joplin server it can be shared automatically so that we both can see the picture.  
This may be out of scope for GSoC but it's something to consider.

Btw, if we decide to have a server, we'll need an API for a plugin to show some kind of popup notification, I don't think it's possible currently?

---

<div class="post-metadata">

**Author:** ![PackElend](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/packelend/32/488_2.png) [@PackElend](https://discourse.joplinapp.org/u/PackElend)\
**Post date:** [23 May 2021 10:48 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/15 "2021-05-23T10:48:38Z")

</div>

Hi,  
I read through all proposal and discussion in this matter: Trying now to summarize it, it may help in this discussion.  
The technologies mentioned in the proposal and other private discussion are pretty much the same as mentioned in [Joplin Server pre-release is now available - Development - Joplin Forum (joplinapp.org)](https://discourse.joplinapp.org/t/joplin-server-pre-release-is-now-available/13605) and [Any suggestions on what web technology could be used to add support for sharing notes? - Development - Joplin Forum (joplinapp.org)](https://discourse.joplinapp.org/t/any-suggestions-on-what-web-technology-could-be-used-to-add-support-for-sharing-notes/10145/1).

These TECHNOLOGIES are:

1. [yjs/yjs: Shared data types for building collaborative software (github.com)](https://github.com/yjs/yjs)
2. [Convergence: The Real-Time Collaboration Engine](https://convergence.io/)
3. [jsfiddle/togetherjs: A service for your website that makes it surprisingly easy to collaborate in real-time. (github.com)](https://github.com/jsfiddle/togetherjs)
4. [Socket.IO](https://socket.io/)
5. [WebRTC](https://webrtc.org/)
6. [bontaq/textdb: The whole shaboodle for textdb, a simple data sharing service (github.com)](https://github.com/bontaq/textdb)
7. [ShareDB](https://github.com/share/sharedb).
8. [Gun](https://gun.eco/)
9. [Automerge](https://github.com/automerge/automerge)

In addition, EXAMPLES are referenced:

1. [Use Microsoft Live Share to collaborate with Visual Studio Code](https://code.visualstudio.com/learn/collaboration/live-share)
2. [An Online Visual Collaboration Platform for Teamwork | Miro](https://miro.com/index/) and [Figma: the collaborative interface design tool.](https://www.figma.com/) to show collobartion could be visualized. I used Miro once and liked the way, the cursor of others is shown.
3. [This Is How to Build a Collaborative Text Editor Using Rails | Aha!](https://www.aha.io/blog/text-editor) what is a good instruction how to implement this
4. [Conclave Case Study - A private and secure real-time collaborative text editor (conclave-team.github.io)](https://conclave-team.github.io/conclave-site/) another instructions as 4. but in much more detail
5. [Textdb](https://textdb.dev/)
6. [JSFiddle - Code Playground](https://jsfiddle.net/) what uses [Mozilla Labs : TogetherJS](https://togetherjs.com/)
7. [Synchronization · zadam/trilium Wiki (github.com)](https://github.com/zadam/trilium/wiki/Synchronization) as it mentions [Conflict resolution](https://github.com/zadam/trilium/wiki/Synchronization#conflict-resolution), what is another GSoC project, #Conflict Resolution.

* * *

@Aksh-Konda, you create a new topic or put it somewhere else, whatever suits you best and do a final compare of the technologies available, similar to [Convergence Labs: Choosing a real-time collaboration library](https://convergencelabs.com/realtime-collaboration-technology-guide/).  
Tell if:

1. server is needed
2. if so, if server can be provided as docker, e.g. [Docker NodeJS Socket.io tutorial (dockerize.io)](https://dockerize.io/guides/node-socket-giude)
3. activity on the repository (project alive, issue closed within a reasonable time etc.)
4. basic implementation into Joplin

This shall happen rather soon

* * *

If we come to the conclusion that a server is required, it shall be easily deployable.  
It may be merged into the Joplin Server, if all runs stable and implementation is not much of a big deal.

* * *

> [@Conflict Resolution Plugin](https://discourse.joplinapp.org/t/conflict-resolution-plugin/17489/11):
>
> I'd say not, the whole point of real-time collaboration is to avoid conflicts while editing.

For sure but I can imagine if you edit something that is deleted by someone else you are going to have a conflict that cannot be avoided.  
I could imaging that in that case, the user, who changed something in the changed section, should be asked if the removal should be applied and sync of this part is frozen until this is resolved.  
Anything else should happen without a conflict. The only challenge is how to keep the overview if a lot of changes are done, avoiding that your cursor jumps up and down the note etc.

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [23 May 2021 11:53 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/16 "2021-05-23T11:53:37Z")

</div>

> [@PackElend](#):
>
> @Aksh-Konda, you create a new topic or put it somewhere else, whatever suits you best and do a final compare of the technologies available, similar to [Convergence Labs: Choosing a real-time collaboration library](https://convergencelabs.com/realtime-collaboration-technology-guide/).

Sure! I'm on it!

---

<div class="post-metadata">

**Author:** ![PackElend](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/packelend/32/488_2.png) [@PackElend](https://discourse.joplinapp.org/u/PackElend)\
**Post date:** [23 May 2021 12:51 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/17 "2021-05-23T12:51:34Z")

</div>

great, looking forward to the results 🙂

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [23 May 2021 17:23 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/18 "2021-05-23T17:23:48Z")

</div>

> [@PackElend](#):
>
> @Aksh-Konda, you create a new topic or put it somewhere else, whatever suits you best and do a final compare of the technologies available, similar to [Convergence Labs: Choosing a real-time collaboration library](https://convergencelabs.com/realtime-collaboration-technology-guide/).  
> Tell if:
> 
> 1. server is needed
> 2. if so, if server can be provided as docker, e.g. [Docker NodeJS Socket.io tutorial (dockerize.io)](https://dockerize.io/guides/node-socket-giude)
> 3. activity on the repository (project alive, issue closed within a reasonable time etc.)
> 4. basic implementation into Joplin

The new topic is posted [here](https://discourse.joplinapp.org/t/which-library-to-be-used-for-real-time-collaboration-on-a-note/17538).

---

<div class="post-metadata">

**Author:** ![PackElend](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/packelend/32/488_2.png) [@PackElend](https://discourse.joplinapp.org/u/PackElend)\
**Post date:** [26 May 2021 12:32 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/19 "2021-05-26T12:32:30Z")

</div>

> [@Aksh-Konda](#):
>
> Create a web app for Real-Time Collaboration.

do we really need an additional web app, as that requires some development work.  
Should we rather focus to have the features well integrated in the existing apps.  
Check with [Joplin Web - Web application companion for Joplin - #111 by foxmask](https://discourse.joplinapp.org/t/joplin-web-web-application-companion-for-joplin/555/111) on the support of plug-ins at the web-companion.

As you have done a check on the libraries.  
could you describe #### Week 1 - 2 in more detail?  
I would like to see milestones / interaction loops how to add feature by feature

---

<div class="post-metadata">

**Author:** ![Aksh-Konda](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/aksh-konda/32/8020_2.png) [@Aksh-Konda](https://discourse.joplinapp.org/u/Aksh-Konda)\
**Post date:** [26 May 2021 14:48 UTC](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486/20 "2021-05-26T14:48:24Z")

</div>

> [@PackElend](#):
>
> do we really need an additional web app

I think the [GSoC idea](https://joplinapp.org/gsoc2021/ideas/#4-real-time-collaboration-on-a-note) wanted the student to develop a web app:

> Expected Outcome: A web application that allows users to collaborate on a note

> [@PackElend](#):
>
> as that requires some development work.

However this is true.

> [@PackElend](#):
>
> Check with [Joplin Web - Web application companion for Joplin - #111 by foxmask](https://discourse.joplinapp.org/t/joplin-web-web-application-companion-for-joplin/555/111) on the support of plug-ins at the web-companion.

I didn't see this, it's Great!. (accessing local Joplin notes from wherever we want...). I'll look into it.

> [@PackElend](#):
>
> As you have done a check on the libraries.  
> could you describe #### Week 1 - 2 in more detail?  
> I would like to see milestones / interaction loops how to add feature by feature

#### week 1-2

> [@Aksh-Konda](#):
>
> Creating routes needed for Real-Time Collaboration.
> 
> 1. Create endpoints to store a note for real-time collaboration.
> 2. Implement the routes using WebSockets which handles sessions and collaboration.
> 3. Write tests and Document the code developed.

- I thought of creating similar end-points to share notes. where this end-point enables real-time collaboration on a note and which lets the web application save the changes to the note which has collaboration enabled.
- As we have now decided to go with a P2P (WebRTC) connection instead of WebSockets, I need to create a signaling server. (which establishes a peer to peer connection)

#### milestone

Creating the basic backend server for the web app to use.

[Next page](https://discourse.joplinapp.org/t/real-time-collaboration-on-a-note-project/17486.md?page=2)
