Multi-Pane Dev Tasks With Mise and WezTerm
I’ve finally transitioned all of my projects to have their tasks wrapped with
Mise. I love how this lets me pop into any directory
and type mise run to see the list of tasks for that project. I think this
will be especially helpful in projects I don’t touch very often.
For example, here are the tasks I have for this blog:

I typically have several tasks to run when I’m working on a project - running the build, tailing logs, etc. It’s nice to have all these grouped in one terminal tab, so I create as many panes as I have tasks in a new WezTerm window and then manually start each task. It’s a bit tedious to do when switching contexts.
Yesterday, I wondered if there was a way to automate creating the WezTerm layout and sending the appropriate task to the appropriate pane. It turns out there is, and it isn’t too difficult!
A quick Kagi search led me to this GitHub discussion, which got me 99% of the way there.
Here’s an example from a Laravel project that I’m working on:
[tools]
bun = 'latest'
[tasks.build]
description = "Build the application for production"
run = "bun run build"
[tasks.build-dev]
description = "Run development build tasks"
run = "bun run dev"
[tasks.pail]
description = "Tail logs with pail"
run = "php artisan pail -vv --timeout=0"
[tasks.queue]
description = "Run the queue worker"
run = "php artisan queue:work --verbose"
[tasks.phpstan]
description = "Run PHPStan"
run = "./vendor/bin/phpstan"
[tasks.arch]
description = "Run architecture tests"
run = "php artisan test --testsuite=Architecture"
[tasks.check]
description = "Run all static analysis checks"
depends = ["phpstan", "arch"]
[tasks.dev]
description = "Run development tasks in WezTerm panes"
run = """
run_command() {
local pane_id
local command_to_run
pane_id="$1"
command_to_run="$2"
echo "$command_to_run\n" | wezterm cli send-text --no-paste --pane-id "$pane_id"
}
new_pane=$(wezterm cli spawn --cwd "$MISE_PROJECT_ROOT")
run_command "$new_pane" "mise run build-dev"
second_pane=$(wezterm cli split-pane --right --pane-id "$new_pane")
third_pane=$(wezterm cli split-pane --bottom --pane-id "$second_pane")
run_command "$second_pane" "mise run pail"
run_command "$third_pane" "mise run queue"
"""
mise run dev starts up Vite, tails the logs, and runs the queue worker in separate panes.
I can kill all the tasks at once with Cmd+w.
If you’ve ever used Laravel Solo, you might consider this a framework-agnostic alternative.
Hope someone else finds it helpful! 😄
PS - I realize that tmux sessions are much more powerful solution for this kind of thing, but I prefer using WezTerm’s native multiplexer.