@waku/run

Spin up a local Waku network for development without relying on external infrastructure

Perfect for hackathons, offline development, or when you need a controlled testing environment for your js-waku application.

What's Included

  • 2 nwaku nodes connected to each other with all protocols enabled:
    • Relay (gossipsub)
    • Filter (light client subscriptions)
    • LightPush (light client publishing)
    • Store (message history)
    • Peer Exchange (peer discovery)
  • PostgreSQL database for message persistence
  • Isolated network - nodes only connect to each other

Requirements

  • Docker Desktop or Docker Engine with Compose plugin
  • Node.js 18+ (only for npx/npm usage)

Installation

Option 1: Use npx (no installation required)

npx waku-run start

Option 2: Install globally

npm install -g @waku/run
waku-run start

Option 3: Clone and run locally

git clone https://github.com/waku-org/js-waku.git
cd js-waku/packages/run
npm install
npm run start

Quick Start

1. Start the Network

Option A: Using npx (recommended for quick setup)

npx waku-run start

Option B: Local development

cd packages/run
npm run start

This will:

  • Start 2 nwaku nodes and a PostgreSQL database
  • Run in the background (detached mode)
  • Display connection information you need for your app

Example output:

{
  "bootstrapPeers": [
    "/ip4/127.0.0.1/tcp/60000/ws/p2p/16Uiu2HAm...",
    "/ip4/127.0.0.1/tcp/60001/ws/p2p/16Uiu2HAm..."
  ],
  "networkConfig": {
    "clusterId": 1,
    "numShardsInCluster": 8
  }
}

2. Connect Your js-waku App

Copy the output from above and use it in your application:

import { createLightNode } from "@waku/sdk";

const waku = await createLightNode({
  defaultBootstrap: false,
  bootstrapPeers: [
    "/ip4/127.0.0.1/tcp/60000/ws/p2p/16Uiu2HAm...",
    "/ip4/127.0.0.1/tcp/60001/ws/p2p/16Uiu2HAm..."
  ],
  networkConfig: {
    clusterId: 1,
    numShardsInCluster: 8
  }
});

await waku.start();

// Your app is now connected to your local Waku network!

3. Stop When Done

npm run stop

Available Commands

Using npx (published package)

Command Description
npx waku-run start Start the network (detached) and show connection info
npx waku-run info Show connection info for running network
docker compose down Stop the network and clean up

Local development

Command Description
npm run start Start the network (detached) and show connection info
npm run stop Stop the network and clean up
npm run restart Restart the network
npm run logs View and follow logs from all nodes
npm run info Show connection info for running network
npm test Run integration tests
npm run build Build TypeScript to JavaScript

Direct Docker Compose Commands

You can also use standard Docker Compose commands:

# Start and see all logs
docker compose up

# Start in background
docker compose up -d

# View logs
docker compose logs -f

# Check status
docker compose ps

# Stop and clean up
docker compose down

# Stop and remove volumes (fresh start)
docker compose down -v

Configuration

Port Configuration

If the default ports are in use, create a .env file:

cp .env.example .env

Edit .env to change ports:

NODE1_WS_PORT=60000
NODE1_REST_PORT=8646
NODE2_WS_PORT=60001
NODE2_REST_PORT=8647

Cluster Configuration

The default configuration uses:

  • Cluster ID: 1
  • Number of shards: 8

To test with different network configurations, create a .env file:

# .env file
CLUSTER_ID=16  # Change to a different cluster

Your js-waku app will automatically use the correct configuration from npm run info:

const waku = await createLightNode({
  defaultBootstrap: false,
  bootstrapPeers: [...],
  networkConfig: {
    clusterId: 1,  // Match your CLUSTER_ID
    numShardsInCluster: 8
  }
});

Changing nwaku Version

# .env file
NWAKU_IMAGE=wakuorg/nwaku:v0.35.0

Debugging

View Node Logs

npm run logs

# Or for a specific node
docker compose logs -f nwaku-1
docker compose logs -f nwaku-2

Check Node Health

# Node 1
curl http://127.0.0.1:8646/health

# Node 2
curl http://127.0.0.1:8647/health

Check Peer Connections

