Chat V2
There is a Proof-of-Concept (PoC) available, but it is not a functioning app and subject to change.
Glitr UI demo
Goals
- End-to-end encryption (E2EE)
- Peer-to-peer (P2P)
- Decentralized
- Progressive web app (PWA)
- User-friendly
- Privacy-focused
- Cross-platform (web, mobile, desktop)
- Offline-first (sync when online)
- Secure (no data leaks, no third-party tracking, etc.)
- Scalable (handle large number of users, messages, etc.)
- Low latency (real-time messaging, notifications, etc.)
- Easy to use (intuitive UI, simple onboarding, etc.)
- Reliable (message delivery, read receipts, etc.)
- Fast (quick load times, smooth animations, etc.)
Cryptography
Standalone cryptography module
UI
Building secure peer-to-peer messaging apps is tough, and it's even tougher to get people to switch from what they already use. I've noticed that a great user interface and an intuitive design often matter more to people than terms like cryptography or end-to-end encryption.
That's why I've started building a UI library to tackle this head-on! It's a work in progress, but the goal is to create a more welcoming and seamless experience for new users.
Standalone UI module
WebRTC
Standalone P2P module
Storage
A linked-list is a good way to order block of sequential data that can be validated by others. Countless real-world examples show that it scales pretty well.
In our apps, We are testing the use of a blockchain-like structure for storing "application data" local-only. The app is a work-in-progress proof-of-concept and experimental. It is an investigation into creating a distributed and decentralized app. This could be considered and over-engineered solution to CRDT.
the sole purpose of this approach is to keep messages between peers in sync via a CRDT solution. The implementation is far from finished. The CRDT is entirely in javascript running in a browser.
Tables needed:
- device
- profile
- preferences
- contacts
- blockchain
device object:
id
: unique identifier for the devicename
: name of the device
profile object:
id
: unique identifier for the profilename
: name of the profileavatar
: URL to the profile avatar imagedevices
: array of device IDs associated with the profilepublicKey
: public key for encryptionprivateKey
: private key for encryption (stored securely)symmetricKey
: symmetric key for encryption (stored securely)
preferences object:
enable notifications
: boolean to enable/disable notificationstheme
: string to store the selected theme (e.g., "light", "dark")language
: string to store the selected languageprivacy settings
: object to store privacy-related settings (e.g., "show online status", "read receipts")
contacts object:
id
: unique identifier for the contactname
: name of the contactavatar
: URL to the contact's avatar imagedevices
: array of device IDs associated with the contactid
: ID of the device associated with the contactpublicKey
: public key for encryptionprivateKey
: private key for encryption (stored securely)symmetricKey
: symmetric key for encryption (stored securely)
blockchain object:
id
: unique identifier for the blockchain entryname
: name of the blockchainchain
: array to store the blocks in the blockchainstorage
: object to store the blockchain data (e.g., messages, transactions)
CRDT
Standalone CRDT module
Architecture
Decentralized Architecture: Link to blog post
While my approach here could be considered overly complicated (because, well, it is), I'm trying something new, and it's entirely possible this strategy won't be viable long-term. My philosophy is "there's only one way to find out." I'm not necessarily recommending this approach, just sharing my journey and what I'm doing.
Statics as Chat App Infrastructure: Link to blog post
While I often see module federation and microfrontends discouraged in online discussions, I believe they're a good fit for my specific approach. I'm optimistic about the benefits and wanted to share the details.
When serving the federated modules, I can also host the Storybook statics. I think this could be an excellent way to document the modules in isolation.
Modules and Applications
This setup allows me to create microfrontends that consume these modules, enabling me to share functionality between different applications. The following applications, which have distinct codebases (and a distinction between open and closed source), would be able to leverage this:
Sharing these dependencies should make it easier to roll out updates to core mechanics across these diverse applications.
Furthermore, this functionality also works when I create an Android build with Tauri. This could streamline the process of creating new applications that utilize these established modules.
Considerations and Future
I'm sure there will be some distinct testing and maintenance overhead with this architecture. However, depending on how it's implemented, I believe it could work and make it easier to improve upon the current functionality.
It's important to note that everything about this project is far from finished. Some might view this as an overly complicated way to achieve what npm already does. However, I think this approach offers greater flexibility by allowing for the separation of open and closed-source code for the web. Of course, being JavaScript, the "source code" will always be accessible, especially in the age of AI where reverse-engineering is more possible than ever before.