The Problem: Repetitive Terminal Setup
Every time I started working on something, I’d go through the same motions:
tmux new-session -s work
# Ctrl-b c (create window)
# Ctrl-b , (rename to "editor")
# Ctrl-b c
# Ctrl-b , (rename to "server")
# Ctrl-b c
# Ctrl-b , (rename to "terminal")
Multiply this by switching between work projects, side projects, and personal stuff throughout the day. I was spending 2-3 minutes on setup every time I context-switched.
I wanted one command that would give me a ready-to-code environment.
Enter dev-session-manager
A simple Bash utility that creates pre-configured tmux sessions:
dev work # Creates session with editor, server, tests windows
dev hobby # Creates session for side projects
dev personal # Creates session for personal coding
That’s it. No manual window creation. No renaming. Just ready to work.
How It Works
The tool reads session configurations from ~/.config/dev-sessions/ and creates tmux sessions based on YAML templates:
# ~/.config/dev-sessions/work.yml
name: work
windows:
- name: editor
commands:
- cd ~/code/work-project
- nvim
- name: server
commands:
- cd ~/code/work-project
- mix phx.server
- name: terminal
commands:
- cd ~/code/work-project
When you run dev work, the script:
- Checks if the session already exists
- If not, creates a new tmux session
- Spawns windows defined in the config
- Runs startup commands in each window
- Attaches to the session
The core logic is straightforward:
create_session() {
local config=$1
local session_name=$(yq eval '.name' "$config")
# Create session
tmux new-session -d -s "$session_name"
# Create windows
yq eval '.windows[] | .name' "$config" | while read -r window_name; do
tmux new-window -t "$session_name:" -n "$window_name"
# Run commands for this window
yq eval ".windows[] | select(.name == \"$window_name\") | .commands[]" "$config" | \
while read -r cmd; do
tmux send-keys -t "$session_name:$window_name" "$cmd" C-m
done
done
# Attach
tmux attach-session -t "$session_name"
}
Publishing to Homebrew
I wrote this on vacation and wanted to make it easy to install. Publishing to Homebrew taught me how package managers actually work.
Creating a Homebrew Tap
Homebrew “taps” are just Git repositories with a Formula/ directory:
# Create tap repository
mkdir -p homebrew-tap/Formula
cd homebrew-tap
# Write the formula
cat > Formula/dev-session-manager.rb <<'EOF'
class DevSessionManager < Formula
desc "Automate tmux session creation from YAML configs"
homepage "https://github.com/jeryldev/homebrew-tap"
url "https://github.com/jeryldev/dev-session-manager/archive/v1.0.0.tar.gz"
sha256 "..."
depends_on "tmux"
depends_on "yq"
def install
bin.install "dev"
end
end
EOF
The tricky part was getting the SHA256 hash right. Homebrew requires exact checksums:
# Generate SHA256 for the release tarball
curl -L https://github.com/jeryldev/dev-session-manager/archive/v1.0.0.tar.gz | shasum -a 256
Publishing Process
- Tag a release on the main project repository
- Calculate SHA256 of the release tarball
- Update Formula with new URL and hash
- Push to tap repository
- Test installation on a clean machine
Users can now install with:
brew tap jeryldev/tap
brew install dev-session-manager
dev help
What I Learned
1. YAML for configuration was the right choice
I considered JSON, TOML, and even custom formats. YAML won because:
- Human-readable and editable
- Supports comments
yqCLI makes parsing trivial in Bash
2. Idempotency matters
The tool checks if a session exists before creating it. Running dev work multiple times doesn’t break anything - it just attaches to the existing session.
3. Homebrew formulas are just Ruby
Understanding that formulas are Ruby classes demystified the whole process. The DSL is syntactic sugar over standard Ruby.
4. Dependencies need to be explicit
The formula declares tmux and yq as dependencies. Homebrew installs them automatically if missing. This prevents cryptic errors.
Real-World Usage
My typical workflow now:
# Morning: Start work session
dev work
# After lunch: Switch to side project
dev hobby
# Evening: Personal coding
dev personal
Each command gives me exactly the layout I need. No manual setup.
The Rough Documentation
I mentioned the documentation might be rough - I wrote this in a few hours on vacation. The README is functional but could use:
- Better examples for complex configurations
- Troubleshooting section
- GIF demos showing actual usage
- Migration guide from manual tmux usage
But it works. And that’s enough for version 1.0.
Try It Out
If you use tmux and find yourself doing the same setup routine, give it a shot:
brew tap jeryldev/tap
brew install dev-session-manager
dev help
The tool is open source:
- GitHub: github.com/jeryldev/homebrew-tap
- Requirements: tmux, yq, Bash 4.0+
Feedback and contributions welcome. If something breaks, file an issue.
What’s Next
Potential improvements:
- Support for nested panes (not just windows)
- Template inheritance (reuse common configurations)
- Integration with project detection (auto-detect project type)
- Support for environment variables in configs
For now, it solves my daily friction. That’s good enough.
Links: