This essay has been published as part of the The Pragmatic Engineer’s “How software engineering is changing: an essay challenge”. 5500 words, all human written.
I’ll walk you through our journey to automated PR reviews, plus what I call agentic pair-engineering, and how AI helped my drive a promotion. I hope you enjoy!
When I joined
Framer in February 2024, one of my first questions on Slack was about which “AI extension” people recommend here and Framer’s CEO, Koen Bok, back then replied that he’d recommend Cursor + GPT 4 in chat. Recommending Cursor in February 2024 was early if you consider Cursor’s growth curve (in August 2024 their Series A valuation was $0.4B). With this in mind, I would define Framer as early adopters and early riders of the agent wave, maybe not the very cutting edge, but close. Framer’s leadership encourages experimenting with new technology, and many of my colleagues also love playing with cutting-edge tech. For me, it feels like playing with new toys. Just as an adult.
In 2025, Framer’s leadership decided to stop hiring, to focus on getting really productive with AI (doubling the number of PRs, without decreasing quality in any way). The result we had seen was more complex PRs, but at the cost of a higher turnaround time, so we unfroze the hiring again after three months. The big learnings here for us were:
- Writing code became faster and cheaper, reviewing it did not.
- More AI doesn’t mean fewer engineers needed.
How PR reviews are treated also seems like an interesting difference between “very top of the wave” (companies like Anthropic, OpenAI, SpaceXSI) and “close to the top” companies (where I categorize Framer). In the very top of the wave companies, it appears like they use agents to write close to a hundred percent of their code. From talking to engineers at those labs, it also seems like they heavily use agents to review code, which feels like the largest gap between those two categories.
In the following, I’ll walk through AI-related tools we use, talk about personal highlights and how we spread various forms of agents. Finally, I’ll go over the struggles and discussions we’ve had about agent-written code internally, which differentiates “close to the top” companies from the frontier ones the most - for the better or worse.
Table of contents
AI at Framer
Framer’s leadership never mandated the use of AI, there were some nudges, but we thankfully never had token leaderboards that mattered for promotions or performance ratings. The strategy we’ve used was showing engineers workflows that made individuals more efficient. In the beginning, we had a weekly meeting where everyone could show something cool they do with AI, present skills or just start discussions. I think this helped raise the awareness of what agents can and cannot do.
Engineers at Framer are free to pick their agent of choice: Claude Code, Codex, Cursor, Devin (Desktop) are the most common ones. Some also use these in Zed or WebStorm. For backend folks, the CLI variants of those seem a little more widespread than the desktop versions. Most of the code I touch is written in TypeScript, with React as framework. Overall, this feels like we’re still in the days where there is no single workflow that fits everyone. Which is not necessarily a bad thing. After all, in the past, devs picked their IDE of choice, so maybe standardizing how engineers work is not something you want to strive for?
For us, writing and reviewing code by relying a hundred percent on agents is not the default and we’re in a phase where it’s not entirely clear how to treat PRs with “100% agent generated code”, what to make out of agent generated artifacts (markdown/HTML/conversations) and how to increase review efficiency. At the same time, the amount of agent generated code that makes it to the main branch grows every day. What is much more established, are various forms of agents that “support” daily engineering work (and do so even outside of engineering):
- Agent PR reviews: They can be annoying and incredibly helpful at once, but especially PR auto-approvals are great time savers and change how PRs are approached
- Slack-driven agents, like Devin: They took a while to “take off”, but eventually it reached basically every channel; from customer support, to legal.
More on that, next.
Agent PR reviews
In January 2025, Framer’s CTO Eelco Lempsink introduced Factory.ai as a code review bot. For the first time, I could request an LLM-driven review for PRs. Initially those weren’t great, because LLM responses often hallucinated scenarios or even falsely explained things. Much of 2025 felt like this. Often you had to read through “slop” (but you did not know initially) and had to spend time chasing ghosts. Digging through them felt close to hell, GitHub’s Copilot also had this issue.
Today, we rely on Devin Review and Codex. Over the months, we’ve come to the conclusion that both of these hit the sweet spot in the noise-to-actual-error-ratio, and we’ve found that often one finds what the other does not.
Automated PR approvals
In March 2026, my timeline had shown me the following - an agent approving a PR:
We've moved our entire code review lifecycle onto Automations. Cursor will approve and unblock changes that are low risk and automatically assign reviewers based on commit history for changes that are medium/high risk. There is so much power in transforming historically static Show more
We're introducing Cursor Automations to build always-on agents.
This made me realize there is a difference in how “top of the wave”-companies work. Nowadays, more and more companies have agentic auto-approvals, but back in March this felt mindblowing. So mindblowing, I had to convince Eelco to allow me to set it up. He in turn had to convince legal / auditors - welcome to Europe.
Once legal stuff was cleared, we started with the template the Cursor team provided and customized it to our needs. The template has examples of what it should approve and what it should not, but these don’t fit every codebase. Over weeks, I’ve prompt-engineered it to fit our codebase and our needs. Later on, Eelco and I mostly rewrote the “scoring” system and introduced a concept like “Slack approval” that ensures human involvement for changes the agent isn’t sure about (see my article). The automation now classifies by impact and complexity.
Worth noting what it currently doesn’t do: It doesn’t factor in reviews from Codex or Devin. I’ve heard some companies block on those, so that not just the diff and PR description decide the outcome, but also wait if reviewers that look for bugs (or other things) clear the PR, before approving. The downside I see with this is, PRs might get blocked for wrong flags (e.g. hallucinated bugs or similar), which makes it incredibly annoying and no longer a time saver. I expect this to be solved by one of the future model generations.
Approaching PRs with auto-approvals in mind
A great shift I’ve seen happen after the introduction of agent-driven auto-approvals, is that engineers mindfully started splitting PRs into chunks that get auto-approved. This may sound trivial (after all humans also want to have PRs that are easy to review), but there is a small difference: A diff can be huge - visually - while it in reality hasn’t changed much. Most of us still review in GitHub’s review UI, where moved, but slightly changed code, often looks like you deleted 200 and added 200 lines. An agent on the other hand doesn’t care how it looks visually, it can easily understand that just some minor things have changed. At the same time, this also makes engineers actively think about “what could I land first to make it easier to review for the next human?”.
My colleague Pablo Caballero phrased it like this when I asked for feedback on the auto-approval system:

