Why Goodnotes' Swift-to-WebAssembly Journey Matters for Your Next Web Project

Why Goodnotes' Swift-to-WebAssembly Journey Matters for Your Next Web Project

Jun 02, 2026 swift webassembly webdevelopment crossplatform mobiledevelopment swiftwasm softwarearchitecture

markdown formatted blog content

When Goodnotes shipped their web application in 2023, they did something remarkable: they ran the exact same Swift code that powers their award-winning iPad app directly in the browser. No JavaScript rewrite. No Flutter port. Just WebAssembly doing the heavy lifting.

This isn't a gimmick or a proof-of-concept. It's been running in production for over two years now, serving real users who expect pixel-perfect ink rendering and buttery-smooth performance. And it opens up some fascinating possibilities for how we think about cross-platform development.

The Problem with "Write Once, Fix Everywhere"

Every development team eventually faces the platform dilemma. Build native for each platform and multiply your maintenance burden. Choose a cross-platform framework and accept the performance tradeoffs or platform quirks. The conventional wisdom says you can't have both native performance and code sharing.

Goodnotes had accumulated over a decade of refinements in their digital ink rendering engine. Their rendering logic handles pressure sensitivity, stroke smoothing, and real-time feedback at 60 frames per second. When they decided to go web, the obvious paths—JavaScript rewrite, Flutter, React Native—all meant starting from scratch and inevitably introducing subtle behavioral differences between platforms.

Their solution was SwiftWasm: a community-driven project that compiles Swift to WebAssembly. The first experiment focused on their handwriting component, the performance-critical heart of their application. If WebAssembly could handle that, it could handle anything.

What Actually Got Shared

The numbers are striking. Out of 2.2 million lines of Swift code in their web application, 1.47 million lines (roughly 66%) are shared with their iOS counterpart. This includes:

  • The entire rendering logic for notebook content
  • Handwriting recognition algorithms
  • Document synchronization using Conflict-Free Replicated Data Types (CRDTs)
  • Content search and indexing systems

The only platform-specific code handles the actual graphics API calls: Metal on iOS, WebGL on the web. The logic remains identical.

Here's what this means in practice: when a user draws a stroke on their iPad and later opens the same document in a browser, they see exactly the same curves, the same pressure sensitivity, the same ink behavior. Not because Goodnotes carefully reimplemented identical algorithms twice, but because it's literally the same Swift code executing on both platforms.

The Technical Journey Wasn't Trivial

Of course, it's not as simple as flipping a compiler switch. Goodnotes had to navigate real architectural challenges:

Concurrency had to evolve. The libdispatch APIs (Grand Central Dispatch) that many Swift apps rely on don't exist in WebAssembly. Goodnotes migrated their concurrent code to Swift's native async/await and actors, which improved cross-platform compatibility overall.

Integer sizes differ. WebAssembly's wasm32 target uses 32-bit integers, which meant hunting down assumptions throughout their codebase about Int width.

JavaScript interoperability required bridges. They used JavaScriptKit to connect their Swift logic to browser APIs and the existing web ecosystem.

These weren't trivial fixes, but they were finite problems with concrete solutions. The alternative—maintaining parallel codebases forever—has no end in sight.

What This Means for Your Projects

Goodnotes' success suggests that Swift on WebAssembly is no longer experimental. If you're building performance-critical applications with complex logic, this approach offers genuine advantages:

True behavioral consistency across platforms without the translation layer that often introduces subtle bugs in cross-platform frameworks.

Leveraging existing native code for teams who already have substantial Swift investments in iOS or macOS applications.

WebAssembly's sandboxed security model combined with Swift's memory safety features.

The web platform has quietly become a legitimate deployment target for languages originally designed for native development. Whether you're building a complex web application, a developer tool, or a creative application like Goodnotes, the barriers to cross-platform deployment are lower than ever.

The 12 MB compressed binary size (down from 50 MB uncompressed) with Service Worker caching means users get fast subsequent loads. Modern WebAssembly implementations are performant enough for real-time graphics. The tooling has matured.

The Bigger Picture

We're witnessing a shift in how we think about platform boundaries. The web was once the great equalizer—a way to reach users without native installation. But increasingly, it's becoming a first-class deployment target for applications built with native languages.

Goodnotes' experience proves something important: the question isn't whether you can run complex, performance-sensitive applications in the browser. The question is whether your architecture was designed with that flexibility in mind.

For startups and development teams, this opens strategic possibilities. Build in Swift for iOS? That same code can reach the web. Invest in performance-critical logic? Deploy it everywhere.

The platform walls are getting thinner. The only question is whether your codebase is ready for the crossing.

Read in other languages: