v1.7.0 · open source · MIT-friendly

Chat on WhatsApp
without leaving your shell.

A fast, keyboard-driven TUI for WhatsApp Web. Live next to vim and tmux — not in another Electron window eating your RAM.

$npm i -g @gtchakama/wa-tui
~ wa-tui
Chats
Mom2
Dev team5
Alex
Book club
Lunch crew
Mom
Momare you eating properly?
Momsend a picture of dinner 🍲
yes mom, promise 🥦
Momgood. love you ❤️

Everything you need. Nothing you don't.

Every feature earns its keybinding.

Keyboard-first by design

j/k to move, to open, Ctrl+K to search. Your hands never leave home row.

Lightweight & native

Pure Node + neo-blessed. Boots in under a second. No Electron, no fan noise.

🔎

Fuzzy finder everywhere

One modal. Search across all chats or scope to the current thread's history. Incremental, case-insensitive.

📎

Media, saved to $PWD

Images, voice notes, documents — downloaded straight into your working directory. Ready for scp or mv.

🎨

Themeable palettes

Press F2 to preview live. Settings persist under ~/.wa-tui/. Matches your dotfiles, not the other way round.

📱

QR pairing, inline

The QR renders in the terminal itself — ASCII or kitty graphics if your emulator supports it. Zero browser tabs.

From zero to chatting in under a minute

Needs Node 18+ and Chrome (or Chromium) on PATH.

1

Install it

One global install via npm. Homebrew tap also available.

$ npm i -g @gtchakama/wa-tui
2

Launch it

Run from the directory where you want session files stored.

$ wa-tui
3

Pair & chat

Phone → Linked devices → scan. Persists across reboots.

↑↓ browse  ⏎ open  Ctrl+K find

Where it shines

Honest about what it's for. (And what it isn't.)

flow

Stay in flow while coding

A ping lands, you glance a pane over, reply, and you're back in vim. No Alt-Tab into a 500MB chat app, no phone pickup that turns into 20 min of scrolling.

ssh

Remote boxes & SSH sessions

Runs happily on a dev server or VPS. Read WhatsApp wherever you have a shell — handy when your phone is across the room or locked in a drawer.

low-spec

Old laptops & Pis

No Electron, no persistent browser window. Boots in under a second and idles cheap on hardware that Slack would melt.

$PWD

Media straight to your project

Downloads land in the current working directory. cd into a repo, grab the asset a client sent, and it's already next to your code. No Downloads graveyard.

focus

Distraction-minimized chat

No stories, no status, no ads, no nudges. Just text and a keyboard. The UI has nothing to sell you, so it doesn't try.

j/k/⏎

For keyboard purists

If you already think in j/k/⏎/Ctrl+K, this is the fastest WhatsApp client you'll ever use. Fuzzy-find across all chats + current thread beats scrolling, every time.

⚠️
Not the right fit for: video calls, sticker bombing, status browsing. Use your phone for those — wa-tui is for people whose WhatsApp is mostly text with a handful of people, and who want that to stop interrupting their terminal.

Readable code. Honest abstractions.

Plain Node. No build step. Every file does one thing and does it clearly.

# Clone, install, run — that's the whole dev loop
git clone https://github.com/gtchakama/wa-tui.git
cd wa-tui
pnpm install          # or: npm install
pnpm start            # scans QR, drops you into the TUI

# Run the test suite
node --test
// src/whatsapp/service.js — every phase is an event you can hook
this.client.on('qr', (qr) => {
  this.emit('lifecycle', { phase: 'qr' });
  this.emit('qr', qr);
});

this.client.on('loading_screen', (percent, message) => {
  this.emit('lifecycle', { phase: 'syncing', percent, message });
});

this.client.on('ready', () => {
  this.emit('lifecycle', { phase: 'ready' });
});

this.client.on('auth_failure', (msg) => {
  this.emit('lifecycle', { phase: 'auth_failure', message: msg });
});
// First-run Chrome install with live progress — no silent hangs
async function installBrowser(onProgress) {
  cleanStaleChromeCache();
  const { install, detectBrowserPlatform, Browser } = require('@puppeteer/browsers');
  const { PUPPETEER_REVISIONS } = require('puppeteer-core/lib/cjs/puppeteer/revisions.js');

  await install({
    browser: Browser.CHROME,
    buildId: PUPPETEER_REVISIONS.chrome,
    platform: detectBrowserPlatform(),
    cacheDir: path.join(os.homedir(), '.cache', 'puppeteer'),
    downloadProgressCallback: (downloaded, total) => {
      if (total > 0) onProgress(Math.round((downloaded / total) * 100));
    },
  });
}
// Vim-flavored keybindings everywhere. Want your own? PRs welcome.
screen.key(['j', 'down'],  () => chatList.down(1));
screen.key(['k', 'up'],    () => chatList.up(1));
screen.key(['enter'],      () => openChat(chatList.selected));
screen.key(['C-k', '/'],   () => openFuzzyFinder());
screen.key(['1', '2', '3'], (ch) => filter(ch));  // all / DMs / groups
screen.key(['F2'],         () => openPaletteSettings());
screen.key(['q', 'C-c'],   () => process.exit(0));

Actual code from main. No transpilation, no pseudocode.

Your weekend project, basically

A few thousand lines of JavaScript. No TypeScript build. No webpack. No drama.

Small repo, big impact

The surface area is tiny — a feature PR lands in days, not months. Great first open source contribution if you've been looking for one.

  • Add a new theme to the palette picker
  • Extend the fuzzy finder with date or sender filters
  • Swap in a different desktop-notification backend
  • Improve inline media rendering (kitty graphics already wired)
  • Write a test — the suite runs on plain node --test
# fork → branch → ship
gh repo fork gtchakama/wa-tui --clone
cd wa-tui
git checkout -b feat/my-idea

pnpm install
pnpm start         # try it live
node --test        # keep the suite green

gh pr create --fill
Star it to help others find it 🐛 File issues — bugs, ideas, either works 🔀 Send PRs — reviewed within days

Built by humans

Two contributors, many late nights, equal commits.

George T Chakama avatar
George T Chakama
@gtchakama · creator
Ngonidzashe Mangudya avatar
Ngonidzashe Mangudya
@iamngoni · maintainer

Want your avatar on this page? Send a PR — first-time contributors especially welcome.

Made in the terminal, for the terminal.

Open source under ISC. If it saves you from one Electron app, consider starring it.

Star on GitHub