Setting Up Tmux For Easy Mobile Coding
Title and description for a blog post
Setting Up Tmux For Easy Mobile Coding
I’ve learned to code on the go, not in a fixed desk setup. The trick isn’t “more gadgets” but a tight, reliable terminal workflow that survives lekky trains, coffee shop Wi‑Fi, and long flights. Tmux has been my honest workhorse for years, and it scales beautifully from a full workstation in a coffee shop to a stripped‑down setup on an iPad. Here’s how I set up tmux for mobile coding, with concrete, battle‑tested lines you can copy‑paste into your own bootstrapped stack.
Why tmux matters for mobile coding
- You often switch contexts: editor, server, logs, mobile emulator, docs. With tmux, you keep all of that in a single SSH or local session, not scattered across windows.
- Screens are precious on mobile devices. A well‑designed pane layout gives you a “3-in-1” view: code editor, terminal, and live output.
- It’s robust to disconnects. If your laptop battery dies or you drop a SSH connection, tmux resurrects your exact layout and running processes.
The core idea: a stable, repeatable layout with reliable commands you can run anywhere. No “rebuild the windowing state by hand” every time.
Prerequisites I actually use
- macOS or Linux laptop; I’m in the San Francisco Bay Area, where I’m often on a train or at a meetup with a tiny desk.
- tmux 3.x (Homebrew on macOS: brew install tmux)
- Neovim or Vim (I code with Neovim; you can swap in your editor of choice)
- tmux plugin manager (TPM) for quick plugin life‑cycle
- Optional: iTerm2 or your terminal of choice with 24‑bit color and good font support
- Optional: tmux‑resurrect and tmux‑continuum for session persistence
If you’re serious about portable setups, invest in good fonts (Nerd Fonts with powerline, or JetBrains Mono) and a terminal that handles true color well.
The minimal toolchain you actually need
- tmux
- A text editor (Neovim is my go‑to)
- A shell with sane defaults (zsh or bash; I’m on zsh with Oh My Zsh)
- Optional tmux plugins:
- tmux-resurrect: save/restore layouts and commands
- tmux-continuum: auto‑save across sessions
- tmux-sensible: sane default bindings
- tmux-yank: copy/paste from system clipboard
Here’s a compact starter setup you can adapt.
# ~/.tmux.conf (minimal, with sensible defaults)
set -g base-index 1
set -g pane-base-index 1
setw -g mode-keys vi
setw -g automatic-rename off
set -g status-interval 2
set -g history-limit 10000
# Plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-yank'
# Optional: battery status on macOS
set -g status-right '#(battery_status 2>/dev/null || echo "bat: N/A") | %Y-%m-%d %H:%M '
# Key bindings (keep them intuitive)
bind-key h select-pane -L
bind-key j select-pane -D
bind-key k select-pane -U
bind-key l select-pane -R
bind-key -r C-h run-shell 'tmux select-pane -L'
bind-key -r C-j run-shell 'tmux select-pane -D'
bind-key -r C-k run-shell 'tmux select-pane -U'
bind-key -r C-l run-shell 'tmux select-pane -R'
# Status bar color (quick touch)
set -g status-bg black
set -g status-fg white
Install TPM and plugins:
# Install TPM (only once)
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# Inside a running tmux session, press prefix + I to install plugins
If you want a more featureful slate, you can add to the plugin list:
- tmux-resurrect
- tmux-continuum
Then enable resurrection in your shell startup if you want to auto‑restore sessions after reboots.
# Enable resurrection in .tmux.conf
set -g @resurrect-strict 1
A practical, mobile-friendly layout
The goal: a setup that works on a laptop with a small screen and also scales to an iPad keyboard or a phone‑size SSH session. I lean toward three main panes per window and a few windows total.
- Window 1: Editor (Neovim) with a split for quick reference or a REPL
- Window 2: Server/Build watcher (node, go, python, etc.)
- Window 3: Logs or tests, plus a tiny “notes” pane for quick ideas
Layout sketch (one session, three windows):
- Window 1: Editor
- Pane 1: Code editor (Neovim)
- Pane 2: Quick REPL or terminal helper
- Window 2: Server
- Pane 1: Dev server (e.g., npm run dev)
- Pane 2: Live reload / watch logs
- Window 3: Logs & notes
- Pane 1: Tail logs
- Pane 2: Shell for ad‑hoc commands
Starting a session with this layout can be automated.
#!/usr/bin/env bash
# start_mobile_tmux.sh
SESSION_NAME="mobile"
# Create a new session with three windows, detached
tmux new-session -s "$SESSION_NAME" -n Editor -d
tmux new-window -t "$SESSION_NAME":2 -n Server -d
tmux new-window -t "$SESSION_NAME":3 -n Logs -d
# In Editor, start Neovim
tmux send-keys -t "$SESSION_NAME":1.1 "nvim" C-m
# In Server window, run the dev server
tmux send-keys -t "$SESSION_NAME":2.1 "npm run dev" C-m
tmux send-keys -t "$SESSION_NAME":2.2 "tail -f logs/server.log" C-m
# In Logs window, tail a log and keep a shell
tmux send-keys -t "$SESSION_NAME":3.1 "tail -f logs/app.log" C-m
tmux send-keys -t "$SESSION_NAME":3.2 "bash" C-m
# Attach to the session
tmux attach -t "$SESSION_NAME"
Make it executable and run when you start coding locally or remotely.
chmod +x start_mobile_tmux.sh ./start_mobile_tmux.sh
Tips:
- You can customize window and pane counts to match your project. If you’re on a tight screen, you might keep just two windows: Editor and Logs, and launch a separate SSH pane on demand.
- Use tmux-resurrect to automatically reopen this layout after each reconnect. A quick workflow is to save at the end of a work session and restore when you reconnect.
Working with mobile devices and emulators in tmux
Mobile coding often means juggling an emulator or a physical device alongside code. Here are pragmatic patterns I use:
- Start the Android emulator from a dedicated pane, not in the editor pane.
- Command: emulator -avd your_avd_name -netdelay none -netspeed full
- If you’re on macOS with an Apple Silicon machine, allocate CPU cores and RAM carefully to avoid throttling your editor.
- Run react-native or Flutter hot reload in a separate pane to keep the UI responsive.
- React Native: npm run ios/android
- Flutter: flutter run
- Monitor device logs in a persistent pane:
- Android: adb logcat | grep -i "your-app"
- iOS: xcrun simctl spawn booted log stream --predicate 'subsystem == "com.your.app"'
The key is to reserve a pane for the emulator or device output and keep your code editing in a separate pane. When you’re on a laptop with a big screen, you can still keep a three‑window mindset, but on a phone or tablet, you’ll trim to two main panes and a small status bar.
A more concrete, ready‑to‑use tmux workflow
I’m consistently surprised how well a disciplined tmux workflow pays off:
- Window 1 (Editor): Neovim with a standard 3‑column split
- Pane 1: main code
- Pane 2: quick reference (man pages, docs, or a chat console)
- Pane 3: git status or a tiny REPL
- Window 2 (Build/Server): your app’s dev environment
- Pane 1: dev server
- Pane 2: watcher (lint, tests, bundler)
- Window 3 (Logs): live output and quick notes
- Pane 1: application log
- Pane 2: shell for one‑off commands
To reproduce this, you can adapt the following quick script that launches Neovim, npm dev, and a second watcher:
# tmux setup snippet (manual)
tmux new-session -s mobile -n Editor -d
tmux send-keys -t mobile:Editor "nvim ." C-m
tmux new-window -t mobile:2 -n Server -d
tmux send-keys -t mobile:Server "npm run dev" C-m
tmux split-window -v -t mobile:Server
tmux send-keys -t mobile:Server.2 "npm run lint -- --watch" C-m
tmux new-window -t mobile:3 -n Logs -d
tmux send-keys -t mobile:Logs "tail -f logs/app.log" C-m
tmux select-window -t mobile:Editor
tmux attach -t mobile
If you adopt this pattern, you’ll save dozens of “where did I leave that pane” minutes per day.
Real‑world tips to make it stick
- Keyboard shortcuts matter. If you’re on a laptop, you want intuitive bindings. I map basic pane navigation to hjkl (vi style) and use a couple of chord-based command keys for common tasks. If you’re using iPad or a compact keyboard, keep the default tmux prefix (Ctrl-b) and add a personal leaner binding for window switching.
- Keep layouts small and predictable. A minimalist three‑window layout is often enough. Save a “mobile layout” in tmux-resurrect so that a reconnect brings you back exactly where you left off.
- Use powerline fonts or Nerd Fonts for a readable status line. A cramped font makes it hard to distinguish logs from code.
- Always alias a quick start. I have a short alias that spawns the “mobile” session with the standard layout, so I don’t waste time reconstructing the workflow:
- alias mobiledev="tmux new-session -s mobile -n Editor -d; tmux send-keys -t mobile:Editor 'nvim .' C-m; tmux new-window -t mobile:2 -n Server -d; tmux send-keys -t mobile:Server 'npm run dev' C-m; tmux attach -t mobile"
Common pitfalls and how I fix them
- Pitfall: Disconnected sessions lose state.
- Fix: tmux-resurrect + tmux-continuum ensure layouts and commands persist across reboots or network drops.
- Pitfall: Pane clutter makes navigation painful on small screens.
- Fix: Use a three‑pane layout max per window; avoid extra panes unless necessary. Adopt a consistent layout so you know where to look when you switch devices.
- Pitfall: Emulators hog resources and make the editor lag.
- Fix: Run emulators in their own window, or on a separate machine if possible. Limit CPU usage by using headless or snapshot modes if you can.
- Pitfall: Inconsistent fonts make the status line unreadable.
- Fix: Pick a font with good readability; set a fixed status bar width and simplify the right side with 1–2 items max.
Extra: a lightweight alternative for minimal setups
If you’re totally bootstrapped and don’t want plugins, you can still get a lot done with a few durable tmux commands:
- Create a session and three windows:
- tmux new-session -s mobile -n Editor -d
- tmux new-window -t mobile:2 -n Server -d
- tmux new-window -t mobile:3 -n Logs -d
- Launch editor and server in the right panes:
- tmux send-keys -t mobile:1 "nvim ." C-m
- tmux send-keys -t mobile:2 "npm run dev" C-m
- tmux send-keys -t mobile:3 "tail -f logs/app.log" C-m
- Attach:
- tmux attach -t mobile
This minimalist approach gives you a robust, repeatable workflow without the plugin footprint. If you find yourself wanting more later, you can always add plugins (and a .tmux.conf) in a few hours.
How this fits into a sustainable bootstrapped workflow
- It’s cheap: a few dotfiles, a shell, and a tiny tmux setup is enough to replace expensive IDE “efficiency hacks.”
- It scales with velocity: as you ship more products, the same layout applies to multiple repos, so you’re not re‑learning the same dev ergonomics.
- It’s portable: the layout travels with you. Whether you’re on macOS, Linux, or SSH’ing from an iPad, the same tmux setup holds.
In the end, tmux is a force multiplier for indie hackers who don’t have a full-time workstation. It keeps context, reduces cognitive load, and makes it feasible to ship solo from any café or coworking space.
Conclusion and takeaways
- Start with a simple three‑window layout: Editor, Server, Logs. Expand later if you need more.
- Use TPM + a couple of plugins (tmux-resurrect, tmux-continuum) to survive disconnects and keep layouts sane.
- Automate initialization with a small script so you don’t waste time on setup.
- Don’t over‑engineer. The best tmux workflows are the ones you actually use daily. Keep it small, predictable, and fast.
- If you want to keep learning, check out related posts on “Developing a portable toolchain for bootstrapped products” and “Efficient CLI workflows that actually save time.”
If you try this approach, I’d love to hear what worked for you and what didn’t. Share your layout or a tip you swear by. You can find me on X (@fullybootstrap) sharing experiments, failures, and small wins from the San Francisco Bay Area indie hustle. And if you want more real‑world notes, I’ve got a growing catalog of practical engineering and bootstrapping guides that cut through the fluff.
Happy coding, wherever you code from.