It seems like auto-approval makes another great argument for keeping PRs small, because these more often get auto-approved.
This mechanism takes time and mental effort away from humans (not just you, but also from peers). Personally, I find looking at refactor PRs where you have to manually puzzle together what changed (by pasting the diff into another diff tool) incredibly annoying and not fun. Now I no longer have to look at those, and don’t have to put the burden onto my colleagues.
Instead, I just tell my agent to split my change into smaller PRs, where some get auto-approved and the rest reviewed by humans. When we introduced this, it felt like science fiction, especially because the approvals in 99.9% of cases felt correct (we’ve looked at some of the PRs, again for auditing reasons, to make sure it’s really hard to sneak in malicious or overly complex changes and similar). In the small percentage of PRs where we’ve disagreed with the auto-approval, our reasoning was more along the lines that the result of the PR could be achieved with much less code.
Some stats: In the past 30 days (September 2026), in one of our repos, ~20% of PRs were auto-approved by our automation and is going up rapidly (approaching 50% EOY as we keep refining the approval guidelines). Cost was ~$1 per run (runs on PR open and on push).
Slack Agents
Once more back to 2025, next to PR reviews, we’ve also been following agents you can tag in Slack. My colleague Ivan Akulov and I set out to compare agents to find one that fits us. The idea was maybe we could give designers a way to prototype changes that require code changes and then let engineers pick up where the designer stopped. Devin was one of those candidates.
What made it stand out, was Devin’s visual computer tab that felt pretty unique back then:

