PR overview
i toggles between the diff and the PR: description, conversation, review threads, checks,
approvals, commits, files. l expands a failing check into its annotations; Enter opens the
offending line in $EDITOR.
brew install candril/tap/riff # or: nix run github:candril/riffriff # review your uncommitted changes
riff takes a target and works out what you meant. A PR number, a revset, a URL, or nothing at all:
riff # uncommitted changes in the working copyriff pr # the PR for the current branch or bookmarkriff 123 # PR #123 in this reporiff HEAD~3 # the last three commitsriff main..feature # a branch comparisonriff @- # a jj revsetriff gh:facebook/react#1234Local and PR mode are the same app. Every motion, every fold, every comment key works in both — PR mode just has GitHub on the other end of it.

j k h l, w b e, f t ; ,, 0 ^ $, gg G, Ctrl+d/Ctrl+u — the motions are the ones your
fingers already know. ]c/[c steps hunks, ]f/[f files, ]u/[u the files you haven’t
looked at yet. za/zo/zc fold a file or a hunk, zR/zM do the lot. Ctrl+o/Ctrl+i walk
a real jumplist, so every jump is undoable.
c opens the comment panel anchored to the cursor’s line; V first if the comment is about a
range. C hands the draft to $EDITOR instead. Comments land in .riff/ in your repo — they
are yours until you decide to publish, so half a review survives a closed terminal.

]r/[r walks every thread in the diff, Enter opens the one under the cursor; ]R/[R skips
the resolved ones. gC is a fuzzy picker over every comment in the PR.
Nothing reaches GitHub until you say so. gS opens the review preview — approve, request changes,
or comment, with every pending comment batched into one review. gs syncs the smaller stuff:
edits to comments you already posted, replies to other people’s threads, resolutions. S posts a
single comment immediately when it can’t wait.

PR overview
i toggles between the diff and the PR: description, conversation, review threads, checks,
approvals, commits, files. l expands a failing check into its annotations; Enter opens the
offending line in $EDITOR.
Commit-by-commit
]g/[g filters the diff down to one commit at a time and wraps back to the full diff — the
way you’d read a stacked PR without checking anything out.
Viewed tracking
v marks a file viewed and jumps to the next unviewed one. In PR mode the state is GitHub’s
own viewed status, so it survives the session and matches the web UI.
Flash jump
s dims the diff and searches what’s on screen as you type; every match gets a one-key
label, and pressing it puts the cursor there. Search and jump in one motion.
Search that behaves
/ and ? search the rendered diff, n/N repeat, */# take the word under the cursor.
Matches highlight in place; Esc clears them.
Action menu
Ctrl+p lists every action available in the current state with its shortcut — the same list
the docs are generated from. Nothing has to be memorised.
Drop into your editor
gf opens the current file at the cursor’s line in $EDITOR, gF in a new tmux window with
riff still running, gc checks out the PR branch first.
Links people can follow
gY copies a GitHub permalink for the selection, the line, or the file, pinned to the branch.
gy copies the PR URL, y in the comments panel copies a link to that thread.
Claude Code, scoped
Chat about the selection, a file, a folder, a multi-select, or the whole diff. A comment
Claude drafts shows up as a notification you copy with gd or dismiss with gD — riff never
posts it for you.
Quiet background sync
New replies arrive on a poll that costs one GraphQL point per tick, skipped while the terminal is unfocused and refreshed when you come back to it.
Noise stays hidden
Lock files, generated code and snapshots are folded out of the review by default, and the pattern list is yours to redefine.
git or jj
Both are first-class. Revsets, bookmarks, @- — riff asks whichever tool the repo actually
uses.

brew install candril/tap/riff # or: nix run github:candril/riffcurl -fsSL https://raw.githubusercontent.com/candril/riff/main/scripts/install.sh | bashSee the installation guide for the Nix flake, the installer’s variables, requirements and first run.