> ## Documentation Index
> Fetch the complete documentation index at: https://crosslink.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

> How to install and set up Crosslink

## Requirements

* **Node.js** >= 20.19
* **npm** (workspaces-aware)

## Get the code

Crosslink is not published to a package registry yet — use it from a clone as npm workspaces.

```bash theme={null}
git clone https://github.com/jacobpowaza/crosslink.git
cd crosslink
npm install
```

Each package under `packages/*` (`@crosslink/sdk-node`, `@crosslink/sdk-browser`, `@crosslink/react`, `@crosslink/core`, `@crosslink/protocol`, ...) is then available as a workspace dependency to any app in the same monorepo, or via `npm link` / a `file:` reference from outside it.

## Optional: OS keychain storage

A host stores its identity seed in the operating system's credential store when
one is reachable, and in an authenticated-encryption file otherwise. `keytar`
and Electron's `safeStorage` are both optional and imported dynamically — their
absence is a normal outcome, not an error.

```bash theme={null}
npm i keytar        # only if you want the libsecret / Keychain / Credential Vault backend
```

On Linux, `keytar` needs libsecret headers to build:

```bash theme={null}
sudo apt-get install libsecret-1-dev
```

Without either, set `CROSSLINK_SECRET_KEY` so the encrypted-file fallback uses a
passphrase you control.

## Optional: run the local services

Nothing here is needed to pair or connect — a phone reaches the host directly
over the address in the QR. Signaling and relay only add a route for phones that
cannot. For local development:

```bash theme={null}
npm run stack
```

This starts both services on localhost (signaling on `:8081`, relay on `:8082` by default).

## Environment variables

| Variable                  | Default             | Description                                                             |
| ------------------------- | ------------------- | ----------------------------------------------------------------------- |
| `CROSSLINK_SIGNALING_URL` | *(auto-discovered)* | Signaling server URL                                                    |
| `CROSSLINK_RELAY_URL`     | *(auto-discovered)* | Relay server URL                                                        |
| `CROSSLINK_SECRET_KEY`    | *(none)*            | Passphrase for encrypted file storage (host fallback)                   |
| `CROSSLINK_LAN_HOST`      | *(auto-detected)*   | Pin the LAN address advertised, when the machine is on several networks |

## Verify installation

```bash theme={null}
npm test          # the full suite
node -e "import('@crosslink/sdk-node').then(() => console.log('Host SDK loaded'))"
```

The packages are ESM-only, so `require()` will not load them.

## TypeScript support

Both SDKs ship with full TypeScript declarations. No `@types` packages needed.

```ts theme={null}
import type { CrosslinkServerConfig } from "@crosslink/sdk-node";
```

## Framework-specific setup

### Vite / React

```bash theme={null}
npm create vite@latest my-app -- --template react
cd my-app
npm install @crosslink/sdk-browser @crosslink/react
```

### Electron

```bash theme={null}
npm install @crosslink/sdk-node  # In main process
npm install @crosslink/sdk-browser  # In renderer (if needed)
```

## Troubleshooting

### WebCrypto unavailable

Ensure you're serving from a **secure context** (HTTPS or localhost). WebCrypto is not available on `http://` origins, which affects `CrosslinkClient.create()`'s encrypted storage (it falls back to plaintext storage, or throws if `allowPlaintextFallback` is `false`).

### Module not found

Ensure you're using ESM:

```json theme={null}
// package.json
{
  "type": "module"
}
```

Or rename files to `.mjs`.
