// case study · custom software
Web-app to native Mac + Windows
in 2 months.
The board demanded features the browser couldn't deliver. We proposed the pivot, scoped it in a week, and shipped native desktop apps for both platforms in eight.
A growth-stage European B2B SaaS client and rot8 were co-developing a web product when the company's board ratified a feature set the browser couldn't reach — multi-window workflows, OS-level integration, offline-first behavior, and sustained low-latency interactions on data-heavy views. rot8 ran the brainstorm, proposed the native desktop pivot, scoped a 2-month delivery window, and shipped working Mac and Windows applications with feature parity plus the desktop-only capabilities the board asked for. The web-app stayed as the marketing and trial surface.
- Published 2026-05-04
- Engagement: 2026 Q1
- By the rot8 team
// the client
Anonymized at client request. Numbers are real.
- Stage: Series A growth-stage B2B SaaS
- Sector: European productivity / vertical SaaS (anonymized)
- Engagement model: rot8 was already co-developing the web-app via Embed — senior pod inside the client's product org
- Web-app status at pivot decision: in production with paying customers, on the active roadmap
- Trigger: the client's board ratified a feature set the existing web-app couldn't accommodate within browser runtime limits
// the problem
The browser was the ceiling, not the team.
The web-app was working. Customers were using it. The team was shipping. The bottleneck wasn't velocity, scope discipline, or design — it was the runtime itself. The board had committed the company to a set of differentiating features, and four of them lived below the browser's permission and performance boundaries.
What the browser couldn't carry
- Multi-window workflows. Power users needed several documents open in independent OS windows with their own state — outside what tab-based web sessions can durably model.
- Sustained low-latency interactions on data-heavy views. Sub-16ms render budget on workloads that the web platform's scheduling couldn't reliably hit at the volumes the customer base was hitting.
- Offline-first. Customers worked in environments where connectivity was incidental. Service workers could not deliver the consistency model the workflow needed.
- OS-integrated file and document handling. Drag-and-drop from the OS file manager, system-level notifications tied to long-running jobs, native print and export pipelines.
None of these were code-level problems we could engineer around. They were runtime-level constraints. Trying to ship them inside the browser would have produced four watered-down versions of features that needed to be sharp.
// the brainstorm
One week to choose the pivot.
The board's feature commitment came in on a Friday. The following Monday, the rot8 pod ran a one-week structured brainstorm with the client's product and engineering leads. We considered three paths.
Path 1 — Push the web-app harder.
Workarounds for each feature: PWA installation, background sync, a browser extension for OS-level affordances, a desktop-only mode toggled by user-agent detection. We mocked the user journey for each. Three of the four features ended up materially compromised; the fourth was unbuildable. Ruled out — the board would have shipped a degraded product.
Path 2 — Hybrid: web-shell-in-desktop-wrapper.
A desktop wrapper around the existing web-app, with a thin native bridge for the OS-level features. Faster to ship in the short run, but the multi-window and low-latency-render requirements re-introduce most of the browser's constraints inside the wrapper. Ruled out — the wrapper would carry forward exactly the limits we were trying to escape.
Path 3 — True native, both platforms.
Mac and Windows applications with platform-native UI shells, sharing a single core layer for state, networking, and business logic, talking to the same back-end the web-app already used. More upfront design and discipline than path 2; cleaner ceiling. Selected.
The proposal landed with the client's CTO and product lead by Friday of week one. The board approved it the following Monday. Build started week two.
// the architecture
Two platforms, one product.
1. Reuse the back-end. Don't fork.
The web-app's API was healthy and already powered the live product. The native apps would speak the same API, with the same auth, the same data model, and the same business rules. No back-end fork. A small adapter layer on each native client mapped server contracts to platform idioms. That decision alone removed an entire category of drift between web and desktop and let one product manager own feature semantics across all three surfaces.
2. Shared core layer, platform-native shells.
State management, networking, sync, conflict resolution, and the domain model lived in a single shared core. Above the core, each platform had its own UI shell written in the platform's native idiom so that windowing, accessibility, gestures, and OS-level integration felt right on each. That gave us roughly 1.4× the engineering cost of a single platform — not 2× — for two true native apps.
3. Offline-first as a first-class concern.
We modeled the local store as the authoritative client state with the server as the eventual-consistency anchor — not the other way around. Every mutation queued locally, replayed against the server with idempotency keys, and reconciled on conflict using a small set of explicit merge rules per entity type. Customers in low-connectivity environments saw the app behave the same online and offline.
4. One design language across both.
A single product designer set the desktop interaction language for both platforms — anchored on each OS's native conventions, with the client's brand treatment as a thin overlay. Customers using both Mac and Windows machines (a meaningful subset) recognized the same product in both places without it feeling like a port.
// the timeline
Two months, week-by-week.
| Week | Phase | What shipped |
|---|---|---|
| 1 | Brainstorm + scope | Three-path option memo · pivot decision · feature parity matrix · 2-month plan · fixed quote |
| 2 | Foundation | Shared core layer scaffolded · API adapter on both platforms · CI for both targets · design system extended for desktop |
| 3 | Foundation → feature work | Auth flow native on both platforms · first end-to-end document workflow live in dev |
| 4 | Feature parity | Read paths complete on both platforms · multi-window state model implemented · drag-and-drop wired |
| 5 | Mid-engagement demo + course-correct | Bi-weekly demo · client product team requested an additional native print pipeline; written change order kept timeline intact |
| 6 | Desktop-only features | Offline-first sync working end-to-end · OS notifications · system-level file integration |
| 7 | Pre-launch | Performance pass to lock the 16ms render budget on data-heavy views · accessibility audit on both platforms · auto-update pipeline · code-signing on both platforms |
| 8 | Launch + stabilization | Rollout to existing paying customers · 72-hour on-call coverage by the rot8 pod · two minor patches in production · runbook delivered · 90-minute handoff session |
Both apps shipped on week 8. The web-app stayed live as the marketing and trial surface.
// the outcome
What unlocked when the runtime stopped fighting the product.
- All four board-committed features shipped at full fidelity. Multi-window workflows, low-latency rendering on data-heavy views, offline-first, OS-integrated file handling — none compromised by runtime constraints.
- Two-tier acquisition shape preserved. The web-app continued to drive trial and onboarding. The native apps became the workspace for paying customers — a clean upgrade path the marketing team could narrate.
- 1.4× cost, not 2×. The shared-core architecture meant two platforms cost roughly the equivalent of 1.4 single-platform builds, not two.
- Codebase the client's team owns. Shared core plus two platform shells, fully documented, in mainstream stacks the client's engineering team could extend. No proprietary frameworks. No rot8 lock-in.
- Board narrative delivered. The pivot from “features we said we'd ship” to “features that shipped” closed inside the timeline the board had set.
// the handoff
End of week 8.
- Codebase: shared core + Mac shell + Windows shell, in mainstream stacks the client's engineering team could extend immediately.
- Architecture decision record: the four structural decisions documented with rationale and what to revisit at scale.
- Build + release pipelines: auto-update, code-signing, and notarization live on both platforms — not deferred to “phase two.”
- Runbook: incident-shape playbooks for sync conflict, auto-update failure, OS-permission revocation, and the boundary between native local store and server state.
- Follow-on: the rot8 pod stayed embedded for the following quarter to support the rollout and pick up the next-priority desktop-only features.
// quick answers
Case study, common questions.
Why pivot from web to native instead of pushing the web-app harder?
The features the client's board was asking for weren't a coding problem — they were a runtime ceiling. Multi-window workflows tied to OS-level state, sustained low-latency interactions on data-heavy views, deep file-system integration, and offline-first behavior live below the browser's permission and performance boundaries. Pushing the web-app harder would have shipped a degraded version of every feature. A native pivot was the lower-risk, higher-fidelity answer.How did rot8 ship two desktop platforms in 2 months?
By treating the platforms as one product with platform-native UI shells. We kept the existing API and data model from the web-app — already in production — and built thin native shells on Mac and Windows that shared a single core layer for state, networking, and business logic. One designer set the desktop interaction language across both. That collapsed two builds into ~1.4× the work of one, not 2×.Did the web-app get deprecated?
No. Web stayed as the marketing surface, the trial onboarding flow, and the read-only dashboard for casual users. The native apps became the workspace for the customers who were paying for the depth. That two-tier shape preserved the marketing and acquisition funnel the client had built around the web product, while moving the value-dense workflows to a runtime that could carry them.Why publish this case study anonymized?
The client preferred it. We default to anonymized case studies because most pre-Series-B clients consider the existence of a partner studio competitively sensitive. We anonymize the brand and never the work — the shape of the problem, the architectural decisions, the timeline, and the engagement model are all real.
// next step
Three projects this quarter. Two remain.
Apply with the four-step form. We respond inside 48 hours, every time, with a real reply from a named founder.