Strawberry: rewriting 130K lines from React to Svelte
Charles Maddock, CEO of Dendrite Systems, on the company blog, 9 March 2026: "How we Rewrote 130K Lines from React to Svelte in Two Weeks." Strawberry is an AI-assisted desktop web browser. Its UI ran on react for about a year and was then ported to svelte two weeks before launch. Markus Andersson, a founding engineer, led the port and is quoted throughout. Found by the research pass for edge 9a, which asked for a team that shipped the same product on both, with bundle size or interaction latency stated. This is that shape, and the first in the spoke.
Tier T3. The post is the vendor describing its own product in a launch-adjacent post. It has numbers but gives no method for any of them, and nobody outside has checked them. It is first-party about a real artifact, which is what T3 means here, and it meets the research bar only because the edge names a first-party fact: what one team measured on its own app.
Why they left React
The case is about workload, not taste. Strawberry runs separate renderer processes for settings pages, modals, dropdowns and the chat sidebar, and each one held its own React app. The post's example is six at once: four settings pages, the sidebar and a dropdown. One event from the main process updated all of them together, and the post calls the result "rendering cascades." Background AI agents push UI updates all the time, so every streamed token became a re-render of a component tree in which one value had changed. Jotai and Zustand are dismissed as "patches bolted on top of React." The line the post turns on: "React was working for us, it just wasn't fast enough."
That is the mechanism the spoke already holds, seen from a product. js-framework-benchmark found the two frameworks within a few milliseconds on most operations and 7× apart on one: an update where a reconciler has to prove that almost nothing changed. Streaming tokens into six live trees is that operation, repeated all day.
What they report
| Claim | Figure | Method stated |
|---|---|---|
| Overall | "2x faster in production" | none |
| New-tab first contentful paint | 300 ms → 124 ms | metric named, no tool or hardware |
| Re-renders during LLM token streams | cut 10× | none |
| One tree-shaking pass | 200 ms gained | no baseline |
| Unused dependencies removed | 56 | — |
| Diff | 103K lines added, 124K removed | — |
There is no bundle size, no memory figure and no frame rate. The 300 → 124 ms figure is the only one tied to a named metric, and it is the closest the spoke now has to the interaction latency the edge asked for.
How it was done
Andersson ported 60% over "a few evenings and a weekend" with coding agents before he showed the team.
The post says a working demo convinced them where a design document would not have. He then spent about
a day writing a Svelte ruleset for the agents ("Avoid $effect", "Prefer stores over component
state"), because "LLMs write much worse Svelte than you think. They reach for $effect out of React
habit." Work went feature by feature: read the rules, port, test. The old code sat in a react-src
folder kept in sync with the dev branch, since the team went on shipping on React during the port.
Cursor did most of it; Claude Code and Codex were used near the end.
What it cost
The post names two costs. Imperfect syncing with the live React branch meant "a few features being silently dropped at launch", which were rebuilt later. And Svelte had no drag-and-drop library that fit the tab bar, so a second founding engineer wrote one. It "still wasn't fully stable at launch" and was fixed in the next update. The ecosystem worry was otherwise unfounded in their case. Hiring is not mentioned.
What this does and does not settle
It settles that, for at least one shipped product, the swap-a-row cost js-framework-benchmark measured was not a lab curiosity. The product's real workload was that operation, and the team rewrote the whole UI to get away from it. It does not settle the edge's wider question, for four reasons:
- No method. Every figure is the vendor's, about its own launch, with no tool, device or run count stated.
- The numbers do not add up. The headline says 130K lines; the diff says 103K added and 124K removed. "The whole rewrite took two weeks" sits beside "85% completion in two weeks," and neither counts the evenings before. "One engineer" sits beside a second engineer who wrote the drag-and-drop library.
- It is the extreme workload. Several live React roots and a constant token stream is the case where a reconciler does worst. The post limits its own argument to "UIs constantly responding to AI," and that limit is fair.
- It is written at the start, not a year later. Ecosystem, hiring and maintenance, the arguments the choice is usually made on, are not reported at all. Edge 8's question, what the choice costs after a year, is untouched.
The post itself concedes the standard advice: "don't rewrite. And it's usually right."
Related
svelte · react · js-framework-benchmark · ui-framework · agent-ready-ui · synthesis
Cross-spoke. Strawberry is a browser, so the product belongs to ../web-browsers-wiki; this page
keeps only the framework decision. The ruleset written to stop agents producing React-shaped Svelte is
a case for ../agentic-tooling-wiki's skills-and-rules thread.