Jjw: Workspace Manager for Jj

ingve1 pts0 comments

Introducing jjw: a workspace manager for jj · Aran Wilkinson&darr;Skip to main content<br>I&rsquo;ve just released jjw, a small command line tool for managing jj workspaces.<br>The short version is that jjw gives me a nicer workflow for creating, switching between, and deleting isolated jj workspaces. The slightly longer version is that I wanted a reliable way to run multiple coding agents in parallel without them trampling over each other&rsquo;s working copies, local state, or setup.<br>It is inspired by wt, a Git worktree manager, but I decided to adapt it for working with jj and jj&rsquo;s workspace and bookmark model.<br>Why I built it #<br>I&rsquo;ve been using jj more recently and really like the model. It makes a lot of day-to-day version control operations feel calmer, especially once you get used to the working copy being a commit and the operation log being there as a safety net.<br>At the same time, my development workflow has changed. I often want to try a few ideas at once, or hand off different tasks to different LLM coding agents. That works best when each task has its own clean, isolated environment.<br>You can already do this with jj workspace add, but I found myself wanting a bit more structure around it:<br>consistent workspace names and locations<br>matching bookmarks for pull requests<br>quick shell integration so creating or switching workspaces actually moves my shell there<br>lifecycle hooks for setting up or tearing down per-workspace state<br>safe deletion and cleanup once work has been merged<br>That became jjw.<br>What jjw does #<br>jjw manages workspaces inside a configured directory in your repository. A basic setup looks like this:<br>version: 1<br>workspace_dir: workspaces<br>default_branch: main

Once configured, creating a workspace is as simple as:<br>jjw create feature-x

Behind the scenes, jjw will:<br>create a jj workspace at workspaces/feature-x<br>create a bookmark for the workspace<br>allocate a workspace index, if configured<br>run any configured post_create hooks<br>ask the shell integration to move you into the new workspace<br>From there you can work normally, push the bookmark with jj git push, open a pull request, and eventually clean things up when the work is merged.<br>The commands #<br>The core commands are intentionally small:<br>jjw create feature-x # create workspace + bookmark, then cd into it<br>jjw list # list workspaces<br>jjw cd feature-x # switch to a workspace<br>jjw exit # return to the main repo<br>jjw delete feature-x # delete workspace, bookmark, and files<br>jjw cleanup # remove clean workspaces with merged bookmarks

There are also configuration and utility commands:<br>jjw config init<br>jjw config get workspace_dir<br>jjw root<br>jjw version

The goal is not to wrap every part of jj. It is only there to smooth over the workspace lifecycle.<br>Hooks for real project setup #<br>The feature that makes this particularly useful for me is lifecycle hooks.<br>A lot of projects need a bit of per-workspace setup. Maybe you need a unique dev server port, a generated .env file, a temporary database name, or some other local resource. When running multiple agents in parallel, those details matter a lot more.<br>jjw supports hooks such as:<br>pre_create<br>post_create<br>pre_delete<br>post_delete<br>Hooks receive useful environment variables, including:<br>JJW_NAME<br>JJW_PATH<br>JJW_BOOKMARK<br>JJW_REPO_ROOT<br>JJW_JJ_ROOT<br>JJW_WORKSPACE_DIR<br>JJW_INDEX

For example, you can use the allocated index to assign each workspace a different port:<br>hooks:<br>post_create:<br>- script: ./scripts/setup-ports.sh

#!/bin/bash<br>PORT=$((3000 + JJW_INDEX))<br>echo "Dev server port: $PORT"

That is the kind of small automation that makes parallel workspaces much easier to live with.<br>Getting started #<br>The easiest way to install jjw is with go install:<br>go install github.com/aranw/jjw@latest

Alternatively, you can build it from source. This requires Just to be installed.<br>git clone https://github.com/aranw/jjw.git<br>cd jjw<br>just install

Then add the shell integration for your shell:<br># zsh<br>eval "$(jjw init zsh)"

# bash<br>eval "$(jjw init bash)"

# fish<br>jjw init fish | source

jjw currently expects jj 0.25+ and a colocated jj/git repository.<br>In a repository where you want to use it, initialise the config:<br>jjw config init

Then create your first workspace:<br>jjw create my-change

What&rsquo;s next #<br>This is an initial release, so I expect the edges to become clearer as I use it more. The current focus is keeping the tool boring and predictable: create workspaces, connect them to bookmarks, run hooks, and clean them up safely.<br>If you use jj, run multiple local workstreams, or are experimenting with coding agents, I&rsquo;d be interested to hear whether this fits your workflow.<br>The project is on GitHub here: github.com/aranw/jjw.

&uarr;

workspace workspaces hooks create rsquo feature

Related Articles