DEV Community

abidibo
abidibo

Posted on

WebSocket Mock Server with a Beautiful Terminal UI

The problem: WebSockets are cool, but testing them sucks

Let's be honest. We all love json-server for quickly mocking REST APIs during development. You create a db.json file, run one command, and boom - you have a fake API. Beautiful. Simple. Fast.

But what about WebSockets?

If you're building real-time features (chat apps, live notifications, collaborative editors, stock tickers...), you know the pain:

  • Your backend team is still working on the WebSocket endpoints
  • You need to test different data scenarios but restarting the backend is slow
  • You want to see what's happening with connections and messages in real-time
  • Setting up a proper WebSocket mock server is... annoying

Many years ago, I wrote ws-server-ftw. Now archived, it’s been reborn with a new face and a new package name: @abidibo/ws-server-ftw — basically json-server’s cool, simpler cousin that speaks WebSocket and comes with a gorgeous Terminal UI.

WS Server Screenshot

Why Should You Care?

Here's what you get:

Works like json-server: Point it to a JSON file (or a js file which exports an object), and it serves data via WebSocket
🎨 Beautiful TUI: See connections, messages, and your database in real-time with syntax highlighting
🔄 Live updates: Send data to connected clients with merge, deep-merge, or append operations
📍 Path-based routing: Different WebSocket paths serve different parts of your database
Fast development: No backend needed, change data on the fly

Installation

npm install @abidibo/ws-server-ftw --save-dev
Enter fullscreen mode Exit fullscreen mode

Quick Start (It's Really Simple)

1. Create a database file (db.json):

{
  "api": {
    "v1": {
      "chat": {
        "messages": [
          {
            "id": 1,
            "user": "Alice",
            "text": "Hey there!",
            "timestamp": "2025-01-08T10:00:00Z"
          }
        ]
      },
      "notifications": {
        "unread": 5,
        "items": []
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Start the server:

npx ws-server -i db.json
Enter fullscreen mode Exit fullscreen mode

3. Connect from your app:

const ws = new WebSocket('ws://localhost:9704/api/v1/chat');

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
  // You get: { messages: [...] }
};
Enter fullscreen mode Exit fullscreen mode

That's it. Your WebSocket client automatically receives the data from db.api.v1.chat.

The TUI is Where Magic Happens

When you run ws-server, you get this beautiful terminal interface with four panels and an informative header:

1. Connections Panel (Top Left)

See all connected clients in real-time. Each connection shows:

  • Connection ID
  • WebSocket path
  • Sent/Received messages

Use arrow keys to select a connection, press x to kill it (perfect for testing reconnection logic).

2. Command Input Panel (Bottom Left)

Send data to the selected connection with powerful commands:

Resend original data (press Enter with empty input):

[Enter]
Enter fullscreen mode Exit fullscreen mode

Merge data (shallow - replaces top-level keys):

merge {"unread": 10}
Enter fullscreen mode Exit fullscreen mode

Deep merge (recursive - keeps nested properties):

deepmerge {"messages": [{"id": 2, "user": "Bob", "text": "Hello!"}]}
Enter fullscreen mode Exit fullscreen mode

Append to arrays:

append [{"id": 3, "user": "Charlie", "text": "Hi everyone"}]
Enter fullscreen mode Exit fullscreen mode

Send raw JSON:

{"status": "updated", "timestamp": 1234567890}
Enter fullscreen mode Exit fullscreen mode

Update the database permanently:

db set api.v1.chat.unread 0
Enter fullscreen mode Exit fullscreen mode

3. Database Viewer (Middle Panel)

Your entire database with beautiful syntax highlighting:

  • Keys in cyan
  • Strings in green
  • Numbers in yellow
  • Booleans in magenta

Press r to refresh from file if you edit it manually.

4. Message Log (Right Panel)

Every connection/disconnection event and every WebSocket message, sent and received.

Real-World Example: Building a Chat App

Let's say you're building a chat application. Here's your workflow:

1. Set up your mock data:

{
  "chat": {
    "rooms": {
      "general": {
        "messages": [
          {"id": 1, "user": "Alice", "text": "Hello world"}
        ],
        "users": ["Alice", "Bob"]
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Start the server:

ws-server -i chat-db.json -p 8080
Enter fullscreen mode Exit fullscreen mode

3. Connect your frontend to ws://localhost:8080/chat/rooms/general

4. Test different scenarios from the TUI:

Want to simulate a new message?

deepmerge {"messages": [{"id": 2, "user": "Bob", "text": "Hi Alice!"}]}
Enter fullscreen mode Exit fullscreen mode

Want to test a user leaving?

db set chat.rooms.general.users ["Alice"]
Enter fullscreen mode Exit fullscreen mode

Then press Enter to resend.

Want to see how your UI handles connection drops? Select the connection and press x.

All without touching your backend code.

Path-Based Routing

The server uses paths to serve different data:

// Connect to ws://localhost:9704/api/v1/chat
// Receives: db['api']['v1']['chat']

// Connect to ws://localhost:9704/notifications
// Receives: db['notifications']
Enter fullscreen mode Exit fullscreen mode

This means one database file can serve multiple WebSocket endpoints. Just like real-world APIs.

Use Cases (When This Tool Shines)

🎮 Frontend development: Build your real-time UI without waiting for backend
🧪 Testing: Create predictable WebSocket responses for integration tests
🎨 Prototyping: Demo WebSocket features to clients/stakeholders quickly
🐛 Debugging: Test edge cases and error scenarios easily
📚 Learning: Experiment with WebSocket APIs without complex setup

Tech Stack (For the Curious)

Built with:

  • TypeScript
  • Ink - React for terminals (yes, the TUI is React components!)
  • ws - the battle-tested WebSocket library
  • Node.js ESM - modern module system

Tips and Tricks

Use JavaScript files instead of JSON if you need dynamic data:

// db.js
export default {
  api: {
    users: Array.from({ length: 100 }, (_, i) => ({
      id: i + 1,
      name: `User ${i + 1}`
    }))
  }
};
Enter fullscreen mode Exit fullscreen mode

Then: ws-server -i db.js

Navigate the TUI like a pro:

  • Tab - Switch between panels
  • Arrow keys - Navigate/scroll in focused panel
  • r - Refresh database (in DB panel)
  • x or c - Close connection (in Connections panel)
  • q or Ctrl+C - Quit

Limitations (Being Honest)

This tool is for development and testing. It's not meant for production. It:

  • Doesn't handle authentication
  • Doesn't scale to thousands of connections
  • Doesn't persist data between restarts (unless you use db set)

But for local development? It's perfect.

Try It Out!

npx @abidibo/ws-server-ftw -i your-db.json
Enter fullscreen mode Exit fullscreen mode

No installation needed with npx. Give it a try on your next WebSocket project.

Star the Repo! ⭐

If this tool saves you time (or if you just think the TUI looks cool), drop a star on GitHub:

👉 github.com/abidibo/ws-server-ftw

Found a bug? Want a feature? Open an issue

Wrapping Up

WebSocket development doesn't have to be painful. With @abidibo/ws-server-ftw, you get:

  • Fast setup (one command)
  • Visual feedback (beautiful TUI)
  • Full control (send any data anytime)
  • Zero backend dependency

It's the json-server experience, but for WebSockets, with a gorgeous terminal UI on top.

Give it a try and let me know what you think!

Happy coding! 🚀


Links:

Top comments (0)