# Node 1 debug info
curl http://127.0.0.1:8646/debug/v1/info

# Node 2 debug info
curl http://127.0.0.1:8647/debug/v1/info

View Database

Connect to PostgreSQL to inspect stored messages:

docker compose exec postgres psql -U postgres

# In psql:
\dt  # List tables
SELECT * FROM messages LIMIT 10;

Troubleshooting

Nodes won't start

Check if Docker is running:

docker ps

Check logs for errors:

docker compose logs

Try a fresh start:

docker compose down -v
npm run start

Port conflicts

If you see "port already in use":

  1. Change ports in .env:
NODE1_WS_PORT=50000
NODE2_WS_PORT=50001
  1. Or find and stop conflicting processes:
# macOS/Linux
lsof -i :60000
kill <PID>

# Or use different ports

Nodes won't discover each other

This is expected on first start. The nodes use peer exchange and discovery protocols to find each other, which can take 10-30 seconds.

Check connection status:

# Wait a moment after starting
sleep 15
npm run info

Can't connect from js-waku

Verify nodes are running:

docker compose ps

Check your firewall - ensure localhost connections are allowed

Verify ports match - the ports in your js-waku config must match the .env configuration

Advanced Usage

Customize Docker Compose

Need more nodes, different configurations, or additional services?

# Copy and customize
cp docker-compose.yml my-custom-compose.yml

# Edit my-custom-compose.yml to add:
# - More nwaku nodes
# - Custom protocol configurations
# - Additional services (monitoring, etc.)

# Run with your custom config
docker compose -f my-custom-compose.yml up

Add More Nodes

Add to docker-compose.yml:

nwaku-3:
  <<: *nwaku-base
  container_name: waku-local-node-3
  ports:
    - "60002:60002/tcp"
    - "8648:8648/tcp"
  depends_on:
    - postgres
    - nwaku-1
  command:
    - --relay=true
    - --filter=true
    # ... same config as other nodes
    - --websocket-port=60002
    - --rest-port=8648

Enable Debug Logging

# .env file
LOG_LEVEL=DEBUG

Or directly in docker-compose:

- --log-level=DEBUG
- --log-format=json  # Structured logs

Use Cases

  • Hackathon development - Work without internet or unreliable connections
  • Local testing - Test your app against real nwaku nodes
  • CI/CD integration tests - Automated testing in isolated environments
  • Protocol experimentation - Try different configurations safely
  • Offline demos - Show your app working without external dependencies

Architecture

┌─────────────────────────────────────────────┐
│           Your js-waku Application          │
│                                             │
│  createLightNode({                          │
│    bootstrapPeers: [node1, node2]           │
│  })                                         │
└──────────────┬──────────────────────────────┘
               │ WebSocket connections
               │ (127.0.0.1:60000, 60001)
               │
    ┌──────────┴──────────┐
    │                     │
┌───▼────┐           ┌────▼───┐
│ nwaku-1│◄─────────►│nwaku-2 │
│        │  relay    │        │
│ :60000 │  gossip   │ :60001 │
└───┬────┘           └────┬───┘
    │                     │
    └──────────┬──────────┘
               │
         ┌─────▼─────┐
         │ PostgreSQL│
         │  :5432    │
         └───────────┘

Both nodes:

  • Run all Waku protocols (relay, filter, lightpush, store)
  • Share a PostgreSQL database for message persistence
  • Connected to each other via relay protocol
  • Discover each other via peer exchange
  • Expose WebSocket for js-waku connections
  • Expose REST API for debugging

FAQ

Q: Do I need to wait for nodes to connect before starting my app? A: No, you can start your app immediately. js-waku will wait for peers to be available.

Q: Can I use this for production? A: No, this is for development only. For production, use The Waku Network or run your own fleet.

Q: Why PostgreSQL? A: The nwaku store protocol requires a database to persist messages. This allows your app to query message history.

Q: Can I connect from a different machine? A: Yes, but you'll need to change 127.0.0.1 to your machine's IP address in the multiaddrs and ensure your firewall allows the connections.

Q: How much disk space does this use? A: Minimal - the PostgreSQL database only stores messages from your local testing. Use docker compose down -v to remove all data.

Resources

License

MIT OR Apache-2.0