All Articles
CategorySwift
Reading Time
13 min read
Published
2026-11-01
Word Count
3,199words

Grab a coffee — this one is a deep dive!

ElementaryUI: Swift Now Runs in the Browser (WebAssembly)

Summary

With Swift 6.4's official Wasm SDK and ElementaryUI, Swift now runs in the browser. We examine Embedded Swift, a Cloudflare Worker demo, and the browser side of full-stack Swift, with sources.

  • Swift 6.4 (September 15, 2026) sped up JavaScriptKit bridging; the official Wasm SDK ships directly from swift.org (since 6.2).
  • Elementary renders HTML on the server, while ElementaryUI is a separate library that runs in the browser via WebAssembly — don't confuse them.
  • In the Cloudflare Worker demo, the edge-side wasm fetch handler is roughly 107 kB; the frontend bundle size should be measured separately.
  • The ecosystem is still experimental: NewCodable and Embedded Swift have usability quirks, and it's still early for critical production use.
ElementaryUI: Swift Now Runs in the Browser (WebAssembly)

Swift is no longer server-only: with WebAssembly compilation, it now runs in the browser too. Swift 6.4 shipped on September 15, 2026; the official Wasm SDK ships directly from swift.org, and JavaScriptKit's JS bridging got a big speed boost this release. ElementaryUI is one of the libraries building a SwiftUI-like, state-driven interface layer on this infrastructure. This guide walks through the browser side of full-stack Swift — from Embedded Swift to a Cloudflare Worker demo.

💡 Pro Tip: Don't confuse ElementaryUI with the server-side Elementary library — they're different projects by the same author; one produces HTML, the other manages state in the browser. This article draws a clear line between the two.

Table of Contents

The missing half of full-stack Swift: the browser

Server-side Swift (Vapor, Hummingbird) has long been mature in the Swift ecosystem, and iOS/macOS has always been Swift's home turf. The missing piece was the browser. swift.org's "What's new in Swift: August 2026 Edition" digest, published September 4, 2026, describes this gap explicitly: thanks to the community's years-long swift-wasm project, compiling Swift to WebAssembly became increasingly viable. That groundwork first led to the birth of Elementary, a server-side HTML rendering library, and then to the emergence of ElementaryUI, which runs in the browser.

Seen through an iOS developer's eyes, the shift is clearer: you already write interfaces in SwiftUI and APIs in Vapor — but a language boundary remained, because the real browser interface layer was JavaScript's monopoly. ElementaryUI's claim is exactly to remove that boundary: you can now run a component built with the same @State logic in the browser via WebAssembly.

Think of this as the next layer on top of the concurrency foundation Swift 6.0 introduced: the language first expanded concurrency, then its compile targets. If you already know server-side Swift from building a backend API with Vapor or the general server-side Swift ecosystem, the browser side completes that picture: server and client in the same language.

Why this matters now

There's a concrete reason this is surfacing at the end of 2026: Swift 6.4's official Wasm SDK and the JavaScriptKit speedup moved an experimental community project much closer to production. But it's worth not overstating this — the ecosystem is still young, as the sections below show.

Elementary (HTML on the server) vs ElementaryUI (state-driven in the browser)

It's easy to mix these two up because their names are nearly identical and they belong to the same developer (Simon Leeb). But their goals are completely different:

Feature
Elementary
ElementaryUI
Runtime
Server (Vapor/Hummingbird)
Browser (WebAssembly)
Output
Static/server-rendered HTML
State-driven, reactive DOM
Integration
hummingbird-elementary, vapor-elementary packages
Embedded Swift + Wasm compile toolchain
Package version
from: "0.6.0" (elementary package)
Separate project, via elementary.codes

This distinction is summed up right in the intro of Elementary's own README and the note right below it: "Elementary is built for server-side rendering" and "check out ElementaryUI for running Swift apps in the browser." So assuming one project replaces the other — or mistaking the elementary repo on GitHub for ElementaryUI — would be a technical mistake. Simon Leeb draws the exact same line in his guest post on the swift.org digest: "Elementary renders HTML on the server, while ElementaryUI runs inside the browser."

The API surface ElementaryUI promises

elementary.codes' homepage features a declarative syntax example aimed at developers already familiar with SwiftUI:

