---
name: livecodes/framework-wrappers
description: >
  Use SDK with React, Vue, Svelte, Solid, Preact, and Web Components.
  sdkReady callback pattern, reactive props, and framework-specific setup.
  Load this skill when embedding LiveCodes in a framework application.
type: framework
library: livecodes
library_version: 0.13.0
requires:
  - sdk-embedding
  - sdk-methods
sources:
  - live-codes/livecodes:docs/docs/sdk/react.mdx
  - live-codes/livecodes:docs/docs/sdk/vue.mdx
  - live-codes/livecodes:docs/docs/sdk/svelte.mdx
  - live-codes/livecodes:docs/docs/sdk/solid.mdx
  - live-codes/livecodes:docs/docs/sdk/preact.mdx
  - live-codes/livecodes:docs/docs/sdk/web-components.mdx
  - live-codes/livecodes:src/sdk/react.tsx
  - live-codes/livecodes:src/sdk/vue.ts
---

This skill builds on sdk-embedding and sdk-methods. Read them first for foundational concepts about createPlayground, SDK methods, and configuration.

# LiveCodes — Framework SDK Wrappers

LiveCodes provides framework-specific components that wrap the core SDK. Each wrapper handles lifecycle, reactivity, and props.

## React

```jsx
import LiveCodes from 'livecodes/react';

// Basic usage
function App() {
  return <LiveCodes template="react" />;
}

// With config
function App() {
  const config = {
    markup: { language: 'markdown', content: '# Hello World' },
  };
  return <LiveCodes config={config} height="400px" />;
}

// Access SDK methods via sdkReady
function App() {
  const [playground, setPlayground] = useState(null);

  const handleRun = async () => {
    await playground?.run();
  };

  return (
    <>
      <LiveCodes
        template="react"
        sdkReady={setPlayground}
      />
      <button onClick={handleRun}>Run</button>
    </>
  );
}

// TypeScript
import LiveCodes, { type Props } from 'livecodes/react';

const options: Props = {
  config: { /* ... */ },
  height: '500px',
};

export default () => <LiveCodes {...options} />;
```

### React: Available Props

| Prop             | Type                        | Description                |
| ---------------- | --------------------------- | -------------------------- |
| All EmbedOptions | —                           | Pass EmbedOptions as props |
| `className`      | `string`                    | Container class name       |
| `height`         | `string`                    | Container height           |
| `style`          | `object`                    | Container styles           |
| `sdkReady`       | `(sdk: Playground) => void` | Callback with SDK instance |

### React: Reactive Props

```jsx
function App() {
  const [config, setConfig] = useState({
    markup: { language: 'html', content: '<h1>Hello</h1>' },
  });

  // Changing config uses setConfig() - no full reload
  const switchToMarkdown = () => {
    setConfig({
      markup: { language: 'markdown', content: '# Hello' },
    });
  };

  // Changing other props causes full reload
  // <LiveCodes template={template} /> // changing template reloads

  return (
    <>
      <LiveCodes config={config} />
      <button onClick={switchToMarkdown}>Switch to Markdown</button>
    </>
  );
}
```

## Vue

```vue
<script setup>
import LiveCodes from 'livecodes/vue';

const config = {
  markup: { language: 'markdown', content: '# Hello World' },
};

let playground;
const onReady = (sdk) => {
  playground = sdk;
};

const run = async () => {
  await playground?.run();
};
</script>

<template>
  <LiveCodes :config="config" @sdk-ready="onReady" />
  <button @click="run">Run</button>
</template>

<!-- With TypeScript -->
<script setup lang="ts">
import LiveCodes, { type Props } from 'livecodes/vue';
import type { Playground } from 'livecodes';

const options: Props = {
  config: {
    /* ... */
  },
};
</script>

<template>
  <LiveCodes v-bind="options" />
</template>
```

### Vue: Available Props

| Prop             | Type     | Description                |
| ---------------- | -------- | -------------------------- |
| All EmbedOptions | —        | Pass EmbedOptions as props |
| `height`         | `string` | Container height           |

### Vue: Events

| Event        | Payload                     |
| ------------ | --------------------------- |
| `@sdk-ready` | `(sdk: Playground) => void` |

### Vue: Reactive Props

```vue
<script setup>
import { ref } from 'vue';
import LiveCodes from 'livecodes/vue';

const config = ref({
  markup: { language: 'html', content: '<h1>Hello</h1>' },
});

// Uses setConfig() - no reload
const switchToMarkdown = () => {
  config.value = {
    markup: { language: 'markdown', content: '# Hello' },
  };
};
</script>

<template>
  <LiveCodes :config="config" />
  <button @click="switchToMarkdown">Switch</button>
</template>
```

