Lifecycle Hooks
Hooks are shell commands defined in rift.yaml that run at worktree lifecycle events.
Hooks
Run commands on lifecycle events:
hooks:
open: "bun install"
jump: "bun install"
close: "echo closing worktree"
purge: "echo purging all"
open— runs after a new worktree is createdjump— runs after switching to a worktreeclose— runs before a worktree is removedpurge— runs before each worktree is removed during purge
How Hooks Work
- Hooks are defined in
rift.yamlat the root of your repository. - Each hook value is passed to
bash -c, so you can use any shell syntax. - Hooks run synchronously — Rift waits for the command to finish before continuing.
- Hook failures are not blocking — if a hook exits with a non-zero code, Rift logs the hook execution but continues with the operation. A failing
openhook will not prevent the worktree from being created. - The working directory is the worktree directory (e.g.
~/.rift/worktrees/my-project/bold-ant). - The environment variable
RIFT_WORKTREEis set to the worktree name (e.g.bold-ant).
Common Patterns
Install dependencies on open/jump:
hooks:
open: "npm install"
jump: "npm install"
Chain multiple commands:
hooks:
open: "npm install && npm run db:migrate"
Call a script file:
hooks:
open: "bash scripts/bootstrap.sh"
This keeps complex setup logic out of rift.yaml and in a version-controlled script.
The Bootstrap Pattern
When multiple worktrees run dev servers simultaneously, they all compete for the same default ports. The bootstrap pattern solves this by running a command on the open and jump hooks that derives a deterministic port from the worktree name — the same worktree always gets the same port.
Bash script example
Create a bootstrap script manually or follow the framework guides:
#!/usr/bin/env bash
set -euo pipefail
# Derive a deterministic port from the worktree name.
# The same worktree always gets the same port (range 3000–9999).
hash=$(echo -n "$RIFT_WORKTREE" | shasum | tr -d 'a-f ' | cut -c1-4)
PORT=$(( (hash % 7000) + 3000 ))
echo "PORT=$PORT" > .env
echo "Assigned port $PORT for worktree '$RIFT_WORKTREE'"
The formula strips hex letters from the SHA hash, takes the first 4 digits, and maps them into the range 3000–9999.
Custom commands
The hook command doesn’t have to be a bash script — it can be any command your project supports. For example:
hooks:
open: "npm run bootstrap"
jump: "npm run bootstrap"
hooks:
open: "node scripts/setup.js"
jump: "node scripts/setup.js"
The RIFT_WORKTREE environment variable is available in all hook commands.
Multiple ports
If your project runs several services (frontend, API, database), derive multiple ports from the same base:
#!/usr/bin/env bash
set -euo pipefail
hash=$(echo -n "$RIFT_WORKTREE" | shasum | tr -d 'a-f ' | cut -c1-4)
BASE=$(( (hash % 7000) + 3000 ))
cat > .env <<EOF
PORT=$BASE
API_PORT=$(( BASE + 1 ))
DB_PORT=$(( BASE + 2 ))
EOF
echo "Assigned ports $BASE, $(( BASE + 1 )), $(( BASE + 2 )) for worktree '$RIFT_WORKTREE'"
Wiring it up
Add the hook command to your rift.yaml:
hooks:
open: "bash scripts/bootstrap.sh"
jump: "bash scripts/bootstrap.sh"
Running on both open and jump ensures the .env file is always present, even if the worktree was created before the script existed.
.gitignore
The generated .env file is worktree-specific and should not be committed:
# .gitignore
.env
Next steps
See the framework guides for step-by-step examples of reading the assigned port, configuring databases, and wiring up hooks, and the Docker Compose guide for isolating containerized services across worktrees.