swift
1// Promo example from the elementary.codes homepage
2@View
3struct LoveCounter {
4 @State var count = 1
5 
6 var body: some View {
7 p { String(repeating: "❤️", count: count) }
8 
9 if count < 10 {
10 button { "More Love" }
11 .onClick { count += 1 }
12 } else {
13 p { "Enough love for you!" }
14 button { "Less Love" }
15 .onClick { count = 1 }
16 }
17 }
18}

This example shows ElementaryUI's intent to bring SwiftUI's @State/@Environment logic to the browser. The site's promise: producing wasm bundles measured "in kB, not MB," thanks to Embedded Swift support.

How the Embedded Swift + swift-wasm toolchain came together

Wasm support didn't arrive overnight. Per the swift.org digest, the community's swift-wasm project first made compiling Swift to WebAssembly increasingly viable; Embedded Swift then joined through experimental steps. Official SDK distribution has existed since Swift 6.2: "with Swift 6.2 and development snapshots, you can easily cross-compile and run Wasm modules."

With Swift 6.4 this formalization advanced on two fronts:

  1. The Wasm SDK version ships alongside the toolchain from swift.org — the matching SDK for the 6.4.0 toolchain is ready at the official download address (distribution has been available since 6.2).
  2. Wasm↔JS bridging via JavaScriptKit got noticeably faster in 6.4 — in swift.org's own words, "WebAssembly bridging via JavaScriptKit is up to 40x faster."

Two SDK variants

The official documentation offers two different SDK packages during setup:

SDK name
Scope
swift-<version>_wasm
The full standard library, complete Foundation support
swift-<version>_wasm-embedded
The Embedded Swift subset — smaller binary, limited runtime features

Which one you pick depends on whether your target is a server-side edge worker or a browser-based interface; libraries like ElementaryUI target the embedded variant for small binary size.

Why two separate SDKs are needed

The reason for this split lies in Embedded Swift's own design philosophy: to shrink the language's runtime, some dynamic features (full reflection, some Foundation APIs) are deliberately left out. swift.org's documentation presents this trade-off openly as a "scope" choice — the full Wasm SDK has no restrictions, while the embedded variant trades some standard-library features for a smaller binary. So clarifying which runtime constraints you can accept, before choosing an SDK, is a step that comes first when starting a project.

Setup, following the pattern in the official swift.org documentation, works like this (the checksum below is for version 6.4.0; use the current value from the swift.org page for newer versions):

bash
1# Official Wasm SDK install (command from swift.org documentation)
2swift sdk install \
3 https://download.swift.org/swift-6.4.0-release/wasm-sdk/swift-6.4.0-RELEASE/swift-6.4.0-RELEASE_wasm.artifactbundle.tar.gz \
4 --checksum f07b7be3c586d92d7a07051fc6d303b87ebea67eadc40640ba59d5a8b79aa86d

This command adds a cross-compilation target to the Swift toolchain; after installing, you take the SDK ID from the swift sdk list output and build with swift build --swift-sdk swift-6.4.0-RELEASE_wasm. For the embedded variant, you use the ID with the -embedded suffix (swift-6.4.0-RELEASE_wasm-embedded).

If you already know the Swift concurrency foundation via async/await, you won't feel out of place on the code side sitting on top of this compile chain — what changes in the browser is mainly the runtime target, not the language itself.

Running the Cloudflare Worker demo step by step

The most concrete evidence is the demo ElementaryUI's creator, Simon Leeb, posted on Swift Forums on August 25, 2026: "Edge of Tomorrow: Full-Stack Swift on Both Sides of Fetch." It was a community preview from before Swift 6.4's official release — the author noted at the time, "Swift 6.4 hasn't shipped yet." Its main components:

  • ElementaryUI (frontend): The interface layer that runs in the browser, compiled to WebAssembly.
  • BridgeJS: A JavaScriptKit-based Wasm↔JS interop layer; the frontend's Fetch API networking also runs through this layer.
  • NewCodable (experimental): For encoding Swift data types shared between the frontend and the backend.
  • Cloudflare Worker (edge backend): The server side where the Swift logic is compiled to Wasm and run at the edge; it runs as a Cloudflare fetch handler.

To run the demo yourself, the "Run locally" section of the source repo's (elementary-swift/example-cloudflare-worker) README lists four commands using Swiftly and Node.js 24+:

bash
1# example-cloudflare-worker README, "Run locally" steps
2swiftly install
3swift sdk install \
4 https://download.swift.org/swift-6.4.x-branch/wasm-sdk/swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-08-14-a/swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-08-14-a_wasm.artifactbundle.tar.gz \
5 --checksum 11fabfac6804222569d330fbbb5fa34eef736abda46790e723ac73b256fd1c7a
6npm install
7npm run dev

