Skip to content

BridgeJS: Declarative JS interop #290

Description

@kateinoigakukun

Motivation

Current JS interop system, JavaScriptKit, has two main issues:

  • It's based on dynamic, string-based method calls and properties access.
    • It's not type-safe and can easily lead to runtime errors even if the JS side is written with types (like TypeScript).
    • There are non-trivial performance penalties due to the dynamism.
  • There is no easy way to expose Swift functionalities to JS side.
    • Developer productivity
    • We need to write so many boilerplates to set up closures and type conversions for each exposed function.
    • Has some performance penalties too.

Current Status

Try on our playground https://swiftwasm.org/JavaScriptKit/PlayBridgeJS/

High-level API

Given the following interface:

// bridge.d.ts
export interface CanvasContext {
  drawRect(x: number, y: number, width: number, height: number) => void;
}

// App.swift
public struct App {
    let context: CanvasContext
    @ExposeToJS
    init(context: CanvasContext) {
        self.context = context
    }

    struct PointerEvent {
        let x: Int
        let y: Int
        let pointerId: Int
    }

    @ExposeToJS
    func feedPointerEvents(_ events: [PointerEvent]) {
        ...
        context.drawRect(...)
    }
}

Then SwiftPM Build Plugin or standalone CLI tool should generate:

  1. Swift and JS bridging glue code to expose CanvasContext to Swift
  2. Swift and JS/TS bridging glue code to expose App methods to JS/TS

Breakdown

  • Produce ES Module package with some instantiation JS code and .wasm
    • Check if the current SwiftPM Plugin API has enough capability to produce a JS package
    • Packaging Plugin #288
  • Prototype a tool to expose Swift interface to TS/JS
    • Check if we can process it without swift-syntax dependency (to avoid longer build time)
    • Performance benchmark
  • Prototype a tool to import TS interface to Swift
    • Check if TypeScript Compiler API can handle third-party JS packages
    • Performance benchmark

Other Languages

Activity

  1. converted this from a draft issue on Mar 10, 2025
  2. changed the title [-]Declarative JS interop[/-] [+]BridgeJS: Declarative JS interop[/+] on Aug 13, 2025
  3. 4 remaining items

  4. moved this from In progress to Done in Yuta's projecton Feb 14, 2026
  5. moved this from In Progress to Done in Swift for Wasmon Feb 14, 2026
  6. unpinned this issue on Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions