Ravio OTP app goes rogue, Ladybird spreads its wings, moving beyond type systems, getting over GraphQL & more

Changelog News

Developer news worth your attention

Jerod here! 👋

I poked fun at Adam on our “You have how many open tabs?!” episode awhile back. Never again. We now have cold, hard evidence of a Firefox user who kept 7400 tabs open for 2+ years 🤯

Ok, let’s get into the news.


Quick correction from last week: the article I covered about clear, readable code was written by Leonardo Creed, not Jordan Cutler. Sorry about that, Leonardo!


🎧 This week in Developer Pods

🎙️ Microsoft’s legendary EVP, Scott Guthrie changelog.fm/593
💚 Our favorite tech lawyer, Luis Villa changelog.com/friends/46
🪩 Zach Leatherman takes 11ty fully independent jsparty.fm/325
🚀 Danielle Lancashire: Is Wasm the new Java? shipit.show/106
🤖 Rep. Don Beyer on AI in the U.S. Congress practicalai.fm/271
⏰ Your ultimate guide to mastering Go gotime.fm/317

😳 Raivo OTP quietly changes hands, loses passwords

In yet-another-unsettling-open-source-sustainability-failure news…

Ravio, a popular open source iOS authenticator app that syncs your one-time-passwords across devices, was quietly transferred from its original creator to a company called Mobime. After ~10 months of zero public commits, the new owners shipped an update that deleted people’s 2FA codes and, according to one angry user review:

It’s ransomware. Unless they pay, their 2fa codes are gone. Some users have had their codes gone forever.

I was tipped off to this ordeal late last week by friend-of-the-log rderik, a previously happy user of Ravio, who said:

This is a super critical app, I mean it holds your OTP, it doesn’t get as critical as that… This is an example of how not to do open source management 😞

Since then, Mobime’s developers have removed the issue tracker from the GitHub repo and closed all open PRs, including one that would inform users about the data loss and paywall.

Say it with me: Rug pull, not cool!

🦅 Ladybird spreads its wings, targets Linux & macOS

Andreas Kling, creator of SerenityOS & its Ladybird browser, is forking Ladybird and stepping down as SerenityOS BDFL:

Until now, the project and its community have existed in a state with two groups sharing all resources and infrastructure:

  • One group who mostly cares about building a desktop OS.
  • Another group who mostly cares about building a cross-platform web browser.

In the past, there was enough overlap between interests that it made sense to share everything, but these interests have slowly grown apart.

I’ve decided it’s time to make a big change. To streamline development of Ladybird, I’m forking it off from SerenityOS into a new, separate top-level project.

This change, while difficult & surely emotional for Andreas, seems like a healthy one for both projects. Ladybird gets to spread its wings and fly on more mainstream operating systems (Linux, macOS) & Serenity is now community-driven, no longer distracted with a web browser effort & “hacking on fun software with friends” is once again the main focus.

🧑‍🚀 Moving beyond type systems

A thought-provoking look at what a “static effect system” is, what it might look like & how it could be beneficial to programming languages moving forward.

To this day we’re pretty used to either having all side effects under our control or having no side effects. What if we could strike a balance?

Vhyrro goes on to explain how Rust has already made a move in this direction, but we don’t think of it in explicit terms as a static effect system. What even is a static effect system though?

A static effect system would be something akin to Rust’s borrow checker but for effects — instead of being able to interact and handle effects through functions, the programming language instead has an effect checker that statically analyzes the program and makes sure that everything holds. This would mean making sure that all effects are annotated properly and that no side effects occur where they shouldn’t.

The remainder of the post focuses on implementing a static effect system. Food for thought! Vhyrro finishes with:

I haven’t been able to find any obvious pitfalls with the idea though, hence I shared it on this blog. Hope I caught your attention! I encourage all theorists to play around with the idea.

🦾 AI for incident management is here

Thanks to FireHydrant for sponsoring Changelog News 💰

Robert Ross:

Over the last five years we’ve seen our customers run 583,954 incidents more efficiently thanks to a shared workspace, powerful Runbook automations, and auto-captured data. Yet despite a great deal of progress, incident efficiency hasn’t achieved peak potential. We talk to a lot of folks that are still stuck in the muck: new responders struggle to get up to speed quickly, incident commanders wade through post-incident drudgery, and knowledge silos prevent comprehensive improvements. But there’s a way for all of us to feel like we’re running incidents with a cheat code: AI.

There’s no shortage of things you can sprinkle AI into, but Robert and his team at FireHydrant took a thoughtful approach and explicitly chose features that “would meaningfully improve the responder experience and had the potential to shave hours of work off every incident.”

The best part: All FireHydrant accounts have immediate access to the new AI functionality. Click here to find out exactly what they’re up to.

👎 Why, after 6 years, I’m over GraphQL

Matt Bessey:

GraphQL is an incredible piece of technology that has captured a lot of mindshare since I first started slinging it in production in 2018. You won’t have to look far back on this (rather inactive) blog to see I have previously championed this technology. After building many a React SPA on top of a hodge podge of untyped JSON REST APIs, I found GraphQL a breath of fresh air. I was truly a GraphQL hype train member.