You can reach the live demo at https://cloudflare-worker.examples.elementary.codes/. It's a concrete example of ElementaryUI's frontend and a Cloudflare Worker's edge backend running together in the same language, in the same repo.

Wasm binary size and initial load cost

Binary size is always the first question in Wasm-based web development. ElementaryUI's official promise: bundles "in kB, not MB," thanks to Embedded Swift. But that's a general tagline — no concrete number appears on elementary.codes' own page.

The one concrete measurement comes from the Cloudflare Worker demo: the wasm fetch handler at the edge is roughly 107 kB. An important nuance — this is the edge worker's (backend) binary size; neither elementary.codes nor the forum post gives a number for ElementaryUI's browser-side frontend bundle. So generalizing "every ElementaryUI app is X kB" would be wrong — 107 kB is one concrete edge-side example from a single real demo.

Practical takeaway: kB-scale binaries ease the traditional worry that "porting Swift to the browser means megabytes of download" — but measuring your own project's real bundle size before production is still your job.

Binary size alone isn't enough to judge initial load cost, either; compiling and instantiating the Wasm module in the browser is a separate cost. Since neither swift.org nor elementary.codes measures download and compile separately, watch both your network tab's download time and the Performance panel's compile/instantiate time in your own project — don't assume "kB-sized means instant."

Connecting the server side with Vapor/Hummingbird

ElementaryUI alone isn't enough for a full-stack Swift application — you also need to wire up the server side. Elementary's official repo offers two bridge packages for this:

  • hummingbird-community/hummingbird-elementary (from: "0.3.0") — integrates Elementary with Hummingbird.
  • vapor-community/vapor-elementary (from: "0.1.0") — integrates Elementary with Vapor.
swift
1// Package.swift — package references from Elementary's official README
2dependencies: [
3 .package(url: "https://github.com/elementary-swift/elementary.git", from: "0.6.0")
4 // Add one based on your server framework:
5 // .package(url: "https://github.com/hummingbird-community/hummingbird-elementary.git", from: "0.3.0")
6 // .package(url: "https://github.com/vapor-community/vapor-elementary.git", from: "0.1.0")
7]

The NewCodable (experimental) types from the Cloudflare Worker demo come into play here too: frontend (ElementaryUI/Wasm) and backend (Vapor/Hummingbird or an edge worker) can share the same Swift structs — no separate DTO layer needed for request/response serialization. This extends the type safety you know from building a backend API with Vapor all the way to the frontend.

Note there are two different compile targets in the same repo: the frontend (ElementaryUI) usually compiles to the wasm-embedded SDK, while the server side (a classic Vapor/Hummingbird backend) compiles to the normal native toolchain. In the Cloudflare Worker demo, though, even the "backend" runs as Wasm at the edge; there, both frontend and edge worker use the Embedded SDK — one setting in vite.config.ts covers both (swiftWasm({ useEmbeddedSDK: true })), and the forum post says it "builds Embedded Swift WebAssembly with 6.4.x and swift-build." So that's not two SDK variants but two Wasm targets in one repo: WebApp and Worker in Package.swift. The general pattern for picking an SDK by target:

bash
1# SDK choice by target — general pattern (IDs from `swift sdk list` output)
2# Note: the Cloudflare Worker demo uses the embedded SDK for both targets.
3swift build --swift-sdk swift-6.4.0-RELEASE_wasm # for a target that needs the full standard library
4swift build --swift-sdk swift-6.4.0-RELEASE_wasm-embedded # for the ElementaryUI frontend, small binary

These two commands summarize how the official documentation's "pick an SDK by target" principle looks in practice — one driven by the frontend's size constraint, the other by the backend's need for the full library.

An honest assessment: what it's good for, and what it isn't, as of September 2026

Don't overstate this. The official docs and Simon Leeb's statements paint this picture:

Reasonable as of September 2026:

  • Personal projects, demos, conference talks (presented in person at FOSDEM 2026).
  • Small, isolated Swift services in edge environments like Cloudflare Workers.
  • Experimental/research projects for teams that want to keep both backend and frontend in Swift.

