How we built an interpreter for Swift

80 jacobx 36 9/4/2025, 4:39:03 PM bitrig.app ↗

Comments (36)

jacobx · 1d ago
Hi HN! Since we launched Bitrig (https://news.ycombinator.com/item?id=45041185), we've gotten questions about how it's able to run dynamically generated Swift code. I wrote up this post to answer that. Let me know if you want to know more about any aspects of it.
jgbuddy · 23h ago
Swift can already be used in REPL mode, not sure if it's accurate to say Swift is a strictly compiled language that a interpreter was developed for (see 'swift' command line executable). Seems misleading that this is not mentioned anywhere in the article.
lanza · 23h ago
That's a JIT. It uses the same compiler infrastructure but swaps out the AoT backend and replaces it with the JIT backend in LLVM. Notably, this blog post is targeting on-device usage which a custom JIT is not allowed. You can only interpret.
jgbuddy · 23h ago
I suppose you could argue the repl is not a true interpreter (parsing and executing from an AST)
firloop · 23h ago
++ had the same reaction as you. When I was picking up Swift, the interpreter was invaluable to check my understanding (although I nearly always needed to begin with `import Foundation` to have my code actually work).
localbuilder · 1d ago
This is fascinating work, amazing job to the team!

Does SwiftUI have properties that uniquely make this type of interpreted system possible, or could it also use UIKit under the hood? On the surface, it seems like UIKit might be more difficult since you’d probably need to parse all of the obj-c header files in addition to the .swiftinterface.

Very cool stuff, excited to follow along how you all develop the product!

jacobx · 23h ago
Thanks! Yes, it works just as well with UIKit. Fortunately Xcode can synthesize a .swiftinterface for Obj-C frameworks bridged into Swift, so we use that to generate a compiled interface for UIKit (and other Obj-C frameworks).
dfabulich · 23h ago
Could you use this to support hot module replacement? Replacing a SwiftUI view in a live app without restarting the process?
jacobx · 23h ago
Yeah you could! The only caveat is that either the whole app, or at least the part of the app showing the view you want to replace, would have to be running via the interpreter.

We're very interested in using the interpreter to improve the Swift developer experience in more ways like that.

fragmede · 17h ago
I bet you could make a ton of money just selling a better dev experience as an xcode add-on to Swift devs without even having the AI component. (But making an app on my phone with AI is unbelievably neat!).
ks2048 · 20h ago
It looks like it is in the App Store, so I guess my question is already answered - but I wonder if they had trouble or concerns getting it accepted.

Section 2.5.2 in "App Review Guidelines" (https://developer.apple.com/app-store/review/guidelines/):

    2.5.2 Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code which introduces or changes features or functionality of the app, including other apps. Educational apps designed to teach, develop, or allow students to test executable code may, in limited circumstances, download code provided that such code is not used for other purposes. Such apps must make the source code provided by the app completely viewable and editable by the user.
jacobx · 20h ago
Yeah there was definitely some back and forth about it before we were eventually approved.

In a sense, this isn't very different from what React Native does (run interpreted code that calls out into native code), just with Swift instead of JavaScript. There used to be JavaScript-specific requirements in the guidelines, but that has been loosened since Swift Playgrounds was released. Now there are Python IDEs, Jupyter Notebooks, and other apps running arbitrary code in the App Store.

Rohansi · 20h ago
The root of these restrictions is to try and prevent people from using dynamic code to bypass App Store reviews. If you're planning to change the functionality of your app then you must submit it for review.
ardit33 · 20h ago
yeah, this is the exception since it is a dev tool. Not sure Apple will approve a regular app doing it.
mtlynch · 22h ago
>Bitrig dynamically generates and runs Swift apps on your phone. Normally this would require compiling and signing with Xcode, and you can’t do that on an iPhone.

>To make it possible to instantly run your app, we built a Swift interpreter. But it’s an unusual interpreter, since it interprets from Swift… to Swift.

I can't understand what they're talking about, and I don't know if it's because I know too little about programming languages or if it's because they're using unusual semantics.

"a compiled language" makes no sense to me because the language itself doesn't determine whether it's compiled or interpreted. It's just a function of what compilers/interpreters exist. I could write an interpreter for C or a compiler for Python, but the languages themselves aren't compiled or interpreted.

I also don't understand what it means to "interpret" Swift to Swift. Do they mean they compile Swift to Swift (or the more modern "transpile" which means the same thing)? But it sounds like they're doing something dynamically at runtime, so it sounds more like decompiling machine code back to Swift, but the rest of the post doesn't match that interpretation.

jacobx · 22h ago
I refer to Swift as a "compiled language" because no officially provided interpreter exists for it.

Bitrig runs Swift apps which are dynamically generated by an LLM on the iPhone, despite the iPhone strict security provisions (e.g. inability to write executable pages of memory). The way we do this is by parsing the generated Swift code and mapping that to the compiled calls to the libraries that come in the OS. It's pretty weird, but we think it's worth it to get the ability to immediately render the generated code on the phone.

mtlynch · 22h ago
Thanks for the reply!

I think that's a more accessible explanation. Consider folding that into the article's introduction.

Is the idea that your interpreter is signed, and then you translate the user's arbitrary unsigned Swift code into calls to other already-signed code that ships with iOS?

nxobject · 21h ago
> I also don't understand what it means to "interpret" Swift to Swift. Do they mean they compile Swift to Swift (or the more modern "transpile" which means the same thing)? But it sounds like they're doing something dynamically at runtime, so it sounds more like decompiling machine code back to Swift, but the rest of the post doesn't match that interpretation.

My understanding is that this system walks the syntax, creates autogenerated wrappers to API structures/functions, and simply invokes them as the syntax directs – as it says, a "glorified FFI". It is not a full free-standing Swift runtime, but it's a very clever hack.

cryptonector · 14h ago
I thought Apple didn't allow any apps that do any kind of code generation or running of user or downloaded code.
kylemacomber · 14h ago
Apple has relaxed the guidelines for developer tools compared to the early days of the App Store. If you look today there are Python IDEs, Jupyter Notebooks, and various other apps that execute user generated code. The key guideline to be mindful of is 2.5.2.
koinedad · 18h ago
This is really cool, will definitely try it out. Does it allow you to move this to your computer later and actually publish the apps? What’s the end goal here?
jacobx · 17h ago
Yep! You can always export your code to take it to your computer.

We also have functionality in bitrig to build your app and send it to App Store Connect so you can deploy it on TestFlight.

nomel · 21h ago
Very very neat.

What's the performance like?

jacobx · 20h ago
There's definitely a cost: everything is type-erased and there's a lot more indirection than there would be if the code was compiled. But you usually don't hit performance issues because most app code (especially in the UI) is just a thin layer calling into the OS frameworks. The framework code does the heavy lifting and is all compiled.

The places you can hit performance issues are things like when the app itself has a tight loop that's doing a lot of work.

flykespice · 19h ago
You could do the same thing CPython does: compile common patterns of code into specialized macro-instructions to reduce the interpreter's penalty.
bartvk · 20h ago
Do you plan to support iPad? If so, how high is it on the backlog?
jacobx · 19h ago
We have a Mac app that we're beta testing with our existing subscribers. Is there a reason you want this on iPad instead of the Mac?
ushakov · 22h ago
Do you think you can make it run in Jupyter as a Kernel?
liuliu · 20h ago
There are Jupyter kernels for Swift that uses REPL mode of Swift lldb. I used to do it but obvious right now it is not a priority: https://github.com/liuliu/swift-jupyter
jacobx · 22h ago
That's not really been something we'd been considering, but yeah I think we probably could. We're primarily using the interpreter to render SwiftUI views, but it supports running arbitrary Swift expressions or statements.
daft_pink · 21h ago
Is apple going to block this?
zapzupnz · 20h ago
It's already on the App Store and meets all their criteria for a development app, so I can't see any reason why it would be blocked.
kelvinjps10 · 1d ago
Your website won't let me scroll to see the content on Firefox Android
jacobx · 22h ago
I just pushed a change that should fix scrolling on Android browsers.
jacobx · 23h ago
Thanks for letting us know! We're investigating now.
pjmlp · 23h ago
Same on Android Chrome.