However, as the years have gone on and I have had the opportunity to deploy to environments where non functional requirements like security, performance, and maintainability were more of a concern, my perspective has changed. In this article I would like to take you through why today, I would not recommend GraphQL to most people, and what I think are better alternatives.

Matt goes on to provide a long list of issues he has with GraphQL, in excellent detail. Of those, this is the one that’s most concerning to me:

In my experience, in a mature GraphQL codebase, your business logic is forced into the transport layer.

Yo! Keep your business logic out of my transport layer, thank you very much. It may be a trade-off that works for Facebook, but you & I are (most likely) not Facebook or Google/Amazon/LinkedIn

👍 Why, after 8 years, I still like GraphQL sometimes in the right context

Matt’s post was a conversation starter! Marc-Andre Giroux responded with his own opinion after also using GraphQL for a long time. His major point is one I don’t see discussed often: Use persisted queries:

Persisted Queries are basically essential for building a solid GraphQL API. If you are not using them, you’re doing GraphQL on hard mode. It’s not impossible, but it leads to difficult problems, some of them discussed in the post. After 8 years of GraphQL, this has only gotten more and more important to me. Persist all queries, as soon as possible in your GraphQL journey. You’ll thank yourself later.

The problem with persisted queries is that they aren’t an option for public APIs, but it sounds like most people are using GraphQL for non-public APIs anyhow…

I can feel the pain of the author when it comes to building public GraphQL APIs. It’s not easy. But the post in general never really addresses a very common use-case for GraphQL, which is an internal API for known multiple clients. In this context, using persisted queries is easy, and solves a lot of the problems the author encountered in their journey…

After 8 years of GraphQL, I still enjoy the decoupling a GraphQL schema offers between server-side capabilities and client-side requirements, but am aware of the trade-offs when picking it as a technology.

So where we’re ending up is… It Depends? 🤓


📝 How (some) good corporate engineering blogs are written

Dan Luu points out that his personal blog often gets more traffic than many corporate blogs that have more staff, resources, etc.

Despite the seemingly obvious benefits of having a “good” corp eng blog, most corp eng blogs are full of stuff engineers don’t want to read. Vague, high-level fluff about how amazing everything is, content marketing, handwave-y posts about the new hotness (today, that might be using deep learning for inappropriate applications; ten years ago, that might have been using “big data” for inappropriate applications), etc.

To try to understand what companies with good corporate engineering blog have in common, I interviewed folks at three different companies that have compelling corporate engineering blogs (Cloudflare, Heap, and Segment) as well as folks at three different companies that have lame corporate engineering blogs (which I’m not going to name).

If you run (or write for) a corporate blog, this is worth reading.

🥶 How to minimize user frustration in Antarctica

The author of this blog spent 14 months at the South Pole and wrote up the many challenges faced with internet access while working in Antarctica:

Downloads are possible at the South Pole, but they are subject to unique constraints. The biggest constraint is the lack of 24x7 Internet. While I was there, I knew we would lose Internet access at a certain time!

It’s a frustrating reality: with most apps that do their own downloads, we were powerless to do anything about this known break in connectivity. We just had to sit there and watch it fail, and often watch all our progress be lost.

The big takeaway for those of us who will probably never visit the South Pole (but might write software for folks who do):

I hope the examples I’ve shown in this post have been a helpful illustration of how minor oversights or under-developed features back home can become major issues in a place with slow Internet.

🔐 What is Tailscale SSH?

Thanks to Tailscale for sponsoring Changelog News 💰

With Tailscale SSH, you can:

  • SSH as normal, using Tailscale for authentication. With Tailscale SSH, Tailscale takes over port 22 for SSH connections incoming from the Tailscale network. Tailscale will authenticate and encrypt the connection over WireGuard, using Tailscale node keys. The SSH client and server will still create an encrypted SSH connection, but it will not be further authenticated.
  • Verify high-risk connections with check mode. Optionally require certain connections, or connections as certain users (for example, root), to re-authenticate before connecting. This allows the user to access these high-risk applications for the next 12 hours or for a specified check period before re-authenticating again.

Your SSH config (/etc/ssh/sshd_config) and keys (~/.ssh/authorized_keys) files will not be modified, which means that other SSH connections to the same host, not made over Tailscale, will still work.

Pretty cool, huh? Learn more

🤬 Why software engineers are always grumpy

Mahesh Balakrishnan lays out the three laws of software complexity:

  1. A well-designed system will degrade into a badly designed system over time
  2. Complexity is a Moat (filled by Leaky Abstractions)
  3. There is no fundamental upper limit on Software Complexity

Co-signed by this sometimes grumpy engineer…

🗯️ Quote of the week

I leave you with Gall’s Law, which correlates highly to Mahesh’s first law of software complexity:

A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.


That’s the news for now, but we have some great episodes coming up this week: Mark Russinovich, Eric Boyd & Neha Batra on Wednesday & we’re once again playing the award-worthy #define game show on Friday.

Have a great week, forward this to a friend who might dig it & I’ll talk to you again real soon. 💚

–Jerod