thinslice

Bind any git worktree to a bag of state — its own postgres, redis, ports, config — and run your whole product. Detach, reattach different code. No Docker, no VMs. Just processes.

How it works

thinslice separates your code from your development state. Your code lives in git worktrees. Your state — database files, redis data, port assignments, configuration — lives in state directories. You bind a worktree to a state directory and run everything.

This means you can:

  • Run multiple copies of your entire product in parallel on one machine
  • Swap different code onto the same state (same database, same ports)
  • Let coding agents work independently, each with their own running backend
  • Clone a known-good state as a starting point for new work

There are no containers, no VMs, no cloud sandboxes. Processes are isolated by port allocation and directory separation. That's it.

The Guide explains each piece as you'd encounter it while setting up a project and using thinslice for the first time.

Getting started

cd ~/src/myapp
slice setup

This transforms your repository into a managed workspace. See Setup for details on the directory structure.

Commands

slice setup, slice use, slice up, slice down, slice detach, slice status, slice local, slice tmp, slice pr checkout, and more. See the full command reference.

A day with thinslice

Suppose you're building a personal video library desktop app — something like a local YouTube for your own clips. Here's what a typical day might look like.

Start working on a feature

Over time you've created a few states — some you mutate as you work, others you keep around as clean starting points to clone from. How you organize them and what you name them is up to you. Here's what yours might look like:

$ cd ~/src/myapp
$ slice state ls

  STATE         BOUND TO   STATUS    DESCRIPTION
  empty         —          stopped   initialized database, no content
  seeded        —          stopped   20 clips imported, tagged, thumbnails done
  mid-import    —          stopped   import 50% complete, resumes on startup
  large         —          stopped   500 clips, for performance testing

Create a worktree for your work. --from seeded clones that state — its database, ports, config — so your new worktree has its own isolated copy.

$ cd ~/src/myapp
$ slice local magic-search --from seeded
$ cd local/magic-search
$ slice up dev

  WORKTREE              STATE           PORTS                       STATUS
  local/magic-search   magic-search   pg:5440 api:3010 web:8090   running

You add a new facet to the search query language, write tests, wire it into the API. You commit, push, and open a PR. This is just git — nothing about thinslice changes how you interact with your repository.

Review a colleague's PR

While you wait for approval, a colleague asks you to review their non-linear timeline editor component. Pull it down with its own state so you can run it without disturbing your feature branch.

$ cd ~/src/myapp
$ slice pr checkout 87 --from seeded
$ cd pr/87
$ slice up dev

Your magic-search branch is still running on its own ports. The PR is running on different ports. You can switch between them in tmux or open both in your browser.

Fire off a coding agent

While reviewing the timeline editor PR, you notice the drag-and-drop reordering doesn't handle undo. Fire off a coding agent to try a fix. --from current clones whatever state you're currently using — same database contents, same test data — into a new throwaway worktree.

$ cd ~/src/myapp/pr/87
$ slice tmp timeline-undo --from current claude -p "add undo support to the drag-and-drop reordering in the timeline editor"

# A new tmux window appears. Claude is working in the left pane,
# your full stack is running in the right pane. Focus stays on
# your current window. You keep working on your review.

Check on everything

$ slice status

  WORKTREE              STATE           PORTS                       STATUS
  local/magic-search   magic-search   pg:5440 api:3010 web:8090   running
  pr/87                 pr-87           pg:5441 api:3011 web:8091   running
  tmp/timeline-undo     timeline-undo   pg:5442 api:3012 web:8092   running

Three copies of your product running simultaneously, each with its own database and ports, no conflicts.

Clean up

$ slice down                     # stop the current worktree's processes
$ slice rm pr/87                 # done reviewing
$ slice gc                       # remove all stopped tmp/ worktrees

Configuration

thinslice uses a thinslice.new-state executable checked into your repo to generate configuration. This script is run each time you create state or bring up a slice. It outputs TOML to stdout. See Template.

If you can't check that script into the repo — locked-down work codebase, strict review process — you can keep it elsewhere on disk and point thinslice at it from your global config. See External Template.

Hooks customize how worktrees are opened and how processes are arranged in tmux. See Hooks.

The tmux DSL provides a concise way to define tmux layouts inside hook definitions. See Tmux DSL.

Port allocation is coordinated globally across all projects on your machine. See Port Registry.