Decentralized messaging is the future of censorship-resistant, privacy-first communication.
Whisper Board is a lightweight, anonymous chat app powered by Waku protocol, designed to showcase how easy it is to integrate Waku into a modern web stack.
Why Decentralized Messaging?
Most recently, we've seen how fragile centralized systems can be. A single AWS outage in the US-East region, knocked out major apps, even Signal, a privacy-first messenger, across Central and Eastern Europe. Billions of messages delayed, communities cut off, and trust shaken.
Here is a full report on what happened.
When all communication routes depend on a few corporate data centers, resilience becomes an illusion.
Decentralized messaging changes that: it doesn’t rely on one server, company, or geography. Messages flow peer-to-peer, so even if one node fails, the network stays alive. It’s more than just privacy, it’s about robustness, autonomy, and continuity.
In this article, you'll learn:
- The architecture behind a simple Whisper Board built with waku
- How to connect to and use Waku in your own app
- How messages flow through the network
- How to onboard and contribute as a new developer
- Visual diagrams to aid understanding
Architecture Overview
Diagram: System Components
File structure :
src
├── components
│ ├── MessageCard.tsx
│ └── MessageForm.tsx
├── hooks
├── lib
├── pages
│ ├── Index.tsx
│ └── NotFound.tsx
├── services
│ ├── MessageService.ts
│ └── WakuService.ts
├── types
├── App.css
├── App.tsx
├── index.css
├── main.tsx
├── vite-env.d.ts
.gitignore
bun.lockb
components.json
eslint.config.js
index.html
package-lock.json
package.json
postcss.config.js
README.md
tailwind.config.ts
tsconfig.app.json
tsconfig.json
tsconfig.node.json
vite.config.ts
</pre>
- Frontend: Built in React, styled with Tailwind and shadcn-ui.
-
Hooks:
useWakuhandles node connection,useMessagesmanages sending/receiving. -
Services:
WakuServicemanages the Waku node,MessageServicehandles message flow. - Waku Node: Lightweight node connects to the decentralized network.
Technologies Used
- Vite
- TypeScript
- React
- shadcn-ui
- Tailwind CSS
- Waku JS SDK
How the App Works
Connecting to Waku
The custom hook useWaku.ts initializes and manages the Waku node:
const { isConnecting, isConnected, error } = useWaku();
- On mount, calls
wakuService.initialize()to connect to Waku peers. - Cleans up on unmount via
wakuService.stop().
Code Reference
//src/hooks/useWaku.ts
/* https://github.com/Oladotunlaniyan/whisper-waku-chat/blob/main/src/hooks/useWaku.ts*/
import { useState, useEffect } from "react";
import { wakuService } from "../services/WakuService";
export const useWaku = () => {
const [isConnecting, setIsConnecting] = useState(false);
const [isConnected, setIsConnected] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const initWaku = async () => {
if (wakuService.isReady()) {
setIsConnected(true);
return;
}
setIsConnecting(true);
setError(null);
try {
await wakuService.initialize();
setIsConnected(true);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to connect to Waku");
} finally {
setIsConnecting(false);
}
};
initWaku();
return () => {
wakuService.stop();
};
}, []);
return { isConnecting, isConnected, error };
};
Messaging Flow
Sequence Diagram: Sending and Receiving a Message
Core Flow
- User submits a message via the UI (
MessageForm). - Hook
useMessagescallsmessageService.publishMessage. -
MessageServiceencodes and pushes the message to the Waku network. - Node listens for incoming messages and updates UI in real time.
Key Code References
//name=src/services/MessageService.ts
export class MessageService {
private getEncoder() {
const node = wakuService.getNode();
return node.createEncoder({ contentTopic: CONTENT_TOPIC });
}
async publishMessage(content: string): Promise<void> {
const node = wakuService.getNode();
const encoder = this.getEncoder();
const message = { content, timestamp: Date.now() };
const payload = this.encodeMessage(message);
await node.lightPush.send(encoder, { payload });
}
async subscribeToMessages(onMessage: (message: WhisperMessage) => void): Promise<() => void> {
const node = wakuService.getNode();
const decoder = this.getDecoder();
await node.filter.subscribe([decoder], (wakuMessage) => {
if (!wakuMessage.payload) return;
const decoded = this.decodeMessage(wakuMessage.payload);
onMessage({ id: `${decoded.timestamp}-${Math.random()}`, content: decoded.content, timestamp: decoded.timestamp });
});
return () => { /* unsubscribe logic */ };
}
}
Onboarding: Steps for Beginner Contributors
Getting Started
- Clone the Repository
git clone https://github.com/Oladotunlaniyan/whisper-waku-chat.git
cd whisper-waku-chat
- Install Dependencies
npm install
- Run the App
npm run dev
- Open http://localhost:8080 in your browser.
-
Edit Code Locally
- Most logic lives in
src/ - Message logic:
src/services/MessageService.ts - Waku node logic:
src/services/WakuService.ts - UI:
src/components/,src/pages/
- Most logic lives in
Contribution Guide
- Follow the onboarding steps above for local development.
- Make sure you have Node.js and npm installed (guide).
- Follow the onboarding steps above for local development.
- Submit issues or pull requests for improvements, bug fixes, or new features.
- For UI tweaks, edit files in
src/components/. - For protocol logic, edit
src/services/WakuService.tsandsrc/services/MessageService.ts.
First-Time Contributor Tips
- Start by reading the README.
- Use the hooks and services as your entry points for understanding message flow.
- To add a feature, create a new component in
src/components/and integrate with hooks/services. - For debugging, use console logs in services and hooks.
- Ask for help or suggestions via GitHub Issues.
Visuals
- System Architecture Diagram (see above)
- Sequence Diagram for Messaging (see above)
- UI Screenshot: (Add your own screenshot or generate one from running the app.)
Conclusion
Whisper Waku Chat is a simple but powerful demo of decentralized, anonymous messaging using Waku.
With a modern React frontend and the Waku JS SDK, it’s easy for new developers to get started and contribute.
Next Steps:
- Fork the repo, run locally, and start hacking!
- Check out the Waku docs for protocol details.
- Join the Waku dev community for support and collaboration.
Further Resources
This is a very simple implementation of the Waku protocol, in subsequent articles I will be increasing functionality and complexity of the whisper board. This includes using new methods, explaining more core concepts etc.


Top comments (0)