npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wabox

v0.1.11

Published

A bridge between WhatsApp and the filesystem — incoming messages/files land in an inbox folder, an outbox folder is watched and sent back. Built on Baileys.

Readme

wabox

CI npm version License: MIT Node Platforms

A bridge between WhatsApp and your filesystem. It connects to WhatsApp via Baileys, drops every incoming message (text + media) into an inbox/ folder, and watches an outbox/ folder for messages to send back.

The idea: point any process at these two folders. It reads new messages from inbox/, and replies by writing job files to outbox/ — no API to learn, just files.

Install

npm install -g wabox
wabox config

Works on Linux, macOS and Windows. wabox config is an interactive setup that:

  1. asks whether you want the defaults or to customize the folders,
  2. writes config.json and creates the data folders (locations below),
  3. installs a background service for your OS (systemd / launchd / Task Scheduler),
  4. pairs with WhatsApp — scan the QR with WhatsApp → Linked Devices,
  5. offers to enable + start the service.

That's it — it runs in the background and starts on login/boot.

Per-OS locations

Each OS uses its native convention. Setting XDG_CONFIG_HOME / XDG_DATA_HOME overrides them on any platform.

| OS | Config | Data (inbox/outbox/auth) | Service | | ------- | --------------------------------------- | ----------------------------------------- | ------------------------------------------------ | | Linux | ~/.config/wabox/ | ~/.local/share/wabox/ | ~/.config/systemd/user/wabox.service | | macOS | ~/Library/Application Support/wabox/ | (same as config) | ~/Library/LaunchAgents/wabox.plist | | Windows | %APPDATA%\wabox\ | %LOCALAPPDATA%\wabox\ | Task Scheduler task wabox (runs at logon) |

Run wabox status any time to print the resolved paths and service state.

Commands

wabox config       # interactive setup (config + service + pairing)
wabox run          # run the gateway in the foreground (what the service runs)
wabox pair         # (re)pair with WhatsApp via QR
wabox allow        # manage who can reach the inbox (by phone number)
wabox update       # update the npm package + restart the service
wabox status       # show resolved paths + service state
wabox uninstall    # remove the service (--purge: also config + data)

Restricting who can reach the inbox

By default wabox accepts messages from everyone. To limit it to specific people, manage an allow list by phone number (country code + number, no +):

wabox allow add 5511999998888      # accepts "+55 (11) 99999-8888" too
wabox allow add 5511999998888 5511888887777
wabox allow list
wabox allow remove 5511999998888
wabox allow clear                  # back to accepting everyone

Changes are written to config.json and the service is restarted automatically so they take effect. You only need the phone number — not the WhatsApp JID; wabox matches incoming senders by number.

Managing the service directly

# Linux (systemd)
systemctl --user status|restart wabox.service
journalctl --user -u wabox.service -f
# keep running while logged out:
sudo loginctl enable-linger $USER

# macOS (launchd)
launchctl kickstart -k gui/$(id -u)/wabox     # restart
tail -f "~/Library/Application Support/wabox/wabox.log"

# Windows (Task Scheduler)
schtasks /Run /TN wabox                        # start now
type "%LOCALAPPDATA%\wabox\wabox.log"     # logs

No systemd on Linux (e.g. minimal/container distros)? Setup still writes the config and pairs; run the gateway yourself with wabox run (under your own supervisor of choice).

Running from a checkout (no global install)

npm install
npm run config      # same interactive setup
npm start           # = wabox run

Putting the inbox/outbox somewhere else

Edit your config.json (see the table above for its location) and point the folders anywhere:

{
  "inboxDir": "~/whatsapp/inbox",
  "outboxDir": "~/whatsapp/outbox"
}

Relative paths resolve against the data dir; ~ is expanded. Then restart the service (see "Managing the service directly").

How it works

Building the process/agent that consumes the boxes? See INTEGRATION.md for the full contract — message format, how to reply, react, send media, format text, and the read-receipt lifecycle. Or install the skill so your agent already knows it: npx skills add wabox-app/wabox (see skills/wabox).

Inbox (incoming)

Each incoming message produces a JSON file in inbox/, e.g. 20260603-031200_5511999998888_3EB0ABCD.json:

{
  "id": "3EB0ABCD...",
  "from": "[email protected]",
  "pushName": "Alice",
  "fromMe": false,
  "timestamp": "2026-06-03T03:12:00.000Z",
  "text": "check out this photo",
  "media": {
    "type": "image",
    "file": "20260603-031200_5511999998888_3EB0ABCD.jpg",
    "originalName": null,
    "mimetype": "image/jpeg"
  }
}

