2026-04-15
Sesame, an unremarkably good 2FA app
Sesame is out. It’s a 2FA app for iPhone. Free on the App Store, open source under MIT.
I’ve used Authy for years. Since the Twilio acquisition it’s been getting worse, and the latest design refresh was the point I gave up on it. The design is ugly. Search is broken in a specific way—tap a result to copy and search exits, so next time you want that code, you’re starting over. The logos it fetches are wrong or missing half the time. The scanner is slow. The app is slow to open. The account order has never made sense. And the whole thing sits behind a Twilio account, which means your 2FA codes are one SIM swap away from being someone else’s.
I looked at alternatives. None of them gave me what I actually wanted. Some were hard to navigate. Some made weird design choices that got in the way. Most importantly, none of them had a clean way to group accounts into profiles, and I’ve got more than fifty accounts spread across personal stuff, work, and various side projects. Scrolling through them as one flat list is miserable. I wanted to switch profiles and see just the ten accounts that matter in the context I’m in.
It’s the kind of app that’s buildable in a weekend, so I built it.
The shape of what I wanted was pretty small. Local, with codes sitting on my phone and not on someone else’s server. Backups I could reliably put wherever I want. Fast. Alphabetical sort. Profiles. Open source and auditable.
That last one mattered. 2FA sits between you and losing access to everything. I want to be able to read what it does, and I want anyone else who cares to be able to read what it does too. Sesame is MIT licensed, all of it. No dependencies either, so no supply chain risk. There’s even a tiny sesame-decrypt CLI that pulls your codes out of a backup file without Sesame installed, so if I stop shipping updates your data still works.
The most fun part was leaning into iOS. A 2FA app doesn’t need a sexy custom UI. Old me would have built one anyway. New me would rather lean into the platform and simplify everything down.
It also means you get some cool platform features for free, like AutoFill means that for most sites, you never open Sesame at all. The code just appears above the keyboard. Siri too: “Hey Siri, what’s my Discord code in Sesame” puts the code on the clipboard.
Then there’s the Live Activity, which I’m most attached to. Some sites disable pasting into their 2FA fields, so autofill can’t help, and you end up opening Sesame, memorising six digits, flipping back to the site, and typing them in before the code rolls. When you copy a code in Sesame it goes into the Dynamic Island if you’ve got one. It stays there in your peripheral vision until it expires which is nice.
The last 10% took as long as the first 90%. I got the app most of the way there over a single weekend: codes rendering, QR scanner, storage, basic UI. Then my weekday evenings for the next week were spent on the polish. Apple’s own sheets aren’t actually consistent across contexts, so you have to chase them. SwiftUI forms behave weirdly based on the sheet detent size, so you have to chase that too. The things my designer brain notices. Thankfully AI hasn’t fully atrophied my brain just yet.
The other part of the last 10% isn’t the app itself. App Store screenshots, a product video, the website, a privacy policy, all the boring bureaucratic stuff you need to actually ship. I hadn’t done any of it in a while, so it all took me longer than I expected.
One cool nerdy thing that saved me a bunch of time is on the App Store screenshots and product video. I did initially reach for fastlane as I’ve used it in the past, but it’s showing its age. Missing the latest simulators, still needs Ruby, and there’s nothing I hate more than setting up fucking ruby gems. So I had Claude write a small script instead. It spins up Xcode UI tests across the simulators I care about, captures screenshots deterministically, and records product videos following a pre-set choreography, handling codes rolling so the loop seams cleanly. There’s a demo mode gated behind #if DEMO_ENABLED that freezes codes to fixed values so the screenshots stay consistent between runs, and the flag means none of the demo code ships in the release build. Update the UI, run the script, and voila.
I’m having a lot of fun making personal software, even if what I’m making is a bit boring. These simple utilities don’t have to be hard, and it doesn’t take a lot to have nice UX if you just think about it for a bit. I’m not going to replace my banking app any time soon (though I wish I could), but I am making little things for my daily life. Right now I’m playing around with a trailcam app to repurpose an old iPhone so I can watch the crows on my balcony.
Some of these things will never make it on to the App Store, but I’m glad I finished something for once and got Sesame up. If you download it, I’d love to hear what you think.