Swift to JavaScript transpiler - possible?

A transpiler between any two turing complete languages is always possible. That doesn't mean it's easy, practical, or worthwhile.

At the bare minimum, you can guarantee that a Swift to JS transpilation is possible because you can compile the Swift to x64 machine code, and use a JS disassembler/decompiler to produce JS. However, the resulting code will be really shit JS.

To make a good conversion you need to account for all the intricate best practices of one language, and what their equivalents are in the other language. That's a huge undertaking, that must be done twice (one in each direction) for any two pairs of languages you'd like to transpile. There's a reason transpilers are so uncommon, and usually crap.


One has to wonder if it makes any sense to write a Swift to JavaScript transpiler, as the languages don't map 1:1. There are many pitfalls besides the ones you've mentioned (e.g. inout parameters or function overloading). There's already some viable alternatives, such as using Haxe/Kotlin to transpile both to JavaScript and Swift, or developing cross-platform apps in Xamarin/React Native.

That being said, both languages share many common best practices as well as have a rather substantial feature overlap (e.g. closures/assigning functions to variables). I don't think there are any features that would be impossible to transpile, although some resulting code could be quite messy.

There is also a distinct advantage over using e.g. Kotlin - you would be able to grab an existing Swift project and transpile it into JS, without having to make the decision to write in Kotlin beforehand. And it's one language less you need to learn.

I have started a transpiler project with live preview myself that I think is an improvement over ShiftJS. It will indeed handle the cases you've mentioned (including passing arrays/dictionaries by value).

Still, it's work in progress, as I haven't even got around to implementing support for classes yet. The inout parameter is one of the things that are bugging me, although there might be an (ugly) solution.

var a = 2
func incr(_ a: inout Int) {
    a += 1
}
incr(&a)//a now equals 3

could be transpiled to something like

var a = 2
function incr(a) {
    a.set(a.get() + 1)
}
incr({get: a => a, set: val => a = val})//a now equals 3!

How's that for a hack!

Is it possible to write a 1:1 Swift to JS transpiler? I'm leaning towards yes, but the jury is out - and it's quite possible I will eventually run into a feature that's impossible to replicate in JS.