Launching Dev Dependencies with tmux
Tags: productivity, coding, todayilearned
Published: 2020-03-29 18:52:06

---
title: Launching Dev Dependencies with tmux
published: true
date: 2020-03-29 16:35:06 UTC
tags: [productivity, coding, todayilearned]
canonical_url: https://camdez.com/blog/2020/03/29/launching-dev-dependencies-with-tmux/
---

When working on [CollBox][], we have a handful of external services the app depends on which we need to have running at development time. I used to run these via [Foreman][], but somewhere along the way my Ruby installation seems to have gotten borked (thanks, [Catalina][]?) and since then I've been running the services by hand.  I always work in a [`tmux`][tmux] session anyway, so I decided it was time to see what it would look like to launch my window full of dependencies in `tmux` from a script.

<!--more-->

As it turns out, `tmux` is fantastically scriptable.  If you simply run `tmux <command>` from a shell inside of a `tmux` session, that command will be run by the encapsulating `tmux` instance, and these are the same set of commands that can be bound to your `tmux` keyboard shortcuts.  You can also simply send a stream of keystrokes to panes inside of `tmux`.  All of this means running my four dependencies in a single window (named "deps") under their own panes is as simple as:

```sh
#!/bin/sh
# deps.sh

tmux new-window -n "deps"

tmux send-keys "redis-server redis.conf" Enter
tmux split-window
tmux send-keys "datomic/bin/transactor transactor.properties" Enter
tmux split-window
tmux send-keys "lein shadow-watch" Enter
tmux split-window
tmux send-keys "npx gulp" Enter

tmux select-layout tiled

```

When I'm ready to work on the project I simply run `./deps.sh` at my shell and I end up with something like this:

```sh
+---------------------------------+---------------------------------+
| $ redis-server redis.conf       | $ datomic/bin/transactor transa |
| ...                             | ...                             |
|                                 |                                 |
|                                 |                                 |
|                                 |                                 |
|                                 |                                 |
|                                 |                                 |
|---------------------------------+---------------------------------|
| $ lein shadow-watch             | $ npx gulp                      |
| ...                             | ...                             |
|                                 |                                 |
|                                 |                                 |
|                                 |                                 |
|                                 |                                 |
|                                 |                                 |
+---------------------------------+---------------------------------+
| 1:deps* | 2:zsh |                                                 |
+-------------------------------------------------------------------+
```

*fin.*

---

A few thoughts on other tools that can be used to address this same problem:

- [Foreman][]: Great project; I've used it happy for years. I love the aggregated, colorized logs, which keep things compact yet comprehensible.  The one downside is that it's not convenient to restart a single service, should you need to.  But my main reason for switching was just to see if I could avoid the additional dependencies to my development stack given that I already use `tmux`.
- [tmuxinator][]: Looks like a nice project to encapsulate essentially what I did above into a simple data-driven format, but I don't see that the gains are big enough (at least for my simple case) to bother adding the additional dependencies.
- [Docker][]: As much as I like the idea of cleanly locking down development dependencies in the Docker style, in practice I've found it exceptionally costly, both in terms of the performance overhead (I literally had to buy a new laptop at my last job once we switched to Docker), and the increased complexity of accessing application state / debugging.

[catalina]: https://www.apple.com/macos/catalina/
[collbox]: https://collbox.co
[docker]: https://www.docker.com/
[foreman]: https://github.com/ddollar/foreman
[tmux]: https://github.com/tmux/tmux/wiki
[tmuxinator]: https://github.com/tmuxinator/tmuxinator