Framer’s main product is the UI where agents and humans build websites in a visual editor, so interacting with the UI needed some kind of visual interface. As engineers, we then set up Devin to “just work” like we want it to and then let people do their thing.
Chat as low-entry barrier
As mentioned earlier, by now basically everyone uses Devin internally. I think the reason is how easy it feels compared to other ways to interact with agents. Non-devs look at CLIs and think “this is some hacker sh*t” (actual quote). Starting and learning a new program (like Codex desktop) is pretty easy, but also something you have to actively chase (or be nudged into).
In comparison, tagging Devin from within a thread is trivial, it’s a much lower entry barrier. You can also do it, zoom out, and re-visit it later. “On-boarding” people is also much easier: I often tell them “try @-devin”, that’s it. People don’t have to download anything first. Not only that, you can start a thread and then just hand the thread and its results over. This way you can prototype first, then hand it to the person that knows how to drive it to production.
An example that personally makes me proud is, my colleague Hannah Bos from our legal department, who has never touched any code in her life, used Devin to prototype a meaningful feature some of our larger enterprise customers kept requesting every now and then. It wasn’t many that did, so it wasn’t a high priority for the engineering department, but it’s something that landed on her desk from time to time. While at a company offsite breakfast chat, I casually suggested she try any of our coding agents if no one else had time for it. She did, and later on turning her prototype into a real feature was just a matter of hours. The lesson here is, if you don’t come with empty hands (not just a feature request), you can convince people much more easily, because it also means less time investment from the other side needed to ship (if you’re curious, she wrote about it here).
To me this chat-based handover is currently one of the better approaches to preserve “context” between humans working with agents, because you can always read through the thread to understand how or why Devin wrote the code. In contrast, chats in the various agent apps/CLIs get lost, unless someone decides to share them on purpose.
When talking to engineers outside of Framer, I’ve heard the same: Not many people are willing to share their chats due to various reasons.
On Slack, threads are usually started in public, so seeing the chat history feels natural and not like laying bare. Maybe because the entry-barrier is lower and the conversation feels more like a real conversation (e.g. it’s not uncommon to read “devin what are you doing”), you mind less if others read it?
Last but not least, a major advantage I see is prototypes and context don’t just vanish. A prototype PR or branch may get forgotten eventually, but a thread about a certain topic may be re-discovered via Slack search (when spot-looking for keywords). Because cloud agents preserve code and state outside of your laptop, you or colleagues can pick it up again from any device, which again makes it a low-entry barrier.
Agent-in-the-middle
The next aspect that makes it successful, is having Devin as “chat in-the-middle”. This can be between engineers that vibechat a prototype together, or between different departments like engineering and customer support. Customer support may ask Devin first “why broken”, Devin may respond, and then engineers either correct Devin if it was wrong (and it then learns by updating its memories), or let it make a PR. For bugs, this is especially nice, because Devin can tell the support person a workaround, while the engineer works on a bug fix. All in one thread.
As an engineer, I also find it interesting to read Devin threads others have started - not just because of a topic I might be interested in reading the agent’s responses, but more so seeing how more experienced people interact with the agent. This is much like pair-programming, but instead of needing to synchronously hop on a call to shadow a more experienced person, you can follow the steps asynchronously (e.g. as a person navigates Devin through a codebase or through the architecture in systems you haven’t touched before). The async nature of Slack also brings the advantage that you can easily take over a thread, either while your colleague is busy or to take over and drive it to production.
Finally, the other major advantage is you can very easily tell what has been thought about and what hasn’t, which later makes it easier to review the PR because you don’t have to re-check what the PR author has (not) thought about.
Healthy skepticism
In the initial months of onboarding, I’ve observed people learnt to be “optimistically cautious”: You don’t want to ‘fact-check’ everything Devin codes or responds, but you also don’t want to blindly trust everything. In other words: You - as a human - still need (and are expected to) invoke brain.exe. Similarly, in the first months of using Devin, it seemed “ok” to review a PR that was a bit lower in quality than humanly written PRs. After all, it was obvious the code was agent generated and thus may not meet the bar we have internally.
Over the course of 2026, this changed. I think the reason is agents became
- much more capable (in writing decent code) and
- we learned to hold people accountable that make agents produce the code.
Especially the latter is a very distinct thing, because before this realization, it felt like “yeah I did prompt Devin, but Devin produced it, so it’s expected that it isn’t the quality we usually want to merge a PR”. This put the burden onto the reviewer.
Nowadays, a Slack agent is treated just like another agent, so it does not matter whether the PR comes from a local agent or a cloud agent. Much like before the age of agents, the code has to meet the bar, and the author who prompted the agent to make the PR, is the person mainly responsible for its quality and breakage when merging (if any).
There wasn’t really a deliberate discussion about this internally, I think it just happened, because more engineers got their hands on agents and agent generated code. With more experience in driving agents, I think the bar every engineer has in mind when it comes to quality of the code the agent produces, got higher and this of course also impacts both your own PRs and the ones you review. Learning how to drive agents to better quality output is a skill engineers have to acquire nowadays.
Understanding the advantages of agents
In February 2026, we held an internal four-day hackathon. My goal was to run multiple projects at the same time, to understand the limits of (human) orchestration; in the end I could finish three out of five. It seems that my personal limit is keeping context for three projects around at once. I’ve heard other engineers mention the same, many of us nowadays have one main branch and one or two workbranches for ‘side’ tasks that you can do while the agent is working on the main one.
Many of us demo’d results that were impressive for that time frame. To us, this was an eye-opener of how the, as Gergely calls it, “winter break” of 2025/26 lowered the time and money needed to prototype things.
Next to engineers, some data and marketing folks participated in the hackathon. Seeing their results felt like an awakening; they fully vibe coded working SaaS replacements, entirely customized to our internal needs. To them, only the result mattered, not the code or how they got there. This made me deeply think about how internal-only code should be treated vs. code that reaches our customers / our core product.
Looking at that code made me honestly sick at times, but it didn’t matter too much, because what they built worked and no engineer had to stop their feature work to help them. I wouldn’t sell it or give to customers, but for internal tools it doesn’t matter as long as they don’t touch PII and are behind a firewall.
From a company perspective, this is highly efficient, as you replace monthly costs with basically a one time cost (tokens) and no wasted engineering time. In this case, the code is also less of a liability, because the people who produced the internal tools can also maintain them without engineering support.
AI as a lever
The smarter agents get, the easier it is to approach ambitious projects. Towards Q3 of 2025, I started an ambitious project that I wanted to have for my performance review for the year. The project was something I always wanted to ship because it could improve React hydration and navigation performance by introducing the render-as-you-fetch paradigm to Framer sites. Leadership knew the importance of the topic, but we had to move it back multiple times, because it felt big, very complex and thus scary (not just to me). I had a perfect vision of what I wanted the result to look like, but it wasn’t really clear to me or anyone else how we get there.
Then, seeing the progress of AI in 2025, plus chatting to AI gave me enough confidence that an RFC seemed like something that could be doable for a single engineer, so I gave it a try and split the complex pieces across multiple milestones. Digging into complicated areas (e.g. CMS) that I had never touched before and just a few engineers had extensive knowledge about, was time-intensive, but manageable with the help of agents. Agents nowadays can drastically speed up research time, but not the human consensus, so getting code owners on board, polishing the RFC together and then the final approval needed a lot of human alignment.
The project turned out to be really successful in improving performance across all Framer sites (see this update), without causing bugs and the added capabilities were built upon by other engineers months later.
This was one of the key projects that was cited as reason for my promotion from Senior to Staff performance engineer. AI is a lever you can pull to both approach highly ambitious projects and to progress your career. Use it to your and your company’s advantage.
The road to becoming efficient
Every new frontier model release, agents get smarter and usually faster, but in codebases some patterns exist that may not reflect the training data. This means, someone has to work through the pain and think about making it better for the next person. I’ve sometimes seen this role called “gardener”, but I think in general this is another skill engineers have to acquire these days: If it doesn’t work, improve it for the next person and next agent.
For example, whenever I got reviews in code areas I’m not so experienced in, I made sure to update related AGENTS.md’s so the next time someone uses an agent to write code in that area, it doesn’t make the same mistake, or automatically writes code with best practices in mind. For the first time in history, you can be sure docs you write get read, because agent harnesses inject the root AGENTS.md at the start of every session.
Understanding the impact this has took a while for me, because no one ever complains when things just work. I figured this out when talking to new hires, they would often say things like
I’m surprised agents work so well here
and in the conversations, we’d come to the conclusion it is because the ‘gardeners’ maintain AGENTS.md’s, so agents understand internal abbreviations, dependencies between different packages in our monorepo, and so on.
We’re also well aware of research on AGENTS.md’s lowering quality if you flood it with info that can get outdated quickly, or is trivially grep-able by agents. So in this case, I do think human reviews are warranted line-by-line, and I see myself as one of these gardeners. We’ve established patterns like splitting up the AGENTS.md’s by using the “load and follow”-syntax, for example “When debugging performance, load and follow <debug-perf.md>”, which avoids flooding the agent with context that not every task may need. To keep instructions from mentioning outdated APIs, we point the agent to the relevant files instead of repeating method names.
PR templates
Speaking of efficiency, we’ve found all models and harnesses have their own kind of ‘default’ PR template, e.g. you can often clearly tell Anthropic models apart from OpenAI models, or even Devin. To avoid filling the context of sessions that do not result in a PR (think research & questions) with terse instructions related to the PR template, we instead made the PR template itself the source of truth with this single line:
Pull Request Guidelines: Always follow the PR template from .github/pull_request_template.md.
The template itself contains a comment with instructions:
<!--
HOW TO FILL THIS PR TEMPLATE IF YOU’RE AN LLM AGENT (CLAUDE, CODEX/GPT, GEMINI, DEVIN, ETC.)
What was done: Write a concise full text summary of the PR; optionally also use up to 3 bullet points. Do not emit what is already obvious from the first glance at the diff; e.g., do not emit the list of changed files. For complex diffs, make sure to include "why" / how the PR fits into the bigger picture.
(...)
If you want to include more details about the PR, do not do this in any of the existing sections (they must be filled as described). Instead, if you have context to add, add the following after the "Context" section:
### AI Context
<details>
[Put your notes here. This can be as short or as long as you want.]
</details>
-->
This keeps the context lean and agents follow the instruction to look up the template all the time. Prior to that, humans would need to manually re-format the entire description to fit our standard template, which cost more time than writing it by hand in the first place.
Agentic pair-engineering
We all know code is produced in chats, but often those chats also disappear in the void. I do think this is a low-hanging fruit waiting to be collected, because chats with a lot of turns contain decisions that may not explicitly make it into the code. Basically, I think there should be a way to make sure the next person with an agent makes the exact same decision as you, even if they lack context in the area of the codebase.
A way to achieve this, is putting those details into comments, commits or PR descriptions. An alternative way to preserve context, is forwarding conversations, literally. For example, today a colleague may review a PR with the help of an agent, then leave the review, the next day you’ll work on the PR, submit to re-review, and the loop starts all over. On the other hand, if the same colleague left a review and a link to their session, you could directly pick up from where the reviewer left and the reviewer could pick up from where you stopped. The advantage I see here is, in cases where agents aren’t correct (either the agent from the PR author, or the agent from the reviewer), humans can step in and correct, without being a meat proxy.
In other words, in this scenario engineers pair on tasks through an agent. This is very much like async Slack threads with cloud agents. From my observations so far, I predict “agentic pair-engineering” will become a thing, because it preserves context that otherwise gets lost in ‘transition’. It also means the old wisdom that pairing needs to happen live is no longer true, one person can now be afk or asleep while the other continues.
—
Apart from that, agents may produce “side-effects”, like Markdown files of investigations or HTML visualizations. Currently, we treat them like throwaway products, they exist for a single purpose (e.g. so the “prompter” can make an informed decision about something) and then they just disappear in the void. From talking to engineers at other companies, it seems like everyone treats it exactly as that. Context created in conversations is a different story though, and based on my observations I see high value in sharing agent chats, or working together through chat-like interfaces.
Apart from Slack agents, we’ve tried Zed Delta and sharing Cursor / Claude / Codex transcripts. I’m also closely watching the team at Entire.io which lets you trace back lines of code to the exact conversation where it got produced (so you can easily figure out “why is the code like it is”). I’ve seen some individuals experiment with these, but it’s far from being an established mechanism at Framer.
How (not) to review agent code
With the increase in efficiency comes the cost of much more code to review. At Framer, we more and more commonly let agents do QA, by defining steps that agents can check and test using Playwright, ‘Computer Use’ or via Devin. For the most part of 2026, we were still expected to review code line-by-line. When I talked to engineers from different frontier labs, I was curious to figure out how they approach PR reviews. I got replies along the lines of “PR reviewers use their agent to review in most teams, just one or two special teams review line-by-line by hand”. This became another meaningful realization, because at Framer, we even discussed things like “how long should a comment be”, or whether internal-only tooling or debugging-related tooling used exclusively by agents, needs to meet our high standards before merging.
I think there is no right or wrong answer here, most of the time the truth is somewhere in the middle. To me, this truly is the most significant difference between the earlier mentioned “top of the wave” and “close to the top” companies: The top of the wave kind of ‘let go’ (if you want to call it like that) and engineers there have learnt to prompt their agents in ways they can confidently review and approve PRs without fully reading the produced code, while other companies are in a limbo. Internally, I’ve observed three camps: The people who still see much value in line-by-line review; the second group is the middle, so line-by-line where it truly matters, otherwise use agents to review PRs; and the third group would love to only use agents to review, to speed up feature delivery.
I don’t think this is unique to Framer. DHH recently posted on X:
It takes a while to build the confidence, but there's no future where you're manually reviewing every line of agent code. Not much acceleration in that. You need adversarial agent reviews, you need automated testing, and maybe you spot check. That's it. From prompt to production!
The replies there kind of paint the exact same picture. Some say quality has always been the problem, not producing code. Others agree with DHH’s take. As an example, Lauren Tan (poteto) from SpaceXAI ships 1000 PRs per month. It shows if you introduce workflows for reviewing PRs, you can ship tons of PRs per month. On the other hand, I’m sure anyone has seen a “slop” interface from bigger companies, so I can see the point when people say quality and not speed is the problem.
To me, quality and speed do not seem like polar opposites, I feel like it really depends on who steers them and what guardrails are provided (or loops as Lauren calls it). The rest comes down to the engineering culture.
I believe engineers will need to let go of “code perfectionism”, depending on what they’re reviewing. It’ll be another skill to acquire where you can fully rely on agents to review and where you should spend time to avoid quality regressions. With agents, the only place for code perfectionism should be in areas where it’s warranted (like security). It shouldn’t matter whether a comment is three or five lines, a reviewer should only in exceptions make a PR author rephrase a comment just because it reads more Claudish than English. The same could be said about variable-name nits or similar, basically anything that extends the “review loop” (author -> reviewer -> author -> reviewer) unnecessarily slows down shipping. To what degree “overly broad” comments are acceptable (or variable names), is something I think every org has to figure out on their own.
What still truly matters is e.g. how a PR fits the architecture, if it introduces regressions, if it’s secure and whether the result is what is intended or what it claims. Those are things I think PR reviewers should look for, and they should do so by using agents (and only if something is ‘sus’, spot check parts of the actual code). PR authors on the other hand should invest in loops before raising a PR, for example making sure the PR is as simple as it can get, or if there are alternative ways to get to the same result, in a more performant or less prone-to-bugs way. A common failure mode I’ve observed is the PR author thinking the first solution the agent proposed is good and the PR reviewer suggesting simplifications the agent would also be trivially able to suggest. This also prolongs the review loop for no reason, but this time it’s the author’s fault. Preventing those failure modes and keeping the review loop tight is what I see as important skills going into the future.
My observation from Framer is, leadership has high interest in keeping the quality high we’re known for, while shipping faster and faster, as AI capability progresses. The challenge there is, how to balance both and we don’t have the one single answer to this (yet).
Conclusion
From my observation, agents do make humans more efficient (not just engineers). As an engineer, you can touch parts of the codebase you barely know; as a backend person you can do frontend (to some degree); as a new hire you can be productive much earlier. Agents seem like a major lever you can pull to work on tasks that have a large scope and real impact, without being in the company for years or knowing every nitty-gritty detail of the area you’re about to touch.
To maximize efficiency, establishing a culture of improvement that has agents in mind is impactful. Have people not just think about their work, but also the next person’s work and the next agent. The other one is, have a low-entry barrier for agentic work. Some companies do this by having their own internal coding agent system (like Ramp’s Inspect), we prefer Slack (Devin).
Back in 2024, I was mostly curious about how I can write code faster. I think today I’m more interested in how we’ll review PRs more efficiently a year from now. My bet is that we’ll stop reading code when we can easily tell what loops authors have run before making a PR (so reviewers don’t have to spend the time on “can we do simpler”). QA will be entirely done by agents. I think line-by-line reviews will only happen where a mistake is expensive: Security, architecture, and changes that are one-way-doors. Or maybe PR’s will be gone entirely, the team at Amp already works like that.

