The goal was not to be fully compatible with Apple Swift yet, but to build a complete compiler pipeline that can run Swift code instantly in the browser with no server and no LLVM dependency.
Current status: - Swift standard library tests: 750 / 750 passing - Compile + run time in browser: ~0.1 ms per iteration - No server, everything runs client-side - About 70k lines of C code - Zero external dependencies
The main motivation was educational: I wanted a Swift playground that runs instantly, works offline, and shows how a compiler pipeline works end-to-end.
I’d love feedback from compiler / Swift / WASM people.
Thanks for the test case! Just pushed a fix. Array now has proper value semantics. var b = a makes a deep copy via __array_create_n. Try it on miniswift.run!
It doesn't respect CustomStringConvertible or CustomDebugStringConvertible. I have no idea where it gets the string for struct instances from, but this seems to print "4200" for some reason:
struct Foo: CustomStringConvertible, CustomDebugStringConvertible {
var description: String { "description" }
var debugDescription: String { "debugDescription" }
}
print(Foo())
as Any / as any P / etc seems to change how enums are printed:
enum Foo {
case bar
}
print(Foo.bar) // "bar"
print(Foo.bar as Any) // "0"
I also can't seem to surface any compiler errors. Various forms of invalid code, such as an empty switch, single quotes, and mismatched parentheses, compile successfully. This code for example should give at least three syntax errors, but instead prints "0":
let x := 'a'
print((x)
and it prints something different if you remove the colon, and a third thing if you add Int between the colon and the equals sign. (Can you guess what? I certainly couldn't!)
I still think this is a neat concept, but it seems like it has a long way to go.
You're right about print, right now it's very primitive and mostly does type-based printing (Int, String, etc.) and doesn't yet respect CustomStringConvertible / CustomDebugStringConvertible. The protocol conformance machinery exists in the compiler, but print() doesn't use witness tables yet. That's something I definitely want to fix.
The enum as Any behavior is also related. When you cast to Any it gets boxed and what print currently sees is basically the raw tag value, so it prints 0 instead of "bar". Same root problem: print isn't doing proper protocol-based dispatch yet.
The parser errors are on me. The parser is currently very permissive and tries to keep going even when the syntax is wrong, so a lot of invalid code ends up compiling and producing weird results instead of proper errors. Tightening error reporting and making the parser less forgiving is pretty high on my list.
MiniSwift is still very much a “happy path” compiler right now – it handles valid code much better than invalid code. Error reporting, diagnostics, and some runtime behaviors like print are definitely areas that need a lot more work.
Really appreciate you trying to break it. That's exactly the kind of feedback I need.
Honestly this is starting to feel like one of those JavaScript “good parts / bad parts” experiments where you poke the language and weird things fall out. The difference is I am definitely not Brendan Eich
Jokes aside, thanks for finding these, this was actually very helpful. I just pushed a fix and deployed it.
Three parser improvements just went live:
1 + * 2 now gives “expected expression after operator” instead of silently producing garbage
'a' now reports “single-quoted string is not allowed; use double quotes”
Operators are only accepted as identifiers in function argument context (so things like reduce(0, +) still work)
You can try the same invalid examples again on miniswift.run they should now produce proper diagnostics instead of strange numbers.
Thanks for testing! The overload case (f("4") → "bye") actually works correctly. The crash you saw was likely a WASM runtime trap from a previous run that left the page in a broken state.
Just deployed a fix: runtime errors are now caught cleanly and the playground recovers without needing a refresh. Try it again on miniswift.run.
For bug reports, I'll set up a GitHub Issues page soon, for now this thread works great. Your reports have already led to 3 fixes deployed today!