---
title: "Setup"
description: "One command turns an existing git repo into a thinslice workspace for running many isolated copies of your app. It won't re-clone anything or touch uncommitted work."
---
# Setup

`slice setup` transforms an existing git repository into a managed thinslice workspace. Run it once inside a normal git checkout.

## How it works 

Given a repository at `~/src/myapp` with the `main` branch checked out:

```
$ cd ~/src/myapp
$ slice setup
```

Your git checkout directory is restructured into:

```
~/src/myapp/
  +clone+/                    # bare git repo
  +state+/
    bindings.toml             # 
  main/                       # your previous checkout (contents moved here)
  local/                      # your worktrees
  pr/                         # worktrees for PR review
  tmp/                        # throwaway worktrees
```

The result is that the original working state lands in `~/src/myapp/main/` intact,
the full git history is in `+clone+/`, and the structure is ready for
`slice up` to use once `+state+/bindings.toml` is created.


1. Renaming the checkout directory to a staging name (`~/src/myapp.__stack_setup__`)
2. Creating a new `~/src/myapp/` with the target subdirectories
3. Setting `core.bare = true` in the `.git/config` and moving `.git/` to
   `+clone+/` — a bare repo is structurally identical to a `.git/` directory,
   so no objects are copied or re-fetched
4. Running `git worktree add --no-checkout` to register the branch worktree at
   ~/src/myapp/main.
5. Then moving the existing files from the staging directory
   (`~/src/myapp.__thinslice_setup__`) into ~/src/myapp/main — avoids re-expanding objects
   from the pack and preserves any dirty working tree state
5. Removing the now-empty staging directory with `rmdir
   ~/src/myapp.__thinslice_setup__`

### +clone+

A bare clone of your repository. All worktrees are created from this bare repo. The `+` delimiters ensure it sorts distinctly from your worktree directories and is visually obvious as infrastructure.

### +state+

Contains all state directories. Each state directory holds everything that isn't code: database files, redis data, port assignments, and the generated `thinslice.toml` configuration. State directories are never checked into git.

The `template-clean` state is created during setup by running your `thinslice.new-state` executable. It represents a clean starting point that you can clone when creating new slices.

### main/

Your original checkout, moved into place as a worktree of the bare repo. This is a shared branch — it tracks `origin/main` and is not prefixed with a namespace.

### local/, pr/, tmp/

Empty directories created as organizational namespaces for your worktrees. These correspond to branch name prefixes:

- **local/** — Your branches. Work you're doing yourself. `slice local feature-auth` creates branch `local/feature-auth` and directory `local/feature-auth/`.
- **pr/** — Other people's branches. PRs you're reviewing locally. `slice pr checkout 4521` creates branch `pr/4521` and directory `pr/4521/`.
- **tmp/** — Disposable branches. Quick explorations, agent tasks, experiments. `slice tmp try-sqlx` creates branch `tmp/try-sqlx` and directory `tmp/try-sqlx/`. Clean up with `slice rm` or `slice gc`.

Top-level worktrees (like `main`, `dev`, `staging`) are shared branches that track remotes. They don't get a namespace prefix.

## Requirements

`slice setup` expects to find a `thinslice.new-state` executable in one of these locations in your project, searched in order:

1. `./thinslice.new-state`
2. `./src/thinslice.new-state`
3. `./config/thinslice.new-state`

This executable is run to generate the initial `template-clean` state. See [Template](template.md) for how to write one.

## After setup

Your `.gitignore` should already exclude state and worktree artifacts, but you may want to add:

```
+clone+/
+state+/
local/
pr/
tmp/
```

Or set up your project-level `.gitignore` before running `slice setup` so these are excluded from any worktree.

## Re-running setup

`slice setup` is idempotent. If the workspace is already set up, it does nothing. To force a fresh `template-clean` state, use:

```
$ slice state rm template-clean
$ slice state new template-clean
```
