wacli: A Scriptable WhatsApp Client That Pairs Like a Linked Device
WhatsApp CLI: sync, search, send. Build from source wacli requires Go 1.26.5 or newer and uses go-sqlite3, so cgo + a C compiler are required.
At a glance
- What is it?
- wacli brings WhatsApp into the terminal as a linked device, mirrors messages into SQLite, and exposes search, send, and sync commands. It is a practical tool for engineers who want to automate WhatsApp without touching a phone, but it demands Go 1.27, cgo, and a C compiler to build from source.
- Who is it for?
- Adopt wacli if you are a developer or ops engineer who needs to read, search, or send WhatsApp messages from scripts and want a local, queryable archive. Do not use it if you cannot meet the build requirements (Go 1.27, cgo, C compiler) or if you expect full message history guarantees, since WhatsApp Web provides history on a best-effort basis.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Problem wacli Solves and Who It Is For
wacli targets people and tools that work from the command line and need to interact with WhatsApp without a phone or a GUI. It pairs as a linked device, mirrors messages into a local SQLite store, and provides search, sending, and chat management. The intended audience is engineers who want to automate WhatsApp workflows, such as sending notifications, searching past conversations, or exporting message history. It is also useful for analysts who need a local, queryable archive of WhatsApp data. The README explicitly positions it as a scriptable client, not a full replacement for the mobile app. If you spend your day in a terminal and want WhatsApp to behave like a Unix tool, this project is aimed at you.
How It Works: WhatsApp Web Protocol and SQLite Storage
wacli uses the WhatsApp Web protocol through the whatsmeow library, which is the same approach as many unofficial clients. It pairs with your phone like a linked device, so you do not need to provide credentials or a phone number directly. After pairing, the auth command performs the first sync, pulling message history from WhatsApp's servers. The client keeps two separate SQLite databases: one for the WhatsApp session and one for the searchable message index. Search reads the local index, so it works even when you are offline. This separation is a sensible design: the session database holds connection state, while the message index is optimized for querying. The README notes that WhatsApp Web provides history on a best-effort basis, so the local store may not contain every message ever sent. You can use the history coverage command to inspect what is available locally before requesting older messages from your phone.
Getting Started: Installation and First Commands
The quickest way to install wacli is via Homebrew on macOS or Linux: brew install openclaw/tap/wacli. Prebuilt archives exist for macOS, Linux, and Windows from GitHub Releases. To build from source, you need Go 1.27.0 or newer, a C compiler, and cgo enabled. The exact command is: CGO_ENABLED=1 CGO_CFLAGS="-Wno-error=missing-braces" go install -tags sqlite_fts5 github.com/openclaw/wacli/cmd/wacli@latest. The sqlite_fts5 tag enables full-text search, which is likely important for the messages search command. After installation, you pair by running wacli auth, which shows a QR code to scan from WhatsApp's Linked devices screen. Then you can search with wacli messages search "meeting" and send a message with wacli send text --to +15551234567 --message "hello". The README shows these as the core quick-start commands. Note that sending requires a recipient you are allowed to contact, and recipients can be phone numbers, JIDs, or names from synced contacts, groups, or chats.
Configuration and Storage: Stores, Accounts, and Read-Only Mode
The default store location is ~/.local/state/wacli on Linux and ~/.wacli elsewhere. You can override it with --store DIR or the WACLI_STORE_DIR environment variable. For multiple WhatsApp identities, you can create named accounts with wacli accounts add work, then run wacli --account work sync --follow to give each account its own session, database, and lock. This is useful for separating personal and work chats. A notable feature is the read-only mode: wacli --read-only or WACLI_READONLY=1 ensures that an integration cannot change WhatsApp or the local store. This is a safety net for scripts that should only read. The README also mentions that write commands take a per-store lock, and when sync --follow is running, send commands are delegated to that process. This avoids concurrent write conflicts. For integrations, you can use --json for one-shot commands and --events for NDJSON lifecycle events from long-running commands.
Search and Sync: What Works and What Does Not
Search is a core feature. The messages search command reads from the local SQLite index, so it works without a live connection. You can filter by media, as in wacli messages search "invoice" --has-media, and you can output JSON with wacli --json messages list --limit 20. The sync command with --follow keeps the store current by continuously mirroring new events. However, the documentation is clear that WhatsApp Web provides history on a best-effort basis. This means you cannot rely on wacli to have complete archives of old messages. The history coverage command exists to inspect what is actually available locally. This is a limitation you should plan for: if you need guaranteed full history, wacli is not the right tool. The README also mentions storage limits and media downloads in the sync documentation, but the provided text does not detail those limits, so you will need to check docs/sync.md for specifics.
Scripting and Integration: JSON, Events, and Companion Tools
wacli is designed for scripting. The default output is human-readable tables, but you can switch to JSON for one-shot commands. For long-running commands like sync --follow, you can use --events to get NDJSON lifecycle events. This makes it easy to consume wacli output from other programs. Progress and errors go to stderr, which is a good practice for separating data from diagnostics. The README mentions companion integrations for webhooks and safe read-only SQLite access, but the details are in docs/integrations.md, which is not included in the provided material. The read-only mode is particularly useful for integrations that must not modify state. You can set WACLI_READONLY=1 globally or use --read-only per command. This is a thoughtful feature that reduces the risk of accidental writes from scripts.
Build Requirements and Maintenance Costs
Building wacli from source is not trivial. It requires Go 1.27.0 or newer, cgo, and a C compiler. The go-sqlite3 dependency means you cannot avoid cgo, which complicates cross-compilation and static builds. The README provides a specific CGO_CFLAGS flag to suppress a warning about missing braces, which suggests that build issues may arise on certain compilers. For development, you also need Node.js 24 or newer and pnpm, because the project uses a frontend build system (likely for the web-based UI or build tooling). The maintenance cost is moderate: you need to keep Go, C compiler, and Node toolchains updated. The project is MIT-licensed, which allows commercial use and modification with attribution. The repository is actively maintained, with a recent release v0.17.1 on 2026-08-14. However, the README does not mention a migration path for the SQLite schema between versions, so upgrading may require care. You should check the release notes for any breaking changes before updating.
Alternatives and Trade-offs
The README credits whatsapp-cli by Vicente Reig as a heavy inspiration. That project likely uses a similar approach but may not have the same level of SQLite-backed search or the same command structure. Another alternative is to use the WhatsApp Business API, which is the official route for sending messages programmatically. The official API requires a business account, a phone number, and approval, but it offers guaranteed delivery and no risk of being banned for using an unofficial client. wacli, by contrast, uses the WhatsApp Web protocol, which is not officially supported by Meta. This means wacli could break if WhatsApp changes the protocol, and it may violate WhatsApp's terms of service. The trade-off is clear: wacli gives you a free, scriptable client with local storage, but you accept the risk of account bans or service interruptions. The official API is more reliable but costly and complex to set up. For personal automation, wacli is a good fit; for business-critical messaging, the official API is safer.
Editorial conclusion
Adopt wacli if you are a developer or ops engineer who needs to read, search, or send WhatsApp messages from scripts and want a local, queryable archive. Do not use it if you cannot meet the build requirements (Go 1.27, cgo, C compiler) or if you expect full message history guarantees, since WhatsApp Web provides history on a best-effort basis. Before relying on it, verify that your Go toolchain and C compiler work with the documented CGO_CFLAGS, and test the --read-only mode with your integration to confirm it never writes unexpectedly. The project is MIT-licensed and actively maintained, but you should confirm the latest release notes for any breaking changes before upgrading.
Community notes