Extensible Software in the age of LLMs

Most software products are built for the top of a demand curve, where a limited set of features serves the largest group of users, while a long tail of individual needs is left unaddressed because supporting it does not scale in the traditional sense Most software products are built for the top of a demand curve, where a limited set of features serves the largest group of users, while a long tail of individual needs is left unaddressed because supporting it does not scale in the traditional sense (and attempting to do so often leads to scope creep)..

Jeremy Morrell argues that large language models change this calculation, since they lower the cost of authoring an extension to the point where serving a single user’s edge case becomes economically viable, provided the surrounding platform can deploy and secure that extension safely.

The interesting part of the argument is not that LLMs can generate code, which is now a familiar claim, but that the harder problem has always been the deployment and trust boundary around that code, not its authorship. Webhooks require the user to operate a separate service and handle delivery failures themselves, and most local extension models, such as IDE plugins or Obsidian’s ecosystem, ask the user to trust every author whose extension they install, which is a workable tradeoff for a notes app but not for a system holding financial transactions or private messages. Salesforce solved a version of this problem two decades ago by building its own compiler, runtime, and standard library so that customer logic could run safely inside a shared multi-tenant platform, well before serverless made that pattern common.

What makes the current moment diffferent is that the primitives Salesforce had to build from scratch now exist off the shelf, whether as V8 isolates, WebAssembly with WASI, or microVMs, and each comes with a different tradeoff between cold start latency, isolation strength, and language flexibility. Morrell’s argument for an object capability model over a traditional API proxy is worth sitting with regardless of which runtime a team chooses, since restricting untrusted code to explicit, narrow references such as getApprovedEmail() rather than a scoped API token removes an entire category of exfiltration risk by construction, instead of relying on a proxy layer to catch every malicious pattern after the fact.

For teams building internal tooling or customer facing platforms, the practical takeaway is that extensibility is no longer purely a UX or roadmap decision, it is also an infrastructure decision, and the primitive chosen early on will determine how much custom logic a platform can safely absorb once users start asking an LLM to write it for them.

https://jeremymorrell.dev/blog/extensible-software-in-the-age-of-llms/

A Reality Check on Rewriting in Rust

JetBrains published a guest post by the cot.rs maintainers reviewing what actually happened when open source and commercial teams rewrote existing software in Rust, rather than relying on the hype. The findings are more nuanced than the “rewrite it in Rust” slogan suggests, since some performance gains come from Rust specific advantages such as auto vectorization or a concurrency model that makes correct parallel merge sort easier to implement, while other gains come simply from a team rewriting a project from scratch with decades of hindsight and no legacy production constraints. Separating those two causes matters, because a team that attributes a speedup to the language alone may be signing up for a multi year rewrite when a more modest refactor in the existing codebase would have delivered most of the same benefit. (btw, I have ranted here how hard it is to switch to a Rust style of programming)

The failures documented in the post are just as instructive as the wins. Cloudflare shipped an unwrap that took down a request scoring component, sudo-rs echoed a partially typed password back to the terminal after a timeout, and the first CVE in the kernel’s Rust code came from a race condition inside an unsafe block, which is a reminder that memory safety guarantees hold only within the boundaries a team actually enforces. Prisma abandoned its Rust query engine due to skill set gaps and deployment complexity, and Loglog Games left Rust after three years because the language rewarded refactoring more than the fast iteration a game studio needed; both cases show that a rewrite can be technically sound and still fail the organization that undertook it.

This same discipline shows up in Raphael Bauer’s older but still circulating argument for defaulting to PostgreSQL over a specialized database, message queue, or search engine for as long as the workload allows it. The underlying principle in both pieces is the same, even though the technologies are unrelated: reducing the number of moving parts in a system, or the number of languages and services a team must operate, tends to matter more for long term velocity than the theoretical ceiling of any single component. Rust’s own authors reach the same conclusion from the opposite direction, recommending incremental expansion into a codebase rather than a full rewrite, since the projects that succeeded at large scale, such as the Linux kernel and Windows, expanded gradually and kept the surrounding system running throughout.

The broader point for engineering leadership is that technology selection benefits from being evaluated against the operational cost of running it, not against the best case demo of a new tool, and that a decision made for good reasons in 2015 deserves the same scrutiny when reapplied to a system in 2026.

Sources:

  1. https://blog.jetbrains.com/rust/2026/08/10/rewriting-in-rust/
  2. https://www.raphaelbauer.com/posts/postgresql-everything/

Learn to Code

I am using ChatGPT since dec/22 and I showed to my son in that same month, I can say the boy turned into a llm master. Fast forward to aug/25, he asked if he should learn Python during his gap year and I said “for sure!” with all the enthusiasm to see your son doing smth you love 🙂 but …I know there is a growing assumption in technical circles that learning to code has lost its purpose, now that language models can generate working software from a short prompt, like my kid could do in a blink.

I stand by my suggestion and I read an article I loved about this clash of opinions. The argument treats coding the way we already treat mathematics or literature, as a discipline worth learning for what it teaches regardless of direct vocational payoff. The skills gained through the learning process extend well beyond syntax. Debugging teaches a structured way of isolating the source of a problem; composition teaches how small, well defined pieces combine into something larger; and the discipline of unambiguous instruction transfers to almost any field that requires clear thinking. These are meta-skills, in the sense that they remain useful long after any specific language or framework becomes obsolete. And with the added bonus of knowing to program 🙂

I could not have said better!

https://stevekrouse.com/learn-to-code

An oral history of Bank Python

𝘉𝘢𝘤𝘬 𝘵𝘰 𝘉𝘢𝘴𝘪𝘤𝘴: go read Cal Paterson’s “An oral history of Bank Python”. It describes a class of software systems that run inside large investment banks, and it is a instructive case study on software architecture. You will probable start reading and thinking “wow, this does not seem right”. Until you realize the constraints that produced them.

Every system runs on limits, whether you name them or not, what’s allowed to change independently, what has to stay coupled, what the system will simply refuse to do, what trade-off you’re accepting today so you don’t have to relitigate it tomorrow. Good architecture isn’t the absence of constraints. It’s choosing the right ones, early, on purpose.

https://calpaterson.com/bank-python.html