<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh" -->

---
title: Bringing Goodnotes to the web with Swift and WebAssembly
description: Goodnotes engineers describe how they brought their iPad note-taking app to the web by compiling millions of lines of Swift code to WebAssembly via SwiftWasm,...
canonical: https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Bringing Goodnotes to the web with Swift and WebAssembly | daily.dev
og:description: Goodnotes engineers describe how they brought their iPad note-taking app to the web by compiling millions of lines of Swift code to WebAssembly via SwiftWasm,...
og:url: https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh
og:image: https://api.daily.dev/og/posts/fjwkXrVqh.png
og:image:alt: Bringing Goodnotes to the web with Swift and WebAssembly
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Bringing Goodnotes to the web with Swift and WebAssembly

**[Swift.org](https://daily.dev/sources/swift)** · 8 min read · 0 upvotes · 0 comments

## Summary

Goodnotes engineers describe how they brought their iPad note-taking app to the web by compiling millions of lines of Swift code to WebAssembly via SwiftWasm, sharing 66% of the web codebase with iOS. The piece covers their architecture (shared rendering engine, business logic, and view models), handling wasm32's 32-bit Int, migrating from libdispatch to Swift Concurrency, implementing true multithreading with WASI threads and SharedArrayBuffer for a 2x INP improvement, debugging Swift in Chrome DevTools, and their custom wasm-memprof tool. They note WebAssembly platform support has been official in Swift since version 6.2 and offer recommendations for teams considering the same path.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://swift.org/blog/bringing-goodnotes-to-web-with-swift>

## Questions this post answers

### Since which Swift version has WebAssembly been an officially supported platform?

WebAssembly platform support has been included in Swift since version 6.2, following upstreaming of WebAssembly-related changes contributed by teams like Goodnotes that had been using SwiftWasm in production. This means developers can now use official tooling and language features for targeting WebAssembly rather than relying solely on the community-driven SwiftWasm project.

_Developers evaluating Swift's WebAssembly readiness can track ecosystem changes like this on daily.dev._

### How much code can be shared between an iOS app and its WebAssembly web version when both are written in Swift?

Goodnotes shares 1.47 million lines of Swift code between its iOS and web apps, which is 66% of the total 2.2 million line web codebase and 34% of the iOS app. The shared portion includes the content rendering engine, business logic layer, and view models, with only platform abstraction layers implemented separately.

_Teams weighing cross-platform code-sharing strategies can follow real-world case studies like this on daily.dev._

### How do you achieve multithreading in a Swift WebAssembly application running in the browser?

True parallelism in Swift compiled to WebAssembly is achieved using WASI Threads combined with Web Workers and SharedArrayBuffer, with Swift Concurrency's Custom Actor Executors (SE-0392) used to pin specific actors to specific Web Workers since JavaScript objects are isolated to their originating thread. This approach delivered over a 2x improvement in Interaction to Next Paint, but requires Cross-Origin Isolation for SharedArrayBuffer support.

_Developers tackling WebAssembly threading and performance tuning can find deep dives like this on daily.dev._

## Similar posts on daily.dev

- [Issue 742 – iOS Dev Weekly](https://daily.dev/posts/issue-742-ios-dev-weekly-nt977rqd0) · iOS Dev Weekly · 0 upvotes · 0 comments
- [WebAssembly gaining adoption "behind the scenes" as technology advances • DEVCLASS](https://daily.dev/posts/webassembly-gaining-adoption-behind-the-scenes-as-technology-advances-devclass-2vsbkezzr) · DEVCLASS · 19 upvotes · 0 comments
- [The 7 Walls JavaScript Hits — and How WebAssembly Gets Past Them](https://daily.dev/posts/the-7-walls-javascript-hits-and-how-webassembly-gets-past-them-isxmm7isd) · DEV · 2 upvotes · 0 comments
- [WebAssembly: an introduction](https://daily.dev/posts/webassembly-an-introduction-1iycvposp) · Flavio Copes · 3 upvotes · 0 comments
- [First Impressions of WWDC 2026: In Line with Expectations, but More Pragmatic -- Fatbobman's Swift Weekly \#139](https://daily.dev/posts/first-impressions-of-wwdc-2026-in-line-with-expectations-but-more-pragmatic----fatbobman-s-swift-w-nypgbg6ex) · Fatbobman · 0 upvotes · 0 comments

---

Tags: [#swift](https://daily.dev/tags/swift), [#webassembly](https://daily.dev/tags/webassembly)

[View this post on daily.dev](https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Bringing Goodnotes to the web with Swift and WebAssembly","url":"https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh"},"datePublished":"2026-08-23T12:17:04.114Z","dateModified":"2026-08-23T12:20:47.969Z","description":"Goodnotes engineers describe how they brought their iPad note-taking app to the web by compiling millions of lines of Swift code to WebAssembly via SwiftWasm,...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3d74604429688f5b97665801b2580703?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3d74604429688f5b97665801b2580703?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Swift.org","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Swift.org","logo":"https://media.daily.dev/image/upload/s--x7Cjs0jz--/f_auto,q_auto/v1787487412/logos/swift?_a=BAMAMicg0","url":"https://daily.dev/sources/swift"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"swift,webassembly","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Swift.org","item":"https://daily.dev/sources/swift"},{"@type":"ListItem","position":3,"name":"Bringing Goodnotes to the web with Swift and WebAssembly"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/bringing-goodnotes-to-the-web-with-swift-and-webassembly-fjwkxrvqh#faq","mainEntity":[{"@type":"Question","name":"Since which Swift version has WebAssembly been an officially supported platform?","acceptedAnswer":{"@type":"Answer","text":"WebAssembly platform support has been included in Swift since version 6.2, following upstreaming of WebAssembly-related changes contributed by teams like Goodnotes that had been using SwiftWasm in production. This means developers can now use official tooling and language features for targeting WebAssembly rather than relying solely on the community-driven SwiftWasm project. Developers evaluating Swift's WebAssembly readiness can track ecosystem changes like this on daily.dev."}},{"@type":"Question","name":"How much code can be shared between an iOS app and its WebAssembly web version when both are written in Swift?","acceptedAnswer":{"@type":"Answer","text":"Goodnotes shares 1.47 million lines of Swift code between its iOS and web apps, which is 66% of the total 2.2 million line web codebase and 34% of the iOS app. The shared portion includes the content rendering engine, business logic layer, and view models, with only platform abstraction layers implemented separately. Teams weighing cross-platform code-sharing strategies can follow real-world case studies like this on daily.dev."}},{"@type":"Question","name":"How do you achieve multithreading in a Swift WebAssembly application running in the browser?","acceptedAnswer":{"@type":"Answer","text":"True parallelism in Swift compiled to WebAssembly is achieved using WASI Threads combined with Web Workers and SharedArrayBuffer, with Swift Concurrency's Custom Actor Executors (SE-0392) used to pin specific actors to specific Web Workers since JavaScript objects are isolated to their originating thread. This approach delivered over a 2x improvement in Interaction to Next Paint, but requires Cross-Origin Isolation for SharedArrayBuffer support. Developers tackling WebAssembly threading and performance tuning can find deep dives like this on daily.dev."}}]}
```