Media (images, video, audio, documents, stickers) is downloaded next to the JSON, with media.file pointing at it. Text-only messages just have "media": null.

Inbox lifecycle & read receipts

Your consumer owns cleanup. wabox never deletes inbox files — the process that reads them is responsible for removing each .json (and any media) once it has handled the message.

That removal is also the "message read" signal: when a .json leaves the inbox/ folder, wabox sends a native WhatsApp read receipt for that message, so the sender sees the blue checkmarks. The recommended flow is read → remove → respond:

  1. message arrives → <stem>.json (+ media) written to inbox/, delivered to the sender as usual (grey ticks);
  2. your consumer reads the file (and any media) into memory, or moves it to a working folder;
  3. your consumer removes <stem>.json from inbox/ right away → wabox marks it read and the sender sees blue checkmarks;
  4. your consumer processes the message and writes its reply to outbox/.

Removing on pickup (before processing) means the sender is acknowledged immediately, not only once a slow reply is ready. A message stays "unread" until you remove it. Blue ticks only appear if both accounts have read receipts enabled in WhatsApp. See INTEGRATION.md for the full consumer guide.

Outbox (outgoing)

To send a message, write a .json file into outbox/:

{
  "to": "5511999998888",
  "text": "Hello from Claude!",
  "files": ["reply.pdf", "/abs/path/photo.jpg"]
}
  • to — a bare phone number (country code + number, no +) or a full JID ([email protected] for people, [email protected] for groups).
  • text — optional. Sent on its own if there are no files, otherwise used as the caption of the first file.
  • files — optional list. Relative paths resolve against outbox/. File type (image / video / audio / document) is inferred from the extension.
  • replyTo — optional. Quote-reply to an incoming message. Either a bare message id string, or an object { "id", "participant", "text" }. Copy id (and participant for groups) straight from the inbox JSON; text is just the preview shown in the quote bubble.
  • react — optional. Add an emoji reaction to a message: { "emoji": "👍", "messageId": "3EB0...", "participant": null }. An empty emoji removes a previously sent reaction. A reaction can be the whole job or ride along with text/files.

Reply + reaction example:

{
  "to": "5511999998888",
  "text": "claro, segue o arquivo",
  "replyTo": { "id": "3EB0ABCD...", "participant": null },
  "react": { "emoji": "👍", "messageId": "3EB0ABCD..." },
  "files": ["doc.pdf"]
}

Once processed, the job file is moved to outbox/sent/. If it fails, it goes to outbox/failed/ with a .error.txt sidecar explaining why.

Tip: write the file to a temp name first and rename it into outbox/ (atomic), so the watcher never reads a half-written file. The watcher also waits for writes to settle, but rename is safest.

Configuration

Settings come from (highest priority first): environment variable~/.config/wabox/config.jsonbuilt-in default.

| config.json key | Env var | Default | Purpose | | --------------- | ---------------- | --------------------- | ------------------------------------------------- | | inboxDir | INBOX_DIR | <data>/inbox | Where incoming messages/media are written. | | outboxDir | OUTBOX_DIR | <data>/outbox | Watched for outgoing job files. | | authDir | AUTH_DIR | <data>/auth | WhatsApp session storage. | | allowFrom | ALLOW_FROM | [] (all) | Numbers/JIDs to accept (array, or CSV in env). | | ignoreFromMe | IGNORE_FROM_ME | true | Skip messages the bot itself sent. | | logLevel | LOG_LEVEL | info | pino log level for wabox's own logs. | | baileysLogLevel | BAILEYS_LOG_LEVEL | warn | Log level for Baileys' (chatty) internal logs. |

<data> is the per-OS data dir from the locations table above. Relative paths in config.json resolve against <data>; ~ is expanded.

Notes

  • This uses the unofficial WhatsApp Web protocol via Baileys. Use a number you control and don't abuse it.
  • Deleting auth/ forces a fresh QR pairing.

Contributing

Contributions are welcome — see CONTRIBUTING.md for setup, how to verify changes, and the AI-assistance policy. Working with an AI coding agent? Point it at AGENTS.md for the architecture and key invariants.

AI assistance

wabox was built with the help of an AI coding assistant (Anthropic's Claude, via Claude Code). The assistant contributed to code generation, refactoring, and documentation. Every change was reviewed, tested, and is maintained by a human (@rodgco), who remains responsible for the project. AI-assisted commits carry a Co-Authored-By: trailer.

Contributions made with AI tools are welcome — please make sure you understand and test your changes, and mention any significant AI assistance in your pull request.

License

MIT © Rodrigo Couto