💥 Check out this insightful post from Hacker News 📖
📂 **Category**:
📌 **What You’ll Learn**:
App development has always been harder than web development for LLMs. Apps tend to have platform style norms and layouts, and they need to look and feel a certain way. People can feel when an app is “native” and crafted for their device. Plus, the web is open and universal in a way apps and app stores typically are not, which means LLMs have comparatively less data in their training sets.
Many vibe-coding platforms have tried to solve the problem by, essentially, compromising. They generate apps using Expo/React Native, Flutter, or even just webviews. But we found none of those approaches provides an optimal user experience; you’re always sacrificing something, whether it’s cross-platform compatibility, native widgets, performance, or features.
We made Dactyl to help you build native apps without those compromises.
Today we present the inner workings of Dactyl’s cross-platform SwiftUI renderer—a Wasm port of the iOS simulator—and how we bring the Apple ecosystem to Android and the web.
iOS previews on the web
We chose Swift as the primary language in Dactyl because of its simplicity and well-defined layout semantics. In fact, Dactyl was initially designed to be a development platform exclusive to iOS.
Previewing an iOS app without a Mac normally means renting one and streaming a real simulator back: a boot, an install, and a launch before you even see the app, metered for as long as you keep working.
That approach only scales as far as your budget allows. But what if you could have a simulator inside your browser? Well, that would scale infinitely. So we built it.
Dactyl’s preview engine is a reimplementation of SwiftUI in Swift, plus the frameworks apps reach for. Plenty of modules are implemented, including Charts, SpriteKit, SceneKit, RealityKit, ARKit, MapKit, StoreKit, MusicKit, PencilKit, WidgetKit, UIKit, CoreGraphics, Metal and Vision.
Apps are built to Wasm and linked against our SwiftUI instead of Apple’s.
The engine emits a binary stream of draw commands into its own linear memory, and the protocol is read by a JavaScript host that paints it on a Canvas2D.
Layout is fully resolved before any command is written, and a reconciler keeps the view tree between passes, marking dirty only the views that read something live this frame: animations, scrolling containers and the like. The host rasterizes each layer once onto an offscreen canvas keyed by a hash of its contents, then composites on later frames.
All of this means Dactyl can render complex SwiftUI layouts smoothly and efficiently, directly in the browser, without any installation step or extra devices. (But it can handle all of that, too.)
Dynamic linking Swift
SwiftWasm links statically. That is not ideal for us, because the engine is ~100 MB and a static link means linking and shipping hundreds of megabytes to the browser on every edit.
The app itself is much smaller, so we split the build. The engine and the standard library link once as a base module, content-addressed, so the browser fetches and compiles it one time and keeps it across edits.
Your app compiles on its own as a position-independent side module, 8 KB to 300 KB. At load, it’s placed at a runtime memory offset, its imports are bound to the base’s exports, and its Swift type metadata is registered with the base’s runtime. The swap happens under the running app. @State is snapshotted before and restored after, so scroll position, text fields, and app data are preserved across edits.
examples/weather/ContentView.swift89 Color(red: 0.42, green: 0.69, blue: 0.95)],
36 KB0.28 s


Android: Jetpack Compose
On Android, the engine compiles natively for aarch64-unknown-linux-android24 with the Swift Android SDK into a shared library. A Jetpack Compose host loads it and drives it over JNI. The command stream is read directly out of native memory, no copy, so the Compose host decodes the same bytes the browser does.
Where the browser host paints a control onto the canvas, the Compose host mounts a real Material switch, text field or date picker at that rectangle, with native focus, ripple, keyboard, and accessibility.
Both phones below are running the same 71-line SwiftUI source: the left is a booted iPhone simulator; the right is the APK on an Android emulator.


PICKER segmentedUIKit segmented control vs Material segmented button, checkmark
SF Symbols and Material Symbols are different icon sets with different names, so one generated mapping table covers both hosts. Compose’s density is pinned to the engine’s layout scale rather than the device’s, so controls land exactly on the rectangles the engine resolved. Per-app APKs don’t rebuild the host. The shared library, app name, and icon are stamped into a prebuilt template.
iPad is the same engine with a different device descriptor. The viewport, safe areas and size classes change, and SwiftUI’s adaptive layouts do the rest.
Development loop



agents on the engine’s framework source4 editing right now
Charts/ChartRender.swiftqueuedSwiftUI/Core/ShapeStyle.swiftqueuedSwiftUI/Modifiers/TextLayoutModifiers.swiftqueuedSwiftUI/Generated/LayoutParams.swifteditingSwiftUI/Core/ColorGradient.swifteditingCharts/ChartPlots.swifteditingSwiftUI/Modifiers/ScrollModifiers.swiftqueuedSwiftUI/Core/SemanticColors.swiftdoneUIKit/GestureScrollControl.swifteditingCharts/ChartViewModifiers.swiftdoneSwiftUI/Core/Animatable.swiftqueuedCoreGraphics/CGPath.swiftdone…and the rest of the red
re-render, diff again, until they agree
Development of the engine is highly automated using a fleet of agents. The agents use Apple’s SDK artifacts to build an API reference. We then render a variety of scenes in a booted iOS simulator, capture them, and diff the engine’s output against them pixel by pixel. When a new iOS ships, we re-render the source of truth against the new simulator.
Screenshots miss anything that moves, so a filmstrip runner drives a virtual clock: it ticks the engine in fixed steps, samples frames on a timeline, and fires synthetic taps and key presses at exact moments.
For games we diff states and events, like where a character actually is onscreen at frame N. Our engine and the real simulator dump the same per-frame node schema (position, rotation, scale, alpha, physics velocity), and the trajectories are diffed per node per frame.
Each diff is handed to a visual large language model that identifies issues, then fans out agents to edit the engine’s framework source until the diff is under a threshold. This is a surprisingly effective process, and it gets us very close to implementing a continuously moving framework like SwiftUI.
See Dactyl in action
That’s it for the technical details behind the scenes. We haven’t even touched on how Dactyl helps you install your apps on your device for testing, though, or how it guides you through listing apps on the App Store. But maybe it’s best if you see for yourself.
Just describe an app, and everything we’ve described here will build it, live in your browser. Give Dactyl a try now.
🔥 **What’s your take?**
Share your thoughts in the comments below!
#️⃣ **#Dactyl #works #Dactyl**
🕒 **Posted on**: 1787945420
🌟 **Want more?** Click here for more info! 🌟

