Create a Stack
This tutorial shows how to create a stack of commits, each becoming its own PR that builds on the previous one.
Why Stack?
Stacking lets you:
- Break large features into reviewable chunks
- Get early feedback on foundational changes
- Merge PRs incrementally as they’re approved
- Keep your PRs small and focused
Prerequisites
- LazyJJ installed
- GitHub CLI (
gh) installed and authenticated - A Git repository with a GitHub remote
Step 1: Start from Trunk
Begin with a fresh start from the latest trunk:
jj stack-startStep 2: First Commit
Make your first set of changes - typically the foundation that later work builds on:
# Make your changesvim src/database/schema.sqlvim src/database/migrations/001_users.sql
# Describe the commitjj describe -m "Add user database schema"
# Create a bookmark for this PRjj bookmark-create db-schema
# Start the next commitjj newNotice: No
git addneeded! In JJ, changes are automatically part of the commit. This feels strange initially but becomes natural. See Mental Model for why this works.
Step 3: Second Commit
Build on the first commit:
# Make changes that depend on the schemavim src/models/user.jsvim src/models/user.test.js
# Describe itjj describe -m "Add user model"
# Create a bookmarkjj bookmark-create user-model
# Start the next commitjj newStep 4: Third Commit
Continue the stack:
# Make changes that use the modelvim src/api/users.jsvim src/api/users.test.js
# Describe itjj describe -m "Add user API endpoints"
# Create a bookmarkjj bookmark-create user-apiStep 5: View Your Stack
See the full stack:
jj stack-viewOutput shows the relationship:
@ xyz user-api "Add user API endpoints"○ abc user-model "Add user model"○ def db-schema "Add user database schema"○ trunkStep 6: Push All PRs
Create PRs for the entire stack at once:
jj pr-stack-createThis creates three PRs:
db-schema- base PR targetingmainuser-model- PR targetingdb-schemauser-api- PR targetinguser-model
Complete Example
Here’s the full workflow:
# Start freshjj stack-start
# First commit - database schemavim src/database/schema.sqljj describe -m "Add user database schema"jj bookmark-create db-schemajj new
# Second commit - model layervim src/models/user.jsjj describe -m "Add user model"jj bookmark-create user-modeljj new
# Third commit - API layervim src/api/users.jsjj describe -m "Add user API endpoints"jj bookmark-create user-api
# View the stackjj stack-view
# Push everythingjj pr-stack-createViewing Stack with File Changes
To see which files each commit touches:
jj stack-filesTips
Naming Bookmarks
Use descriptive names that indicate the order or relationship:
jj bookmark-create feature/01-schemajj bookmark-create feature/02-modeljj bookmark-create feature/03-apiDon’t Forget jj new
After describing a commit, run jj new before starting the next set of changes. Otherwise, you’ll keep modifying the same commit.
This is a common mistake—see Common Mistakes for details.
What if I Forgot jj new?
If you accidentally kept editing the same commit:
# Split the commitjj split# Choose what belongs in first commit# Rest becomes a new commitView All Your Stacks
If you have multiple features in progress:
jj stacks-allAfter a PR Merges
When a PR in your stack gets merged:
# Sync with trunk - this rebases your remaining stackjj stack-sync
# Push the updated stackjj stack-submitJJ automatically rebases your remaining commits onto the new trunk.
Next Steps
- Learn to Navigate Your Stack
- See how to Edit Mid-Stack Commits
- Learn about Syncing with Remote
Ernesto Jiménez