Still early as of September 2026:

  • Critical, high-traffic production frontends. In the sharing developer's own words, NewCodable is still experimental, and Embedded Swift still has "a few usability quirks."
  • Teams waiting for the broad library/tooling support that mature ecosystems like React/Vue/Svelte offer.
  • ElementaryUI itself is a young project — the swift.org digest sums it up as "ElementaryUI is still young, with plenty left to build."

Swift 6.4's official Wasm SDK and the JavaScriptKit speedup are an important milestone — but not "production-ready." The right frame: a rapidly maturing ecosystem with experimental parts. If you've gradually adopted Swift Concurrency and Actors in production, the same caution fits ElementaryUI.

Use this table to sharpen your decision:

Scenario
Status as of September 2026
Conference demo / personal project
Fine — presented in person at FOSDEM 2026
Small, isolated Swift service at the edge (Cloudflare Worker)
Fine — the live demo shows this works
Internal team research/prototype
Fine, with caution
High-traffic critical production frontend
Still early — NewCodable and Embedded Swift are experimental
A project needing broad third-party library support
Still early — the ecosystem is small

This table isn't an absolute rule; it's a summary of Simon Leeb's statements in the forum and the official status of the projects — you need to interpret it according to your own risk tolerance.

GOLDEN TIP

The most valuable insight in this article

This tip holds the article's most important takeaway.

Easter Egg

You found a hidden gem!

There's a hidden detail in this section. Want to uncover it?

Reader Reward

If you followed this guide from start to finish, I've put together a practical checklist you should go through before starting to try Swift's browser side. The items below are concrete steps drawn from the sources cited in this article, ones you should verify before starting setup.

FAQ

Does Swift run in the browser?

Yes, via WebAssembly compilation. As of Swift 6.4 (released September 15, 2026), an official Wasm SDK is distributed directly through swift.org, and JS bridging performance via JavaScriptKit got noticeably faster in this release. Libraries like ElementaryUI build a SwiftUI-like declarative API on top of this infrastructure.

What is ElementaryUI, and how does it differ from Elementary?

Both belong to Simon Leeb, but for different goals: Elementary is a type-safe HTML-generating templating library on the server, integrated with Hummingbird/Vapor; ElementaryUI is a separate library that runs in the browser via WebAssembly, with SwiftUI-like state management. Elementary's own docs confirm this distinction directly: "check out ElementaryUI to run it in the browser."

How big is a Swift WebAssembly binary?

There's no definitive general number. The one concrete example is that the edge-side wasm fetch handler in the Cloudflare Worker demo is roughly 107 kB. ElementaryUI officially promises bundles "in kB, not MB" thanks to Embedded Swift, but doesn't give a separate number on its own site — you need to measure it in your own project.

Is full-stack Swift production-ready today?

Not fully. In the sharing developer's own words, NewCodable is experimental and Embedded Swift still has usability quirks. Swift 6.4's official Wasm SDK is an important step, but there's no "production-ready" declaration in the official sources — better to treat it as a rapidly maturing ecosystem with experimental parts. Trying it in a small, isolated module first (a single edge endpoint or internal tool) fits the general tone of the sources best.

Conclusion

The browser side of Swift is no longer an abstract promise: Swift 6.4's official Wasm SDK, JavaScriptKit's faster bridging, and libraries like ElementaryUI have made the missing half of full-stack Swift concrete. But assessing this ecosystem means keeping two things separate: that Elementary (server) and ElementaryUI (browser) are different projects, and the gap between "there's an official SDK" and "it's production-ready."

If you already know building a backend API with Swift Vapor and follow the server-side Swift ecosystem, trying ElementaryUI in a small side project is a sensible next step. If you've kept up with Swift 6.2 and the concurrency updates after WWDC26, the code side sitting on top of this Wasm chain won't feel unfamiliar. Our Swift Structured Concurrency and Swift Concurrency and Actors articles go deep into the same concurrency model that also applies in the browser.

Sources

Tags

#Swift#WebAssembly#ElementaryUI#Embedded Swift#Full-Stack Swift#Cloudflare Workers#Vapor
Muhittin Camdali

Muhittin Çamdalı

Senior Mobile Engineer

Senior Mobile Engineer with 12+ years of experience. I build mobile products with iOS, Flutter and React Native, working full-stack and AI-native.

iOS Development News

Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.

Your subscription starts when you open the link in the confirmation email and press “Confirm my subscription”. The newsletter keeps open/click statistics; you can unsubscribe anytime with one click. Privacy

Share