# elementary-ui: a SwiftUI style frontend that compiles to WebAssembly

> ElementaryUI brings the declarative rendering approach of the Elementary server-side Swift library to reactive apps that run in the browser through WebAssembly, with @State, @Environment and CSS based animations, and it is still an early project whose APIs are expected to change.

**elementary-swift/elementary-ui** — Build SwiftUI-style apps that run in the browser

- Repository: https://github.com/elementary-swift/elementary-ui
- Website: https://elementary.codes
- Stars: 522 · Forks: 16
- Language: Swift
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/elementary-swift-elementary-ui

## A SwiftUI shaped layer over a declarative HTML renderer

ElementaryUI is the browser-side counterpart to Elementary, the server-side HTML rendering library for Swift. The stated idea is to carry Elementary's declarative approach over to reactive Swift applications running directly in the browser. That framing explains the shape of the API. Views are values that describe structure, and a runtime applies them to the DOM, in the same spirit as the way Elementary builds HTML on a server. The features list adds a SwiftUI-inspired syntax, so a developer moving from native Swift sees familiar property wrappers and a body-based view definition rather than a template language. The whole thing runs through WebAssembly, which means the browser executes compiled Swift rather than downloading a script, and the project claims support for Embedded Swift so the resulting wasm bundles are measured in kilobytes rather than megabytes.

## The counter example shows the view model in twelve lines

The README opens its feature section with a complete component, and it is the fastest way to see the model in action:

```swift
@View
struct Counter {
    @State var count = 0
    
    var body: some View {
        div {
            p { "Count: \(count)" }
            button { "Increment" }
                .onClick { count += 1 }
        }
    }
}
```

Three things stand out. The view is a struct marked with @View, and it exposes a body property, which is the SwiftUI shape. The state lives in a @State property wrapper and is mutated inside an event handler, again as in SwiftUI. But the elements are lowercase HTML tags used as functions: div, p and button, each taking a closure for their children. There is no separate builder or DSL, and there is no name collision with the Swift standard library to solve in this example. The modifier .onClick attaches behaviour to an element the way a framework like that would. It reads as SwiftUI with the body renamed, and the README notes in passing that migrating from var content to var body was one of the recent changes.

## Reactivity comes from @State, @Environment and @Reactive

State management is described as built in, with three property wrappers named in the feature list: @State, @Environment and @Reactive. @State holds local mutable state, which is what the counter example uses. @Environment reads values from an ambient context passed down the view tree. @Reactive is the one that reaches beyond the view itself, and it connects to a ReactiveObject type that the project provides, along with the Environment machinery to pass those objects down. The work list shows this was hard won: there is a crossed-out entry about different handling of environment, noting that individual reactivity was needed, and another about @Environment with an optional ReactiveObject not building in embedded mode. The feature list describes automatic state management, but the history in the same README makes clear that the model is still being reshaped. A @Reactive object that can be observed and passed through the environment is the mechanism a real application would depend on most, and it is the one to test early.

## CSS does the animation work, including automatic FLIP transitions

The animation system is CSS based, and the feature list calls out automatic FLIP transitions as part of it. FLIP means you measure a change in position and size, invert it, then play it, which is how a framework can move an element between layouts without repainting the whole page. Doing that from CSS rather than from JavaScript keeps the animation off the main thread and out of the compiled wasm bundle. The transition catalogue in the work list is long enough to be informative: entries for transitions and animations, CSS-based easing applied through the Web Animations API, better control over animations, and an auto-flip animation for custom CSS values triggered on value changes. Two entries are marked as still open, an animateContainerLayout modifier and combined and reversible transitions. The list also records that an earlier DOM approach based on replaceChildren failed to preserve animations and nodes, and that this has since been fixed, though it is a reminder of how recently the diffing ground was settled. Animation fidelity is the feature area where the design was least settled for longest.

## Vite drives the dev server and the bundle stays small

Development is described as Vite powered, with a fast dev server and hot reload for rapid iteration. That choice matters for a WebAssembly project because the standard toolchain for Rust and JavaScript is built around Vite plugins, and the same pipeline can serve Swift compiled to wasm. Small output is the other half of the story. The claim is that Full Embedded Swift support means kilobyte sized wasm bundles instead of megabytes, which follows from compiling a constrained subset of Swift rather than the full standard library. The embedded direction shows up throughout the work list, with entries for making printing work without WASI by piping putchar through to JavaScript, for a simple build with SwiftPM using wasm-ld, for the _Concurrency module and for Synchronization with Mutex, and for embedded friendly Browser APIs such as Storage and History. An embedded waitlist section lists Codable 2.0 as still needed, with the serialization macros described as on the horizon, so JSON handling is not settled.

## Views can ship as typed custom elements