## Svelte

```svelte
<script>
  import LiveCodes from 'livecodes/svelte';

  let playground;
  const config = {
    markup: { language: 'markdown', content: '# Hello World' },
  };

  function onReady(sdk) {
    playground = sdk;
  }

  async function run() {
    await playground?.run();
  }
</script>

<LiveCodes {config} on:sdkReady={onReady} />
<button on:click={run}>Run</button>
```

## Solid

```tsx
import LiveCodes from 'livecodes/solid';
import { createSignal } from 'solid-js';

function App() {
  const [playground, setPlayground] = createSignal(null);
  const config = {
    markup: { language: 'markdown', content: '# Hello World' },
  };

  const handleRun = async () => {
    await playground()?.run();
  };

  return (
    <>
      <LiveCodes config={config} sdkReady={setPlayground} />
      <button onClick={handleRun}>Run</button>
    </>
  );
}
```

## Preact

```tsx
import LiveCodes from 'livecodes/preact';
import { useState } from 'preact/hooks';

function App() {
  const [playground, setPlayground] = useState(null);

  const handleRun = async () => {
    await playground?.run();
  };

  return (
    <>
      <LiveCodes template="react" sdkReady={setPlayground} />
      <button onClick={handleRun}>Run</button>
    </>
  );
}
```

## Web Components

```html
<script src="https://cdn.jsdelivr.net/npm/livecodes/web-components.js"></script>

<!-- Basic usage -->
<live-codes template="react"></live-codes>

<!-- With config -->
<live-codes height="400px"></live-codes>

<script>
  const playground = document.querySelector('live-codes');
  playground.config = {
    markup: { language: 'markdown', content: '# Hello' },
  };
</script>
```

## Common Mistakes

### HIGH Not using sdkReady to access SDK in frameworks

Wrong (React):

```jsx
function App() {
  // No way to get SDK reference
  return <LiveCodes template="react" />;
}

function handleRun() {
  // Where's playground? Can't access SDK methods
  playground.run(); // Error: playground is undefined
}
```

Correct (React):

```jsx
function App() {
  const [playground, setPlayground] = useState(null);

  const handleRun = async () => {
    await playground?.run();
  };

  return (
    <>
      <LiveCodes template="react" sdkReady={setPlayground} />
      <button onClick={handleRun}>Run</button>
    </>
  );
}
```

Correct (Vue):

```vue
<script setup>
import LiveCodes from 'livecodes/vue';
import { ref } from 'vue';

const playground = ref(null);

const onReady = (sdk) => {
  playground.value = sdk;
};
</script>

<template>
  <LiveCodes template="vue" @sdk-ready="onReady" />
</template>
```

The SDK is only available after the playground initializes. Use `sdkReady` (React), `@sdk-ready` (Vue), or `on:sdkReady` (Svelte) to get a reference.

Source: docs/docs/sdk/react.mdx, docs/docs/sdk/vue.mdx — sdkReady section

### MEDIUM Changing non-config props causes full reload

```jsx
// React - config changes use setConfig (no reload)
const [config, setConfig] = useState(initialConfig);
setConfig(newConfig); // Efficient update, no iframe reload

// React - other prop changes cause full reload
const [template, setTemplate] = useState('react');
setTemplate('vue'); // Destroys and recreates iframe
```

Changing `config` prop uses SDK's `setConfig()` method under the hood — efficient. Changing other props (`template`, `params`, `loading`) destroys and recreates the iframe.

If you need reactive changes, prefer updating `config` over changing other props.

Source: docs/docs/sdk/react.mdx — Reactive Props section

## Framework Installation

```bash
# React
npm install livecodes
import LiveCodes from 'livecodes/react';

# Vue 3
npm install livecodes
import LiveCodes from 'livecodes/vue';

# Svelte
npm install livecodes
import LiveCodes from 'livecodes/svelte';

# Solid
npm install livecodes
import LiveCodes from 'livecodes/solid';

# Preact
npm install livecodes
import LiveCodes from 'livecodes/preact';

# Web Components (CDN)
<script src="https://cdn.jsdelivr.net/npm/livecodes/web-components.js"></script>
```

## Exported Types

All frameworks export:

- `Props` — EmbedOptions plus framework-specific props
- `Playground` — SDK Playground interface
- `Config` — Configuration type
- `Code` — Code object type
- `Language` — Language string type
