Skip to content

swiftwasm/JavaScriptKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,337 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

JavaScriptKit

Run unit tests Documentation

Swift framework to interact with JavaScript through WebAssembly.

Quick Start

Check out the Hello World tutorial for a step-by-step guide to getting started.

Overview

JavaScriptKit provides a seamless way to interact with JavaScript from Swift code when compiled to WebAssembly. It allows Swift developers to:

  • Access JavaScript objects and functions
  • Create closures that can be called from JavaScript
  • Convert between Swift and JavaScript data types
  • Use JavaScript promises with Swift's async/await
  • Work with multi-threading
import JavaScriptKit

// Access global JavaScript objects
let document = JSObject.global.document

// Create and manipulate DOM elements
var div = document.createElement("div")
div.innerText = "Hello from Swift!"
_ = document.body.appendChild(div)

// Handle events with Swift closures
var button = document.createElement("button")
button.innerText = "Click me"
button.onclick = .object(JSClosure { _ in
    JSObject.global.alert!("Button clicked!")
    return .undefined
})
_ = document.body.appendChild(button)

Learn more: JavaScript Interop Cheat Sheet

BridgeJS Plugin

Note: BridgeJS is experimental. APIs may change in future releases.

BridgeJS provides easy interoperability between Swift and JavaScript/TypeScript. It enables:

  • Export Swift to JavaScript - Expose Swift functions, classes, and types to JavaScript; the plugin also generates TypeScript definitions (.d.ts) for the exported API.
  • Import JavaScript into Swift - Make JavaScript/TypeScript APIs (functions, classes, globals like document or console) callable from Swift with type-safe bindings. You can declare bindings with macros in Swift or generate them from a TypeScript declaration file (bridge-js.d.ts).

For architecture details, see the BridgeJS Plugin README. For package and build setup, see Setting up BridgeJS in the documentation.

Exporting Swift to JavaScript

Mark Swift code with @JS to make it callable from JavaScript:

import JavaScriptKit

@JS class Greeter {
    @JS var name: String

    @JS init(name: String) {
        self.name = name
    }

    @JS func greet() -> String {
        return "Hello, \(name)!"
    }
}

JavaScript usage:

const greeter = new exports.Greeter("World");
console.log(greeter.greet()); // "Hello, World!"

Learn more: Exporting Swift to JavaScript

Importing JavaScript into Swift

Declare bindings in Swift with macros such as @JSFunction, @JSClass, @JSGetter, and @JSSetter:

import JavaScriptKit

@JSClass struct Document {
    @JSFunction func getElementById(_ id: String) throws(JSException) -> HTMLElement
    @JSFunction func createElement(_ tagName: String) throws(JSException) -> HTMLElement
}
@JSGetter(from: .global) var document: Document

@JSClass struct HTMLElement {
    @JSGetter var innerText: String
    @JSSetter func setInnerText(_ newValue: String) throws(JSException)
    @JSFunction func appendChild(_ child: HTMLElement) throws(JSException)
}

@JS func run() throws(JSException) {
    let button = try document.createElement("button")
    try button.setInnerText("Click Me")
    let container = try document.getElementById("app")
    try container.appendChild(button)
}

You can also generate the same macro-annotated Swift from a TypeScript file (bridge-js.d.ts). See Generating bindings from TypeScript in the documentation.

Learn more: Importing JavaScript into Swift

Try It Online

Use the BridgeJS Playground to preview what interfaces will be exposed on the Swift/TypeScript sides.

Examples

Check out the examples for more detailed usage patterns.

Contributing

Contributions are welcome! See CONTRIBUTING.md for details on how to contribute to the project.

Sponsoring

Become a gold or platinum sponsor and contact maintainers to add your logo on our README on Github with a link to your site.