The final feature in the list is web components, and it is aimed at a different use case from everything else here. Rather than running a whole application inside ElementaryUI, you can publish a single ElementaryUI view as a typed custom element, with the optional ElementaryWebComponents library providing the mechanism. That lets a Swift view live inside an otherwise conventional web page, or inside a dashboard that is not written in Swift at all, and it is a realistic entry point for a team that wants one component in Swift rather than a whole frontend. The example application referenced in the README is Swiftle, and the repository carries two example directories, Examples/Basic and Examples/Swiftle, plus a Benchmarks directory and an IntegrationTests directory. The separation of Basic from Swiftle suggests a minimal program and a fuller demo, and the benchmarks directory suggests the bundle size claims are at least partly measured rather than asserted.

## Swift 6.4 and the WebAssembly SDKs are a hard prerequisite

The requirements are stated without ambiguity. Swift 6.4 or later with matching Swift SDKs for WebAssembly from swift.org is required, and the project sits on the swift.org WebAssembly SDKs, JavaScriptKit and Elementary. The SDKs are the awkward part for anyone arriving from another language, because a Swift SDK for WebAssembly is not a single compiler download but a toolchain plus a target SDK that has to match the Swift version. The README links the swift.org install page rather than giving a command, so the setup is documented on the Swift site rather than in this repository. The README also does not document a build command, a package manifest step or a local dev server invocation, so the path from a clone to a running page is not described here. The guide and get started pages at elementary.codes and the API documentation on Swift Package Index are the places the README points to for those steps.

## The work list is the honest roadmap, and it is long

The Work In Progress section is unusual and genuinely useful, because it lists what has been solved and what has not, with struck-through entries marking finished work. Done items include the identity system and list diffing, lifecycle events, the @State system, typed event handlers, the @Environment system, dependencies on versioned packages so the build works without unsafe flags, model bindings for inputs such as binding a @Binding to a text box or a checkbox, view value comparing, transitions and animations, automatic FLIP animations for certain layout changes, and splitting JavaScriptKit into its own module. Still open: a router implementation, probably in an extra module, multi-select bindings for options, radio buttons and tagged checkboxes, more unit testing around FLIP handling, animations and reactivity, a preference system that bubbles values up, and isolation and @MainActor handling for reusable types. Several of those are prerequisites for an ordinary application.

## Single author, Apache 2 licence, and an explicit warning about stability

The README states plainly that ElementaryUI is an actively developed passion project in its early days, that readers should expect sharp edges, that APIs may change, and that things may break while the author balances performance, ergonomics and feature set. The stated ambition is to make Swift a first-class option for building serious web applications and to keep the project healthy for the long run. The repository is not archived and the last push was on 2026-10-19, with releases 0.8.0 on 2026-09-29, 0.7.0 on 2026-08-24 and 0.6.1 on 2026-08-22, so the version numbers are still pre-1.0 and moving quickly. The project is sponsored through GitHub Sponsors. Licensing is Apache 2 for the package generally, with a LICENSE file and a separate LICENSE-swift_org.md in the repository root, which points to code derived from the Swift project carrying its own licence terms. The README begins a section on derived code by referring to a Reactive component, and that section is cut off, so the exact attribution for the reactive layer is not readable from the source.

## Conclusion

Adopt elementary-ui if your team already writes Swift and wants to ship a browser frontend without learning a JavaScript component model, and if you are willing to track an API that the author says may change as the project balances performance against features. It is a poor fit for production work that cannot tolerate sharp edges, for a team without Swift 6.4 and the matching WebAssembly SDKs, or for anyone who needs a router, multi-select bindings or wider unit testing coverage today. Before building on it, read the guide at elementary.codes, try the Swiftle example app, and confirm your JavaScript interop needs fit what ElementaryWebComponents and JavaScriptKit currently expose.

## FAQ

### What is ElementaryUI and what does it build on?

ElementaryUI brings the declarative approach of Elementary, the server-side HTML rendering library for Swift, to reactive Swift applications running in the browser. It builds on the swift.org WebAssembly SDKs, JavaScriptKit and Elementary.

### What does it take to build an ElementaryUI project?

Swift 6.4 or later with matching Swift SDKs for WebAssembly from swift.org. The README does not give a build command, so the setup steps are documented on the Swift site and in the guide at elementary.codes.

### Is ElementaryUI ready for production use?

The README calls it an actively developed passion project in its early days, and says to expect sharp edges, APIs that may change and breakage while performance, ergonomics and feature set are balanced. The latest listed release is 0.8.0 from 2026-09-29.

### Can ElementaryUI views be used inside an existing web page?

Yes. The optional ElementaryWebComponents library publishes ElementaryUI views as typed custom elements, so a Swift view can be embedded in a page that is not written in Swift.

### Which licence applies to ElementaryUI?

The package is generally licensed as Apache 2, with a LICENSE file and a separate LICENSE-swift_org.md in the repository root covering derived code from the Swift project.

## Sources

- [elementary-swift/elementary-ui on GitHub](https://github.com/elementary-swift/elementary-ui)
- [License: Apache-2.0](https://github.com/elementary-swift/elementary-ui/blob/main/LICENSE)
- [Project website](https://elementary.codes)
- [README](https://github.com/elementary-swift/elementary-ui/blob/main/README.md)
- [Releases](https://github.com/elementary-swift/elementary-ui/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/elementary-swift-elementary-ui
