A little while ago I got one of those emails. You know the one. "Your annual subscription renews in 7 days." It was for the diff and merge tool I'd been leaning on for years, the app I open a dozen times a day to eyeball a blueprint change, sanity-check a Twig template, or work through a merge conflict on a plugin.
I'd bought that tool once, years back. Then the pricing turned into a yearly thing, and every summer it quietly renewed and took another chunk of money for an app that, if I'm honest, hadn't gained a single feature I actually wanted in all that time. I was paying rent on software I already knew inside out.
So I did what any reasonable person does at 11pm. I closed the email, opened Xcode, and started building my own. That app is Riffle.
The renewal that broke me
The tool I was using was fine, to be fair. It did 2-way diffs, it did merges, it looked nice. But "fine" is a strange thing to pay for on a loop, forever, especially when I'd started keeping a running list of the things it didn't do.
I review a lot of code. Between Grav core, the Admin2 plugin, the API plugin, and a pile of themes and skeletons, I spend a good part of my week reading diffs and stepping through pull requests. And the tool I was renting couldn't review a pull request at all. It couldn't look at a whole branch. It couldn't open a GitHub PR, let me walk the files, and leave a review. For that I was bouncing between the terminal, the browser, and the diff app, three windows to do one job.
That was the itch I couldn't stop scratching.
What I actually wanted
Before I wrote a line of code, I made a list. Same as I do for anything. Here's what I wanted from a diff and merge tool in 2026:
- Native and fast. A real Mac app, not a web page wearing a title bar.
- One price. Pay once, own it, done. No annual renewal email, ever.
- A proper 3-way merge I could actually edit, line by line, not just "pick the left side or the right side."
- Folder comparison that walks two trees and drills straight to the file that changed.
- Real git, Tower, and command-line integration, the kind that just slots into how I already work.
- The big one: codiff-style GitHub pull request review, right on my Mac.
- Theming that matched the editor I stare at all day, so the whole thing didn't feel like a foreign app.
Plenty of tools did some of that. Nothing did all of it. So, option #2 was the only option left to me. I started building.

What Riffle does now
Months of nights and weekends later, here's where it landed.
Diffing, the part you do all day
The everyday stuff had to be excellent, because it's what you touch most. Riffle does clean 2-way file diffs with three view modes: blocks, fluid, and unified. Word-level highlighting shows exactly what moved inside a line, not just which lines changed, and similarity-based hunk pairing keeps the two sides lined up even when things shift around.
Then all the little things that add up: show invisibles when whitespace matters, flip on soft wrap for long lines, swap A and B with a keypress, set your own pane fonts, and keep several comparisons open in tabs with ⌘1 through ⌘9.

Merging without losing your mind
A real 3-way merge was non-negotiable. In Riffle you step through each conflict, select the exact lines you want, and apply them with Use or Add chips. Everything lands on a single unified undo stack, so one ⌘Z walks back through every edit no matter which pane it came from. Auto-merge handles the safe regions for you, and every auto-merged region stays reviewable, so nothing sneaks into the result without you seeing it.

The middle column is the real thing, and it's editable. You're not picking a winner between two files, you're building the merged result, with every conflict called out and stepped through until there's nothing left flagged.
Reviewing a pull request without leaving the Mac
This is the feature I built the whole app to get to. Point Riffle at a repository and it reviews the whole changeset in one window: a file list down the side, an inline diff on the right, code-review style. It works on your working tree, the staged index, a branch, a single commit, or a GitHub pull request:
riffle review pr 132
That fetches the PR through the gh CLI and drops you into a proper review. You get the Conversation first, the PR description and every comment and review rendered right there, then you step through the files one by one. Hover a changed line and leave an inline comment. When you're done, hit Comment, Approve, or Request Changes, and Riffle posts the review straight back to GitHub. No browser tab, no context switch. Review a plugin PR, approve it, move on.

That screenshot is an actual Grav core pull request (#4056), reviewed start to finish inside Riffle. This is the part I missed most in every other tool, and now it's the part I use every day.
Even the images
I threw image diff in because I kept needing it and nothing good existed for a quick "did this asset actually change?" check. Compare two images two-up, by difference, with an onion skin, or with a split slider. Pan and zoom stay synced across both, and Riffle gives you a straight pixel-identical verdict at the bottom.

Themes that match your setup
Because I couldn't help myself, theming got a little out of hand, in the best way. Riffle follows your Mac's light and dark appearance out of the box, and it ships 62 bundled themes on top of that. It also reads VS Code and TextMate theme JSON directly, so you can bring the exact theme you already use in your editor. And the theming covers the whole window chrome, not just the code panes, so the entire app matches instead of being a dark editor bolted into a grey macOS frame.

Dark all day, light when the sun's out, or a specific theme pinned for each. It's your call, and the whole app comes along for the ride.
Why this matters if you build with Grav
Everything above is general-purpose, but a lot of it came directly from doing Grav work every day:
- Blueprint and config YAML diffs, where a single wrong indent matters and word-level highlighting catches it.
- Twig template merges when you're pulling upstream changes into a customized theme.
- Comparing a fresh skeleton against your customized copy of it, folder against folder, to see what drifted.
- Reviewing a contributor's pull request to a Grav plugin,
riffle review prpointed straight at agetgravrepo, approving it without ever opening the browser. - Stepping through a merge on a
.mdpage where the frontmatter and the content both changed.
It's the tool I wanted for the work I actually do, which turns out to be the only kind of tool worth building.
One price, no subscription
Here's the part that started the whole thing, so I made sure I got it right.
Riffle is a 14-day full-feature trial from first launch, no credit card up front. When the trial ends, unlimited 2-way file diff stays free forever. The 3-way merge, folder comparison, and git review live behind a one-time $29.99 license that covers 3 Macs with unlimited validations. Pay once. That's it. No renewal email next summer.
It's a direct download, a Developer ID-signed and notarized DMG with Sparkle auto-updates, or you can grab it with Homebrew:
brew install --cask skulkworks/tap/riffle
Riffle is a native, universal Swift app, so it runs on both Apple silicon and Intel Macs, and it needs macOS 14 (Sonoma) or later.
Get it
You can download Riffle right now at skulkworks.dev/riffle, or install the Homebrew cask above. Start the trial, throw a messy merge at it, review a real pull request with it, and see if it earns a spot in your dock.
If you've got questions, ideas, or you just want to tell me what your diff tool still can't do, come find me in the SkulkWorks Discord at discord.com/invite/vUShQGeUPC. It started as a scratch for my own itch, and the best features so far came from people telling me what annoyed them.
Enjoy!
Andy