Is there a way to use Swift script files as an embedded scripting language within a macOS app?
The idea is to allow users to write their own Swift-based scripts to control the app’s behavior.
Background:
Hammerspoon uses Lua as its embedded scripting language. I’m wondering whether it’s possible to replace Lua with Swift for user scripting — similar to how JavaScriptCore enables JavaScript scripting.
If in your case it's acceptable for script authors to compile Swift code to Wasm before executing their scripts, I wonder if WasmKit could be a solution?
The AudioWorkstation example in the swiftlang/swift-for-wasm-examples repository demonstrates a Hummingbird server that loads and executes audio plugins written in Swift. This example project was demoed at SwiftLeeds, so you can check out the recorded talk to see it an action.
WasmKit doesn't require a server of course, it's an interpreter (no JIT) that can run on any platform supported by Swift.
Thank you for this talk, @Max_Desiatov, it was quite illuminating!
This would allow one to develop widely multi-platform apps with a plugin-based architecture that can even run on restricted platforms like iOS and (within plugin API limitations) support any language at the discretion of the plugin author, as well as come with built-in security precautions, without forcing one to rely on OS-specific solutions like XPC and process sandboxing.
The base assumption for this would be that each target OS has a highly optimized WASM interpreter, which would be the basis for the performance cost of such an app architecture.
This is a critical point IMO. Lua can execute code directly. You can do the same thing with JavaScriptCore. To get this facility in Swift / Wasm you’d need to embed the Swift compiler. That’s certainly doable, but it’s also not trivial.
FWIW this recently came up on DevForums, and you can see my reply there.
Yes, you can use Swift as an embedded scripting language in a macOS app using Swift's runtime and SwiftSyntax or LLBuildSwift. However, it’s complex compared to using AppleScript or JavaScriptCore.