Skip to content

Embedding on Web

Graphyn targets both Kotlin/JS (webpack-based) and Kotlin/WASM (wasmJs). WASM is the recommended target for production — it is faster at runtime, but requires a browser that supports WebAssembly GC (Chrome 119+, Firefox 120+, Safari 17.4+).


Which target to use

JS (js { browser() }) WASM (wasmJs { browser() })
Browser support All modern browsers Chrome 119+, Firefox 120+, Safari 17.4+
Startup time Faster Slightly slower (WASM compilation)
Runtime speed Good Better
Bundle size Larger Smaller
Recommended Fallback / broad compat Production default

Adding the dependency

// shared/build.gradle.kts
kotlin {
    js { browser() }

    @OptIn(ExperimentalWasmDsl::class)
    wasmJs { browser() }

    sourceSets {
        commonMain.dependencies {
            implementation("io.github.ronjunevaldoz:graphyn-editor:0.1.0")
        }
    }
}

Entry point

// webApp/src/wasmJsMain/kotlin/Main.kt

fun main() {
    CanvasBasedWindow(title = "My Workflow Editor") {
        // `App()` (and `GraphynEditorShell`) ship in the published `graphyn-editor` library.
        // `GraphynApp` — the full standalone launcher + template catalog — lives in the app
        // module and is not published, so embedders use the shell directly.
        App()  // or your own GraphynEditorShell wrapper
    }
}

For Kotlin/JS the entry point is the same — CanvasBasedWindow works on both targets.


Content Security Policy

If your deployment has a CSP header, you need to allow WebAssembly evaluation for the WASM target:

Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval';

The JS target requires 'unsafe-eval' instead (less restrictive — prefer WASM for CSP-sensitive deployments).


Outbound HTTP from the browser

The io.http_request executor runs in the browser context. Requests are subject to CORS — the target server must return appropriate Access-Control-Allow-Origin headers. For production, proxy outbound requests through your own backend to avoid CORS issues and to keep credentials server-side. See Remote Execution.


Offline support

Graphyn itself has no offline/service-worker integration. If you need the editor to work offline, ensure your bundled assets are cached by a service worker and that your persistence layer (see Persistence) handles the case where the backend is unreachable:

LaunchedEffect(state.workflow) {
    val wf = state.workflow ?: return@LaunchedEffect
    delay(1_000)
    try {
        api.save(wf)
    } catch (e: NetworkException) {
        localStorage.setItem("draft-${wf.id}", wf.toJson())
    }
}

Keyboard shortcut conflicts

Browsers intercept some key combinations (e.g., Cmd+S for save, Cmd+W to close tab). Add event.preventDefault() in your host page if you need to intercept these before the browser sees them. The Compose event loop handles this inside the canvas — shortcuts that land in the canvas work without extra configuration.