# Packages

> The Lia SDK as npm packages. A typed bridge, a tree-shakeable SDK, and bindings for React, Preact, Vue, Svelte, Solid, Angular and web components. From the Lia developer docs: https://docs.lialabs.org/packages

The [script tag](/reference/sdk) is the quickest way in. If your app has a build step, the npm packages give you the same SDK with TypeScript types, imports you can tree-shake, state that fits your framework, and a pretend Lia for building outside the app.

## Which package

| Package | Use it for |
| --- | --- |
| [`@lia-labs/sdk`](/packages/sdk) | Any app with a bundler, with or without a framework. |
| [`@lia-labs/sdk-react`](/packages/react) | React: hooks like `useInit`, `useMainButton`, `useBackButton`. |
| [`@lia-labs/sdk-preact`](/packages/preact) | Preact: the same hooks. |
| [`@lia-labs/sdk-vue`](/packages/vue) | Vue 3: composables returning refs. |
| [`@lia-labs/sdk-svelte`](/packages/svelte) | Svelte 4 and 5: stores. |
| [`@lia-labs/sdk-solid`](/packages/solid) | Solid: accessors and `create*` primitives. |
| [`@lia-labs/sdk-angular`](/packages/angular) | Angular 17 and later: `inject*` functions and signals. |
| [`@lia-labs/elements`](/packages/elements) | Any page, no framework: `<lia-main-button>` and friends. |
| [`@lia-labs/bridge`](/packages/bridge) | The low level messages, for building your own layer. |

Each framework package re-exports the whole SDK, so one import is enough:

```sh
npm install @lia-labs/sdk @lia-labs/sdk-react
```

```tsx
import { pay, useInit, useMainButton } from '@lia-labs/sdk-react';
```

## How they fit

<ol class="flow">
<li><b>@lia-labs/bridge</b><span>Lia's frame messages, typed: <code>request('pay', { productId })</code>, <code>on('theme', …)</code>. And <code>mockLia()</code>, a pretend Lia for building in a desktop browser.</span></li>
<li><b>@lia-labs/sdk</b><span>Every feature as a named export (<code>init</code>, <code>pay</code>, <code>mainButton</code>, <code>cloudStorage</code>…), with the same checks and error codes as the script tag. Its state (theme, language, viewport…) is a set of small observable values.</span></li>
<li><b>Framework packages</b><span>Thin: they turn those values into hooks, refs, stores or signals, and tie Lia's buttons to your components, shown while mounted and hidden after.</span></li>
</ol>

## State you can watch

The SDK's state is a set of `Readable` values: `get()` reads one now, and `subscribe(listener)` hears each change (with the new and old value) and returns a function that stops listening. They update from Lia's events after `init()`.

| Value | Type |
| --- | --- |
| `player` | `{ id, name }` or `null` before `init()` |
| `mode` | `"test"`, `"live"` or `null` |
| `language`, `rtl` | The person's language in Lia, and whether it reads right to left |
| `colorScheme`, `themeParams` | `"light"` or `"dark"`, and Lia's colours |
| `viewport` | `{ height, expanded }` |
| `safeArea`, `contentSafeArea` | `{ top, bottom, left, right }` in px |
| `display`, `isFullscreen` | How the app opened, and whether it's edge to edge |
| `startParam` | What it was opened with, kept current while open |
| `soundOn`, `notificationsAllowed`, `notificationsAvailable` | The person's choices |
| `initialized` | Whether `init()` has answered |

Each framework package has a matching hook, composable, store or signal for each.

## The script tag still works

`https://api.lialabs.org/sdk/lia-apps-v1.js` (the global `Lia`) is unchanged. Use it or the packages on a page, not both: both listen for Lia's answers on the same channel, and the second one to load can't.

## Versions

The packages speak the protocol of SDK 1.6.0. A Lia app older than a feature answers `unknown_method`; see the [changelog](/changelog).
