|
| 1 | +# The Story Behind warp-cli |
| 2 | + |
| 3 | +## Why This Started |
| 4 | + |
| 5 | +I use Cloudflare WARP daily as a developer. I need to: |
| 6 | +- Test applications with different geographic origins |
| 7 | +- Access internal networks securely |
| 8 | +- Toggle VPN connectivity on demand for local development |
| 9 | +- Integrate VPN control into scripts and CI/CD pipelines |
| 10 | + |
| 11 | +The problem? **The official WARP GUI app is optimized for non-technical users**, not developers. |
| 12 | + |
| 13 | +### The GUI Problem |
| 14 | + |
| 15 | +The WARP app sits in your menu bar consuming: |
| 16 | +- **Screen real estate** - constant presence |
| 17 | +- **Battery life** - GUI constantly refreshing status |
| 18 | +- **CPU cycles** - background UI work |
| 19 | +- **Mental bandwidth** - notifications and visual distractions |
| 20 | +- **Automation capability** - zero scripting, no pipelines, no JSON output |
| 21 | + |
| 22 | +Meanwhile, buried inside macOS is `warp-cli` - a binary that does everything. It's just hidden behind 20+ confusing command flags and no UX. |
| 23 | + |
| 24 | +## The Solution |
| 25 | + |
| 26 | +Build a beautiful CLI wrapper that: |
| 27 | +1. Exposes WARP functionality through intuitive commands |
| 28 | +2. Leaves the daemon running (it does the real work) |
| 29 | +3. Provides a developer-first interface for terminal workflows |
| 30 | +4. Enables scripting, automation, and pipeline integration |
| 31 | + |
| 32 | +**One command instead of confusion:** |
| 33 | +```bash |
| 34 | +# Instead of: |
| 35 | +warp-cli tunnel host add example.com |
| 36 | + |
| 37 | +# Just: |
| 38 | +warp exclude add example.com |
| 39 | +``` |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +## What I Learned |
| 44 | + |
| 45 | +### 1. Reverse Engineering macOS Applications |
| 46 | + |
| 47 | +I discovered that **the Cloudflare WARP architecture is elegant but hidden**. |
| 48 | + |
| 49 | +**The discovery process:** |
| 50 | +- Located the `CloudflareWARP` daemon running as root via launchd |
| 51 | +- Found the communication protocol: gRPC over Unix domain socket at `/var/run/warp_service` |
| 52 | +- Extracted binaries from the `.app` bundle structure |
| 53 | +- Understood how launchd manages daemon lifecycle and auto-start |
| 54 | + |
| 55 | +**Why this matters:** Most macOS apps are black boxes. Understanding the internals taught me: |
| 56 | +- How system daemons work |
| 57 | +- IPC (Inter-Process Communication) patterns |
| 58 | +- How to work with system-level resources |
| 59 | +- The importance of good process management |
| 60 | + |
| 61 | +### 2. Rust for CLI Development |
| 62 | + |
| 63 | +Building this in Rust taught me about real-world CLI design. |
| 64 | + |
| 65 | +**Key technical insights:** |
| 66 | +- **`clap` crate** - The power of derive macros for command parsing |
| 67 | +- **Error handling** - Using `anyhow` for human-friendly error messages |
| 68 | +- **Output formatting** - The `colored` crate for terminal UX |
| 69 | +- **JSON serialization** - `serde_json` for structured output |
| 70 | +- **Subprocess execution** - Calling system binaries and parsing results |
| 71 | + |
| 72 | +**The bigger lesson:** Rust forces you to think about: |
| 73 | +- Error cases upfront |
| 74 | +- Type safety in CLI arguments |
| 75 | +- Performance (single static binary, no runtime) |
| 76 | +- Security (memory safety matters for system tools) |
| 77 | + |
| 78 | +### 3. CLI/UX Design Philosophy |
| 79 | + |
| 80 | +This project taught me that **UX design applies to CLIs just as much as GUIs**. |
| 81 | + |
| 82 | +**Design principles I discovered:** |
| 83 | +- **Simplicity over completeness** - 8 core commands beats 20+ flags |
| 84 | +- **Consistency in naming** - `exclude add/remove/list` is predictable |
| 85 | +- **Progressive disclosure** - Help text reveals advanced options |
| 86 | +- **Feedback matters** - Colored output tells you immediately if it worked |
| 87 | +- **Scriptability is a feature** - Not an afterthought |
| 88 | + |
| 89 | +**Real example:** |
| 90 | +```bash |
| 91 | +# Good CLI feedback: |
| 92 | +$ warp up |
| 93 | +✓ Connected to WARP |
| 94 | + |
| 95 | +# vs confusing daemon output: |
| 96 | +$ warp-cli connect |
| 97 | +Attempting connection... |
| 98 | +``` |
| 99 | + |
| 100 | +### 4. System Integration on macOS |
| 101 | + |
| 102 | +Working with launchd, plist files, and system binaries taught me how macOS really works. |
| 103 | + |
| 104 | +**What I learned:** |
| 105 | +- **launchd** is more powerful than people realize |
| 106 | +- **plist files** are just XML with specific structure |
| 107 | +- **Unix domain sockets** are the IPC of choice on macOS |
| 108 | +- **Permissions and sudo** - when and why you need them |
| 109 | +- **System service management** - starting/stopping daemons safely |
| 110 | + |
| 111 | +This knowledge is transferable to any system software project. |
| 112 | + |
| 113 | +### 5. Installation Automation |
| 114 | + |
| 115 | +Building smart installation scripts (`install-complete.sh`, `install-from-github.sh`) taught me: |
| 116 | + |
| 117 | +- **Dependency detection** - Check if WARP is installed before proceeding |
| 118 | +- **Non-interactive installation** - `curl | bash` safety practices |
| 119 | +- **User experience in installation** - Clear feedback at each step |
| 120 | +- **Fallback strategies** - Multiple installation paths for different users |
| 121 | +- **Verification** - Confirm everything worked |
| 122 | + |
| 123 | +### 6. Multi-Tap Homebrew Publishing |
| 124 | + |
| 125 | +Setting up automated Homebrew publishing with GitHub Actions revealed: |
| 126 | + |
| 127 | +- **Tap architecture** - How Homebrew discovers and installs formulas |
| 128 | +- **SHA256 automation** - Calculate and embed in CI/CD |
| 129 | +- **Multi-app scaling** - One tap can host unlimited formulas |
| 130 | +- **CI/CD patterns** - Conditional logic for different event types (push vs release) |
| 131 | +- **Cross-repo coordination** - Publishing to a separate repository safely |
| 132 | + |
| 133 | +--- |
| 134 | + |
| 135 | +## Why CLI > GUI Matters |
| 136 | + |
| 137 | +### The Core Difference |
| 138 | + |
| 139 | +| Aspect | GUI App | CLI Tool | |
| 140 | +|--------|---------|----------| |
| 141 | +| **Startup time** | 2-3 seconds | Instant | |
| 142 | +| **Memory usage** | 150+ MB resident | <10 MB | |
| 143 | +| **CPU idle** | Constantly refreshing | Zero overhead | |
| 144 | +| **Automation** | Impossible | Native | |
| 145 | +| **Pipeline integration** | None | Full JSON support | |
| 146 | +| **Developer workflow** | Context switch required | Stay in terminal | |
| 147 | +| **Scripting** | Can't script GUI clicks | Shell scripts, CI/CD | |
| 148 | + |
| 149 | +### It's Not Just About Performance |
| 150 | + |
| 151 | +The philosophical difference runs deeper: |
| 152 | + |
| 153 | +**GUI philosophy:** "Helpful features, always available, user-friendly" |
| 154 | +- Assumes users want visual feedback |
| 155 | +- Optimizes for discovery |
| 156 | +- Trades resources for convenience |
| 157 | + |
| 158 | +**CLI philosophy:** "Do what you ask, get out of the way" |
| 159 | +- Assumes users know what they want |
| 160 | +- Optimizes for automation |
| 161 | +- Respects your system resources |
| 162 | + |
| 163 | +**For developers:** CLI is the right choice because: |
| 164 | +1. We think in commands, not clicks |
| 165 | +2. We automate, not explore |
| 166 | +3. We integrate, not interact |
| 167 | +4. We script, not watch |
| 168 | + |
| 169 | +--- |
| 170 | + |
| 171 | +## The Space: Why This Matters for Developers |
| 172 | + |
| 173 | +### The Problem We're Solving |
| 174 | + |
| 175 | +There's a growing trend: **companies shipping GUI-first apps for things that should be CLIs.** |
| 176 | + |
| 177 | +Examples: |
| 178 | +- Docker Desktop (GUI wrapper around daemon) |
| 179 | +- GitHub Desktop (GUI wrapper around git) |
| 180 | +- Cloudflare WARP (GUI wrapper around daemon) |
| 181 | + |
| 182 | +The issue: **Developers are forced to pay the resource cost of GUIs they don't want.** |
| 183 | + |
| 184 | +### The Opportunity |
| 185 | + |
| 186 | +This project proves that **better UX isn't the GUI's exclusive domain.** |
| 187 | + |
| 188 | +A well-designed CLI can be: |
| 189 | +- Easier to use than the GUI (fewer options, clear defaults) |
| 190 | +- More powerful than the GUI (scriptable, pipelinable) |
| 191 | +- Less resource-intensive than the GUI (no rendering overhead) |
| 192 | +- More accessible than the GUI (terminal works everywhere - remote servers, containers, CI/CD) |
| 193 | + |
| 194 | +### What This Teaches |
| 195 | + |
| 196 | +**For developers:** |
| 197 | +- You don't need a GUI to be user-friendly |
| 198 | +- A good CLI is a form of great design |
| 199 | +- Simplicity means removing features, not adding options |
| 200 | +- Automation should be built-in, not bolted on |
| 201 | + |
| 202 | +**For the industry:** |
| 203 | +- Not everything needs a GUI |
| 204 | +- Respecting developer workflows means providing CLI access |
| 205 | +- The daemon can do the heavy lifting; the interface can be simple |
| 206 | +- Tooling is a product too |
| 207 | + |
| 208 | +### The Ecosystem Impact |
| 209 | + |
| 210 | +If more tools shipped with: |
| 211 | +- Well-designed CLIs by default |
| 212 | +- GUIs as optional add-ons |
| 213 | +- Full automation support |
| 214 | +- Respect for developer workflows |
| 215 | + |
| 216 | +We'd have: |
| 217 | +- **Less bloat** on developer machines |
| 218 | +- **More automation** in CI/CD pipelines |
| 219 | +- **Better developer experience** overall |
| 220 | +- **Faster iteration** (no GUI to refresh/restart) |
| 221 | + |
| 222 | +--- |
| 223 | + |
| 224 | +## Key Insights |
| 225 | + |
| 226 | +### 1. Simplicity Is Radical |
| 227 | + |
| 228 | +In a world of feature-bloated apps, a tool that does one thing well is revolutionary. |
| 229 | + |
| 230 | +The warp-cli project succeeded because it said "no" to everything except the core: intuitive VPN control. |
| 231 | + |
| 232 | +### 2. UX Isn't About Pixels |
| 233 | + |
| 234 | +Good UX is about respecting your user's time and resources. |
| 235 | + |
| 236 | +A CLI that runs in 50ms is better UX than a GUI that takes 3 seconds to launch. |
| 237 | + |
| 238 | +### 3. Reverse Engineering Builds Understanding |
| 239 | + |
| 240 | +I didn't understand how WARP worked until I extracted the binaries and traced the socket communication. |
| 241 | + |
| 242 | +This deep understanding allowed me to build something better. |
| 243 | + |
| 244 | +### 4. Rust Forced Good Practices |
| 245 | + |
| 246 | +Rust's compiler caught bugs I wouldn't have found in Python or Go. |
| 247 | + |
| 248 | +Type safety and memory safety matter, even for system utilities. |
| 249 | + |
| 250 | +### 5. Automation Changes Everything |
| 251 | + |
| 252 | +The ability to script VPN control opens up possibilities: |
| 253 | +- Automatic VPN toggle in CI/CD |
| 254 | +- Location-based connection changes |
| 255 | +- Monitoring and health checks |
| 256 | +- Integration with other tools |
| 257 | + |
| 258 | +The GUI can never do this. |
| 259 | + |
| 260 | +--- |
| 261 | + |
| 262 | +## What I'd Do Differently |
| 263 | + |
| 264 | +### In Retrospect |
| 265 | + |
| 266 | +1. **Started with the CLI first** - I should have built the wrapper before understanding why |
| 267 | +2. **More comprehensive testing** - Added tests later in the process |
| 268 | +3. **Performance profiling** - Measured resource usage more rigorously |
| 269 | +4. **User feedback earlier** - Validated the UX with actual users sooner |
| 270 | +5. **Documentation alongside code** - Docs became comprehensive only at the end |
| 271 | + |
| 272 | +### For Others Building Similar Tools |
| 273 | + |
| 274 | +1. **Understand your users first** - What's their pain point? |
| 275 | +2. **Simplicity > completeness** - Start with core, add features later |
| 276 | +3. **Automation support from day one** - Don't make it an afterthought |
| 277 | +4. **Good error messages** - They matter more in CLI than GUI |
| 278 | +5. **Make it installable** - Homebrew, one-liners, or package managers are table stakes |
| 279 | + |
| 280 | +--- |
| 281 | + |
| 282 | +## The Bigger Picture |
| 283 | + |
| 284 | +This project started as a personal frustration: **an over-engineered solution to a simple problem.** |
| 285 | + |
| 286 | +It became a lesson in: |
| 287 | +- How to think about design for developers |
| 288 | +- How systems actually work (not how they're marketed) |
| 289 | +- How to build tools that respect user resources |
| 290 | +- How small, focused tools outperform bloated all-in-ones |
| 291 | + |
| 292 | +### Why This Matters Beyond WARP |
| 293 | + |
| 294 | +Every developer uses dozens of tools. Most are: |
| 295 | +- Slower than they need to be |
| 296 | +- More complex than necessary |
| 297 | +- Built with GUIs when CLIs would be better |
| 298 | +- Hard to automate or integrate |
| 299 | + |
| 300 | +**This project is proof that you can do better.** |
| 301 | + |
| 302 | +--- |
| 303 | + |
| 304 | +## What's Next |
| 305 | + |
| 306 | +### For warp-cli |
| 307 | + |
| 308 | +- User feedback from developers using it daily |
| 309 | +- Expand the formula library (homebrew-tools tap) |
| 310 | +- Explore macOS-specific optimizations |
| 311 | +- Potential contribution back to Cloudflare (in some form) |
| 312 | + |
| 313 | +### For Me |
| 314 | + |
| 315 | +- Apply these learnings to other tools |
| 316 | +- Build more dev-first CLI applications |
| 317 | +- Contribute to the open-source CLI ecosystem |
| 318 | +- Help others understand that simple, focused tools matter |
| 319 | + |
| 320 | +--- |
| 321 | + |
| 322 | +## Final Thoughts |
| 323 | + |
| 324 | +This project is small. It's not going to change the world. |
| 325 | + |
| 326 | +But it represents something important: **the belief that developer experience matters, and that simplicity beats complexity.** |
| 327 | + |
| 328 | +Every tool you use should respect your: |
| 329 | +- Time (fast startup, zero overhead) |
| 330 | +- Attention (clear output, no noise) |
| 331 | +- Workflow (CLI, not GUI if you're a developer) |
| 332 | +- Automation needs (scriptable by design) |
| 333 | + |
| 334 | +warp-cli is my small contribution to that vision. |
| 335 | + |
| 336 | +If you're building tools: **Choose simplicity. Respect your users' resources. Build for automation.** |
| 337 | + |
| 338 | +If you're using tools: **Demand better. CLI tools can be beautiful too.** |
| 339 | + |
| 340 | +--- |
| 341 | + |
| 342 | +*This project is an ongoing learning experience. These insights will evolve as I build more tools and learn from the community.* |
0 commit comments