> For the complete documentation index, see [llms.txt](https://docs.hello-lisa.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hello-lisa.com/developers/guides/player-communication/type-definitions.md).

# Type Definitions

Every message described in the Message API Reference is available as a ready-made type definition, so you do not have to hand-write the protocol for each platform you ship on.

The definitions cover both directions — the messages the LiSA Player sends and the messages it accepts — and carry the same documentation you are reading here, inline in your editor.

<table><thead><tr><th width="220" valign="top">Platform</th><th width="240" valign="top">Distribution</th><th valign="top">Dependencies</th></tr></thead><tbody><tr><td valign="top">Web</td><td valign="top">npm package</td><td valign="top">None</td></tr><tr><td valign="top">React Native</td><td valign="top">npm package</td><td valign="top">None</td></tr><tr><td valign="top">iOS</td><td valign="top">Single Swift file</td><td valign="top">Foundation only</td></tr><tr><td valign="top">Android</td><td valign="top">Single Kotlin file</td><td valign="top"><code>kotlinx-serialization-json</code></td></tr></tbody></table>

***

### Web and React Native

Install the package from npm:

{% tabs %}
{% tab title="pnpm" %}

```sh
pnpm add @hellolisa/sdk-messages
```

{% endtab %}

{% tab title="npm" %}

```sh
npm install @hellolisa/sdk-messages
```

{% endtab %}

{% tab title="yarn" %}

```sh
yarn add @hellolisa/sdk-messages
```

{% endtab %}
{% endtabs %}

[**View on npm**](https://www.npmjs.com/package/@hellolisa/sdk-messages)

The package ships as ES modules with TypeScript declarations and has no runtime dependencies. It exposes every message as a discriminated union, so narrowing on `messageType` gives you exactly the properties that message carries:

```typescript
import {
  InboundMessageType,
  OutboundMessageType,
  createInboundMessage,
  parsePlayerMessage,
} from '@hellolisa/sdk-messages';

window.addEventListener('message', (event) => {
  if (event.origin !== PLAYER_ORIGIN) return;

  const message = parsePlayerMessage(event.data);
  if (message === null) return;

  if (message.messageType === OutboundMessageType.ProductAddToCart) {
    // productReference and variantReference are typed here.
    addToCart(message.productReference, message.variantReference);
  }
});
```

`parsePlayerMessage` accepts both shapes the player puts on the wire: the structured object delivered by `window.postMessage` on the web, and the JSON string delivered by the React Native bridge. It returns `null` for anything that is not a LiSA Player message, so it is safe to attach to a channel that carries other traffic.

***

### iOS

The Swift definitions are distributed as a single, self-contained file. It depends on Foundation only, so it drops into any UIKit or SwiftUI target without a package manager.

Download the current version:

```sh
curl -O https://cdn.jsdelivr.net/npm/@hellolisa/sdk-messages/platforms/ios/LiSAMessages.swift
```

[**Download LiSAMessages.swift**](https://cdn.jsdelivr.net/npm/@hellolisa/sdk-messages/platforms/ios/LiSAMessages.swift)

To pin a specific version, include it in the path:

```sh
curl -O https://cdn.jsdelivr.net/npm/@hellolisa/sdk-messages@0.1.0/platforms/ios/LiSAMessages.swift
```

Add the file to your target, then register the player's script message handler:

```swift
let configuration = WKWebViewConfiguration()
configuration.userContentController.add(self, name: LiSAPlayerBridge.scriptMessageHandlerName)

func userContentController(
    _ controller: WKUserContentController,
    didReceive scriptMessage: WKScriptMessage
) {
    guard let message = LiSAPlayerBridge.decode(scriptMessage.body) else { return }

    switch message.messageType {
    case .productAddToCart:
        guard let reference = message.product?.productReference else { return }
        cart.add(reference, variant: message.product?.variantReference)
    case .playerDismiss:
        dismiss(animated: true)
    default:
        break
    }
}
```

{% hint style="info" %}
**Swift Package Manager support is in progress.** We are preparing a distribution that will let you add the definitions as a versioned SPM dependency rather than vendoring the file. Until then, the single-file download above is fully supported and receives the same updates.
{% endhint %}

***

### Android

The Kotlin definitions are likewise distributed as a single file. It has no Android framework dependency, so it is equally usable from a plain JVM module or a Kotlin Multiplatform JVM target.

Download the current version:

```sh
curl -O https://cdn.jsdelivr.net/npm/@hellolisa/sdk-messages/platforms/android/LiSAMessages.kt
```

[**Download LiSAMessages.kt**](https://cdn.jsdelivr.net/npm/@hellolisa/sdk-messages/platforms/android/LiSAMessages.kt)

To pin a specific version, include it in the path:

```sh
curl -O https://cdn.jsdelivr.net/npm/@hellolisa/sdk-messages@0.1.0/platforms/android/LiSAMessages.kt
```

The file uses `kotlinx.serialization`, so add the plugin and runtime to your module:

```kotlin
// build.gradle.kts
plugins {
    kotlin("plugin.serialization") version "2.0.0"
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
}
```

It requires Kotlin 1.9 or newer. Register the player's JavaScript interface:

```kotlin
webView.addJavascriptInterface(object {
    @JavascriptInterface
    fun postMessage(payload: String) {
        val message = LiSAPlayerBridge.decode(payload) ?: return
        runOnUiThread { handle(message) }
    }
}, LiSAPlayerBridge.JAVASCRIPT_INTERFACE_NAME)
```

{% hint style="warning" %}
`@JavascriptInterface` methods are invoked on a background thread. Move to the main thread before touching your UI, as shown above.
{% endhint %}

{% hint style="info" %}
**JitPack and Maven Central distribution is in progress.** We are preparing an artifact that will let you declare the definitions as a Gradle dependency rather than vendoring the file. Until then, the single-file download above is fully supported and receives the same updates.
{% endhint %}

***

### Verifying an integration

The package includes `spec/fixtures.json`, a set of canonical wire examples covering every message the player accepts and a representative sample of the messages it sends.

Each platform's definitions are validated against this same file before release, which is how the four implementations are kept in step. You can point your own tests at it to confirm your handlers decode what the player will actually send:

```sh
curl -O https://cdn.jsdelivr.net/npm/@hellolisa/sdk-messages/spec/fixtures.json
```

Reference conformance checks are included alongside the native definitions, at `platforms/ios/FixtureCheck.swift` and `platforms/android/FixtureCheck.kt`.

***

### Versioning and compatibility

The definitions follow semantic versioning, and all four platforms share a single version number. A given version describes the same protocol everywhere, so an iOS and a web integration on the same version are guaranteed to agree.

{% hint style="info" %}
**New message types are added in minor releases.** Treat a `messageType` you do not recognise as a no-op rather than an error, and your integration will keep working across player updates without redeployment. The provided definitions already do this: both native decoders return `null` for unknown types, and the TypeScript unions are narrowed by an explicit `messageType` check.
{% endhint %}

Removing or changing the meaning of an existing message is a breaking change and will only ever happen in a major release, announced in advance.
