# LiveCodes > LiveCodes is a feature-rich, open-source, client-side code playground that supports React, Vue, Svelte, Solid, JavaScript, TypeScript, CSS, Sass, Tailwind CSS, Python, Go, Ruby, PHP, and 90+ languages/frameworks. A large number of starter templates are available to help you get started quickly. Projects can be saved, shared, exported (e.g. to GitHub Gists), deployed (e.g. to GitHub Pages), or embedded in web pages. A powerful yet easy-to-use SDK enables the creation of and communication with embedded playgrounds. With extensive language support and high configurability, LiveCodes can easily adapt to your needs. It offers excellent mobile support, featuring a responsive layout and a touch-friendly code editor. LiveCodes is an outstanding tool for learning, teaching, prototyping, sharing, and testing code. It can be easily self-hosted, if needed, on any static file server. LiveCodes is completely free for unlimited use, with no ads and no account required. Its MIT License also permits commercial use. - [Docs](https://livecodes.io/docs/llms.txt) - [Full Docs](https://livecodes.io/docs/llms-full.txt) - [README](https://raw.githubusercontent.com/live-codes/livecodes/refs/heads/develop/README.md) # LiveCodes A Code Playground That Just Works!
Demo: (console=full)
:::tip Setting the querystring `languages` only shows these languages. Selecting one language and setting console to `full` gives an environment similar to a REPL. ::: Demo: (Python - print to console)
Demo: (template=jest-react)
Demo:
You can import from React like that: ```js import { useState } from 'react'; ``` Demo:
  This is identified as <strong>HTML</strong> code
```
The HTML editor is prefilled with: `This is identified as HTML code`
Please note that the code should be html-encoded to avoid interference with the HTML of the page.
:::
Example:
https://livecodes.io/?x=https://live-codes.github.io/livecodes-examples/prefill-from-code-blocks.html
Alternatively, custom CSS selectors can be specified using [query params](../configuration/query-params.html.md):
`?x={url}&{language}-selector={selector}`
The following example loads the content of the first element that matches the CSS selector `h3` as `html`:
https://livecodes.io/?html-selector=h3&x=https://live-codes.github.io/livecodes-examples/prefill-from-code-blocks.html
Of course, [embedded playgrounds](./embeds.html.md) can be prefilled with code from the same embedding page. This works well for documentation and educational websites.
[This is a demo](https://live-codes.github.io/livecodes-examples/prefill-from-code-blocks.html) for automatic extraction of code blocks to prefill editors by creating "Edit in LiveCodes" links. Also embedded editors are prefilled from the code blocks. ([View source](https://github.com/live-codes/livecodes-examples/blob/master/prefill-from-code-blocks.html))
## Import Raw Code
If the response text could not be parsed as DOM or no elements matched the CSS selectors, it is assumed to be raw code and the response text is loaded to editor. If the URL ends with an extension it is used to identify the language, otherwise it is assumed to be `html`.
Alternatively, the language of raw code can be specified using [query params](../configuration/query-params.html.md):
`?x={url}&raw={language}`
## Import from CodePen
Currently, CodePen API does not allow directly importing code from Pens. However, you can export any saved Pen as a [zip file](https://blog.codepen.io/documentation/exporting-pens/#export-zip-1) or [Github gist](https://blog.codepen.io/documentation/exporting-pens/#save-as-github-gist-2) and then import it to LiveCodes. The format that Codepen exports is well understood by LiveCodes. Most Pens can be imported with no or minimal changes.
**Note:** External resources (styles/scripts) are not exported with source code in zip file export of CodePen. However, export to GitHub gist does export these. So if a Pen with external resources exported as zip file is not imported properly, try exporting to GitHub gist or manually add the [external resources](./external-resources.html.md).
## Import Code from Image (OCR)
Code can be extracted from images (local or via URL) using [Tesseract.js](https://github.com/naptha/tesseract.js), a library for Optical Character Recognition (OCR).
To ensure accurate identification, the text in the image should be clear, have high contrast against the background, and be free from unrelated text.
Language detection is performed using [highlight.js](https://highlightjs.readthedocs.io/en/latest/api.html#highlightauto), which makes its best guess based on the content.
Best results are obtained when the image is generated using LiveCodes "[Code to Image](./code-to-image.html.md)" feature.
## Import Exported LiveCodes Projects
A [single project exported as JSON](./export.html.md)#exporting-a-single-project) can be imported in the same or a different device from the import screen under the tab "Import Project JSON". The JSON file can be supplied as a local file upload or from a URL.
Similarly, [multiple projects exported in bulk](./export.html.md)#exporting-multiple-projects) can be imported from the tab "Bulk Import".
## Related
- [Code prefill](./code-prefill.html.md)
- [Export](./export.html.md)
- [External resources](./external-resources.html.md)
- [Module resolution](./module-resolution.html.md)
- [Projects](./projects.html.md)
---
# Export
## Exporting A Single Project
Project export can be accessed from the Project menu → Export.

Any project can be exported to:
- **Project (JSON):** a JSON file containing project [configuration object](../configuration/configuration-object.html.md). This can be used to later [import](./import.html.md)#import-exported-livecodes-projects) that project on the same or a different device or to share a copy of the project with others.
- **Source (ZIP):** a zip file containing the project configuration file as JSON, in addition to the source code in separate files. This can be useful for opening the code in an external IDE.
- **Result (HTML):** [result page](./result.html.md) as a single html file. Can be used for the purpose of demo or deploy.
- **GitHub gist** (_requires login with [GitHub account](./github-integration.html.md)_): creates a **public** GitHub gist on the user's GitHub account containing the source code as separate files.
- **CodePen:** creates a [CodePen](https://codepen.io/) prefilled with the project code. If the used [languages/frameworks](./../languages/index.html.md) are not supported in CodePen (e.g. Astro, Svelte, Python, ...etc), the compiled code is exported so that it continues to work there. [Bare module imports](./module-resolution.html.md) are converted to esm imports, for example:
  ```js
  ```
  becomes:
  ```js
  import React from 'https://cdn.skypack.dev/react';
  ```
- **JSFiddle:** creates a [JSFiddle](https://jsfiddle.net/) prefilled with the project code. Exported code may be modified like with CodePen (see above).
## Exporting Multiple Projects
Multiple projects can be exported in bulk from the [Saved Projects](./projects.html.md) screen (Project menu → Open) using the button `Export All`.

This produces a JSON file containing an array of project configuration objects. They can be later imported in the same or a different device using the `Bulk Import` functionality in the [Import screen](./import.html.md)#import-exported-livecodes-projects).
All the currently visible projects will be exported. If projects are filtered (e.g. by language, tag or search query), only the shown projects are exported.
## Related
- [Projects](./projects.html.md)
- [Import](./import.html.md)
- [Backup/Restore](./backup-restore.html.md)
- [Sync](./sync.html.md)
- [Share](./share.html.md)
---
# Share
It is easy to share LiveCodes projects!
A URL is generated to load the shared project. This URL can be copied or shared to different social media.
The share screen can be accessed from the share icon at the top right or from the Project menu → Share.

By default, the generated URL encodes the project configuration in a base-64-encoded compressed query string. This step is generated locally in the browser without sending the code to any server. However, depending on the size of the project, the URL can be very long. The length of the URL is indicated in the share screen. [Try not to use very long URLs](https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers) to ensure cross-browser compatibility.
When requested by the user, short URLs can be generated. This requires sending the project configuration (**including source code**) to a server that saves the code and provides a short Id which can be used to retrieve the project.

:::caution
Generating a short URL for sharing requires sending the project configuration (**including source code**) to LiveCodes share service. **It cannot then be deleted**.
:::
:::info Note
The app hosted on [`https://livecodes.io`](https://livecodes.io) uses an API endpoint specifically provided to generate short URLs for LiveCodes share service. We will make every effort to keep that online and available for free use, so long as it is not abused. Please help keep it available by not abusing it and by [sponsoring the project](../sponsor.html.md).
Short URLs generated by LiveCodes share service are **private** — the links are not published anywhere on the site, and the IDs are non-sequential.
However, _static_ [**self-hosted apps**](./self-hosting.html.md) use the free service [dpaste](https://dpaste.com/) for short URLs which are [**deleted after 365 days**](https://dpaste.com/help). If this is a significant issue for you, you may want to use the [docker setup](../advanced/docker.html.md) instead, which provides a self-hosted implementation for the share service among other features. LiveCodes [sponsors](../sponsor.html.md) (Bronze sponsors and above) get access to a hosted implementation.
:::
QR code can be generated for the share URL. This can then be scanned by any QR code scanner (e.g. mobile/tablet camera) to load the project on other devices without having to send the link. Please note that generating QR code also requires generating a short URL (code is sent to the share service - see above).

## Related
- [Export](./export.html.md)
- [Import](./import.html.md)
- [Deploy](./deploy.html.md)
- [Broadcast](./broadcast.html.md)
- [Backup / Restore](./backup-restore.html.md)
- [Sync](./sync.html.md)
- [Permanent URL](./permanent-url.html.md)
---
# Welcome Screen
---
# Recover Unsaved
---
# Code to Image
LiveCodes has a feature called "Code to Image" that allows converting the code in the code editor into nice-looking images (or code screenshots), that can be downloaded or shared.
This can be accessed from the camera icon in the toolbar below the editor. Clicking the icon will open the "Code to Image" screen and load the code in the editor.

Code can be modified in the "Code to Image" screen and then downloaded as image or shared.

There are many options to configure the image to be generated, including background color, border radius, image size, padding, shadow, window style, share URL, editor theme, opacity, code font, image format, etc.
There are multiple presets that can be used or the options can be manually configured.




---
# Display Modes
import LiveCodes from '../../src/components/LiveCodes.tsx';
The [configuration](../configuration/configuration-object.html.md) option [`mode`](../configuration/configuration-object.html.md)#mode), also available as [query param](../configuration/query-params.html.md), can be used to select different display modes.
The following display modes are supported:
## `full`
This is the default mode with toolbars, editor and result panes.
Example: https://livecodes.io/?template=react
Screenshot: (App in full mode)

Demo: (Embedded playground in full mode)
# Hello World!# Hello World!`](../api/interfaces/Playground.md#getcode)
Gets the playground code (including source code, source language and compiled code) for each editor (`markup`, `style`, `script`), in addition to result page HTML.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
  const code = await playground.getCode();
  // source code, language and compiled code for the script editor
  const { content, language, compiled } = code.script;
  // result page HTML
  const result = code.result;
});
```
### `show`
Type: [`(panel: 'editor' | 'markup' | 'style' | 'script' | 'console' | 'compiled' | 'tests' | 'result' | 'toggle-result', options?: { full?: boolean; line?: number; column?: number; zoom?: 1 | 0.5 | 0.25 }) => Promise`](../api/interfaces/Playground.md#show)
Shows the selected panel, which is either:
- Active Editor: `editor`
- Specific Editor: `markup`, `style` or `script`
- Tool: `console`, `compiled` or `tests`
- Result page: `result` or `toggle-result`
The second optional argument is an object:
- It may have the boolean property `full`, which If `true`, selected editor or result page will take the full vertical and horizontal space of the playground, while tools will take the full vertical and half the horizontal space, leaving some space for the active editor.
- The optional properties `line` and `column` allow scrolling to line/column number in the shown editor.
- The optional property `zoom` sets the result page [zoom level](../features/result.html.md)#result-page-zoom) (the selected panel must be `result`).
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
  const delay = (duration) =>
    new Promise((resolve) => {
      setTimeout(resolve, duration);
    });
  await playground.show('toggle-result');
  await delay(2000);
  await playground.show('style');
  await delay(2000);
  await playground.show('result', { full: true });
  await delay(2000);
  await playground.show('script');
  await delay(2000);
  await playground.show('result', { zoom: 0.5 });
  await delay(2000);
  await playground.show('console', { full: true });
});
```
### `runTests`
Type: [`() => Promise<{ results: TestResult[] }>`](../api/interfaces/Playground.md#runtests)
Runs project [tests](./../features/tests.html.md) (if present) and gets test results.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
  const { results } = await playground.runTests();
});
```
### `watch`
Type: [docs](../api/interfaces/Playground.md#watch)
```ts
((event: 'load', fn: () => void) => { remove: () => void }) &
((event: 'ready', fn: (data: { config: Config }) => void) => { remove: () => void }) &
((event: 'code', fn: (data: { code: Code; config: Config }) => void) => { remove: () => void }) &
((event: 'console', fn: (data: { method: string; args: any[] }) => void) => { remove: () => void }) &
((event: 'tests', fn: (data: { results: TestResult[]; error?: string }) => void) => { remove: () => void }) &
((event: 'destroy', fn: () => void) => { remove: () => void });
```
Allows to watch for various playground events. It takes 2 arguments: event name and a callback function that will be called on every event.
In some events, the callback function will be called with an object that supplies relevant data to the callback function (e.g. code, console output, test results).
The `watch` method returns an object with a single method `remove`, which when called will remove the callback from watching further events.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then((playground) => {
  const codeWatcher = playground.watch('code', ({ code, config }) => {
    // this will run on every code change
    console.log('code:', code);
    console.log('config:', config);
  });
  const consoleWatcher = playground.watch('console', ({ method, args }) => {
    // this will run on every console output
    console[method](...args);
  });
  const testsWatcher = playground.watch('tests', ({ results }) => {
    // this will run when tests run
    results.forEach((testResult) => {
      console.log('status:', testResult.status); // "pass", "fail" or "skip"
      console.log(testResult.errors); // array of errors as strings
    });
  });
  // then later
  codeWatcher.remove();
  consoleWatcher.remove();
  testsWatcher.remove();
  // events are no longer watched
});
```
These are the events that can be watched and the description of their callback functions:
- `"load"`: Called when the playground first loads.
  ```ts
  (
    event: "load",
    fn: () => void
  ) => { remove: () => void }
  ```
- `"ready"`: Called when a new project is loaded (including when [imported](../features/import.html.md)) and the playground is ready to run.
  ```ts
  (
    event: "ready",
    fn: (data: { config: Config }) => void
  ) => { remove: () => void }
  ```
- `"code"`: Called when the playground "content" is changed (see [`getCode`](./js-ts.html.md)#getcode) and [`getConfig`](./js-ts.html.md)#getconfig)).
  This includes changes in:
  - Code (in editors)
  - Editor languages
  - [CSS processors](../features/css.html.md)#css-processors)
  - [External resources](../features/external-resources.html.md)
  - Project info (e.g. allows adding content in page head and attributes to `` element)
  - [Custom settings](../advanced/custom-settings.html.md) (e.g. allows changing [import maps](../features/module-resolution.html.md)#custom-module-resolution))
  - Project title
  - [Test](../features/tests.html.md) code
  ```ts
  (
    event: "code",
    fn: (data: { code: Code; config: Config }) => void
  ) => { remove: () => void }
  ```
- `"console"`: Called when the playground console gets new outputs. The callback method is passed an object with 2 properties: `"method"` (e.g. `"log"`, `"error"`, etc.) and `"args"` (the arguments passed to the method, as an array).
  ```ts
  (
    event: "console",
    fn: (data: { method: string; args: any[] }) => void
  ) => { remove: () => void }
  ```
- `"tests"`: Called when tests run and test results are available (see [`runTests`](./js-ts.html.md)#runtests)).
  ```ts
  (
    event: "tests",
    fn: (data: { results: TestResult[]; error?: string }) => void
  ) => { remove: () => void }
  ```
- `"destroy"`: Called when the playground is destroyed.
  ```ts
  (
    event: "destroy",
    fn: () => void
  ) => { remove: () => void }
  ```
### `onChange`
**Deprecated**: Use [`watch`](#watch) method instead.
Type: [`(fn: ChangeHandler) => { remove: () => void }`](../api/interfaces/Playground.md#onchange)
Allows to watch the playground for changes. It takes a callback function that will be called on every change.
The callback function will be called with an object that has 2 properties: `code` and `config`, representing the current codes and configuration objects (see [`getCode`](#getcode) and [`getConfig`](#getconfig)).
The `onChange` method returns an object with a single method `remove`, which when called will remove the callback from watching changes.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then((playground) => {
  const watcher = playground.onChange(({ code, config }) => {
    // this will run on every code change
    console.log('code:', code);
    console.log('config:', config);
  });
  // then later
  watcher.remove();
  // changes are no longer watched
});
```
### `exec`
Type: [`(command: APICommands, ...args: any[]) => Promise<{ output: any } | { error: string }>`](../api/interfaces/Playground.md#exec)
Execute custom commands, including:
- `"setBroadcastToken"`: Sets [broadcast `userToken`](../features/broadcast.html.md)#technical-details).
```js
// in browser console of full app (e.g. https://livecodes.io)
await livecodes.exec('setBroadcastToken', 'my-token');
```
- `"showVersion"`: Logs the current LiveCodes app version, SDK version, git commit SHA, [permanent app URL](../features/permanent-url.html.md) and SDK URL in the browser console.
```js
// in browser console of full app (e.g. https://livecodes.io)
await livecodes.exec('showVersion');
```
### `destroy`
Type: [`() => Promise`](../api/interfaces/Playground.md#destroy)
Destroys the playground instance, and removes event listeners. Further call to any SDK methods throws an error.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
  await playground.destroy();
  // playground destroyed
  // any further SDK call throws an error
});
```
## Styles
### Default Styles
By default, the container element is styled when the SDK is initialized (including width, height, border, etc.). To disable default styles, set the container element attribute `data-default-styles` to `"false"` before initializing.
Example:
```html
```
### Height
By default, the playground container height is set to `"300px"`. To change the height, either disable the default styles and override them, or simply set the `data-height` attribute to a number (in pixels) or any valid CSS value (e.g. `"100%"` to take the full height of its parent element).
Example:
```html
```
## Demo
export const sdkDemo = {
  js: `import { createPlayground } from "livecodes";\n\nconst params = {\n  html: "Hello World!
",\n  css: "h1 {color: blue;}",\n  js: 'console.log("Hello, LiveCodes!")',\n  console: "open",\n};\n\ncreatePlayground('#container', { params });\n`,
  html: '',
};
`.
  Defines styles to add to playground container element. Styles set here override the [default styles](js-ts.html.md)#default-styles).
  Example:
  ```tsx title="JSX"
  import LiveCodes from 'livecodes/react';
  const style = {
    margin: 'auto',
    width: '80%',
  };
  export const Playground = () => ();
    const onReady = (sdk: Playground) => {
      setPlayground(sdk);
    };
    const run = async () => {
      await playground?.run();
    };
    return (
      <>
        Hello World!
",\n    css: "h1 {color: blue;}",\n    js: 'console.log("Hello, World!")',\n    console: "open",\n  };\n\n  return Hello World!
',\n      css: 'h1 {color: blue;}',\n      js: 'console.log("Hello, Svelte!")',\n      console: 'open',\n    },\n  };\n\n  let container;\n  let playground = $state(null);\n  onMount(() => {\n    createPlayground(container, options).then((p) => {\n      playground = p; // now the SDK is available\n    });\n    // cleanup when the component is destroyed\n    return () => playground?.destroy();\n  });\n\x3C/script>\n\n\n`,
};
Hello World!
',
      css: 'h1 {color: blue;}',
      js: 'console.log("Hello, Solid!")',
      console: 'open',
    },
  };
  const onMounted = (container: HTMLElement) => {
    createPlayground(container, options).then((sdk) => {
      playground = sdk; // now the SDK is available
    });
  };
  onCleanup(() => playground?.destroy());
  return ;
}
```
export const solidSDKDemo = {
  "solid.tsx": `import { onCleanup } from 'solid-js';
import { createPlayground, type Playground, type EmbedOptions } from 'livecodes';
export default function App() {
  let playground: Playground | null = null;
  const options: EmbedOptions = {
    params: {
      html: 'Hello World!
',
      css: 'h1 {color: blue;}',
      js: 'console.log("Hello, Solid!")',
      console: 'open',
    },
  };
  const onMounted = (container: HTMLElement) => {
    createPlayground(container, options).then((sdk) => {
      playground = sdk; // now the SDK is available
    });
  };
  onCleanup(() => playground?.destroy());
  return ;
}
`,
};
Hello World!
"
  console.log(code.result); // (result page HTML)
});
```
## Examples
The following examples show how to use the headless mode to make a Markdown editor, an MDX editor and a Python interpreter.
:::tip
You may want to view the following playgrounds in full screen (using the full screen button in the top right of each playground).
:::
### Markdown Editor
In this demo, code changes are watched using the SDK method [`watch('code', callback)`](./js-ts.html.md)#watch). The callback function accepts an argument which is an object with the properties `code` and `config` (see [`getCode`](./js-ts.html.md)#getcode) and [`getConfig`](./js-ts.html.md)#getconfig)). The compiled code is obtained as `code.markup.compiled`.
export const mdDemo = { markup: { language: 'html', content: `\nLoading...\n\n\x3Cscript type="module">\n  import { createPlayground } from "https://cdn.jsdelivr.net/npm/livecodes@0.2.0";\n  import debounce from "https://jspm.dev/debounce";\n\n  const initialCode = "# Hello, LiveCodes!\\n\\n";\n\n  // the code editor\n  const editor = CodeMirror.fromTextArea(document.getElementById("editor"), {\n    lineNumbers: true,\n    mode: "markdown",\n  });\n  editor.setSize("100%", 200);\n  editor.setValue(initialCode);\n\n  // the playground\n  const options = {\n    view: "headless",\n  };\n\n  const livecodes = await createPlayground(options);\n  await livecodes.load();\n\n  const compile = async () => {\n    await livecodes.setConfig({\n      autoupdate: false,\n      markup: {\n        language: "markdown",\n        content: editor.doc.getValue(),\n      },\n    });\n  };\n\n  // watch for changes\n  editor.on("change", debounce(compile, 1000));\n  livecodes.watch("code", ({ code, config }) => {\n    createSandbox(document.querySelector("#output"), code.markup.compiled);\n  });\n\n  await compile();\n\n  // create a sandbox for safe execution of compiled code\n  function createSandbox (container, html) {\n    const iframe = document.createElement("iframe");\n    iframe.src = "https://livecodes-sandbox.pages.dev/v7/";\n    iframe.sandbox =\n      "allow-same-origin allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-presentation allow-scripts";\n    iframe.onload = () => {\n      iframe.contentWindow.postMessage({ html }, "*");\n    };\n    container.innerHTML = "";\n    container.appendChild(iframe);\n    return iframe;\n  };\n\x3C/script>\n\n\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/lib/codemirror.js">\x3C/script>\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/mode/markdown/markdown.js">\x3C/script>\n\n\n` }}
Hello, {name}!
\n      You clicked {count} times.
\n      \n    >\n  );\n};\n\n item.docId !== 'languages/index')}/>
```
---
# Custom Settings
---
# Services
LiveCodes (being a [client-side](../why.html.md)#client-side) app) uses multiple services (for example for short-URL [sharing](../features/share.html.md), [broadcast server](../features/broadcast.html.md), authentication, module resolution, etc).
Some of these services are not supported on _static_ [self-hosted](../features/self-hosting.html.md) deploys and are either replaced by other compatible services or require you to provide alternative ones.
Examples:
- The [share](../features/share.html.md) service in [self-hosted](../features/self-hosting.html.md) apps uses [dpaste](https://dpaste.com/) for short URLs, which are [**deleted after 365 days**](https://dpaste.com/help).
- [Firebase configuration](https://github.com/live-codes/livecodes/tree/develop/src/livecodes/services/firebase.ts) for authentication.
Demo for a static self-hosted app (on GitHub Pages): https://live-codes.github.io/livecodes
Most likely, you will not need to provide these services yourself, and the app will work just fine using the other compatible services (e.g. dpaste).
However, if you do need to provide them, you may wish to use the included [docker setup](../advanced/docker.html.md) which provides a self-hosted implementation for these services, very similar to the official [hosted app](https://livecodes.io).
You can find the list of provided services [here](../advanced/docker.html.md)#services).
Demo for a self-hosted app that uses the [docker setup](../advanced/docker.html.md) (on a VPS): https://vps.livecodes.io
:::info
LiveCodes [sponsors](../sponsor.html.md) (Bronze sponsors and above) get access to a hosted [docker setup](../advanced/docker.html.md) with managed [services](../advanced/docker.html.md)#services).
:::
---
# Docker Setup
This guide makes it easy to set up a self-hosted instance of LiveCodes on a VPS using Docker.
## Why?
LiveCodes is a [client-side app](../why.html.md)#client-side). It can be easily self-hosted on any static file server or CDN (See [Self-Hosting guide](../features/self-hosting.html.md)).
All core functionalities (e.g. editors, compilers, formatters, code execution, etc) run in the browser.
However, some features require [external services](./services.html.md) which depend on server-side implementations (e.g. [sharing](../features/share.html.md) short URLs, [broadcast server](../features/broadcast.html.md), etc).
The docker setup described here provides out-of-the-box implementations for self-hosting these services.
See below for the list of provided [services](#services).
This allows self-hosted instances to have the same features as the hosted app ([livecodes.io](https://livecodes.io)).
:::warning Note
Most self-hosted instances will not require this setup. The static app should work just fine using other simpler [self-hosting methods](../features/self-hosting.html.md)#guide).
Only use the docker setup if you need to self-host [these services](#services).
:::
## Example
This is an example of a self-hosted instance deployed to a VPS using the included Docker setup:
https://vps.livecodes.io/
Setting it up can be as simple as running the following command:
```sh
HOST_NAME=vps.livecodes.io docker compose up --build -d
```
## Requirements
- Docker and Docker Compose ([installation guide](https://docs.docker.com/engine/install/))
- Git: optional - for pulling updates ([installation guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git))
Example script to install Docker, Docker Compose and Git on Ubuntu
```sh title="install_docker_ubuntu.sh"
#!/bin/bash
# Update package lists
sudo apt update
# Install Docker
sudo apt install -y ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
# Add current user to docker group
sudo usermod -aG docker $USER
newgrp docker # Apply group changes immediately
# Install Docker Compose
sudo apt install -y docker-compose
# Install Git
sudo apt install -y git
```
To use this script:
**Save**
Save the script to a file, for example: `install_docker_ubuntu.sh`.
**Make Executable**
Make the script executable with:
```sh
chmod +x install_docker_ubuntu.sh
```
**Run**
Execute the script using:
```sh
sudo ./install_docker_ubuntu.sh
```
**Verify**
Verify the installations with:
```sh
docker --version
docker compose version
git --version
```
## Getting Started
:::info note
When running in a non-local environment (e.g. VPS),
make sure your domain's A/AAAA DNS records properly point to the machine public IP **before** running the docker containers.
The hostname should be set using [environment variables](#environment-variables).
:::
Clone the repo:
```sh
git clone https://github.com/live-codes/livecodes.git
```
Enter the directory:
```sh
cd livecodes
```
Optionally, checkout a specific branch:
```sh
git checkout main
```
Run docker compose:
```sh
docker compose up -d
```
By default, the app is served at https://livecodes.localhost 
(Yes, `localhost` can be served over HTTPS and have subdomains!).
The hostname and many other options can be set using [environment variables](#environment-variables).
## Services
- Automatic HTTPS
  This is provided by [Caddy server](https://caddyserver.com), which automatically obtains and renews TLS certificates.
  Local addresses (e.g. `localhost`, `livecodes.localhost`) are served over HTTPS using locally-trusted certificates.
- [Open Graph meta tags](https://ogp.me/)
  Provide project-specific meta tags, for social media cards.
- [oEmbed](https://oembed.com/)
  Allows embedded representations on third party sites.
- Adding [headers](https://github.com/live-codes/livecodes/blob/develop/src/_headers)
  e.g. aggressive caching of static assets for improved performance.
- [Short-URL share service](../features/share.html.md)
  Generates a short URL that can be shared. The project config is stored in a [Valkey](https://valkey.io/) store (a Redis fork with a permissive open-source license).
  Data is persisted to disk every 60 seconds (See [Volumes](#volumes) section below).
- [Broadcast server](../features/broadcast.html.md)
  Broadcasts updates to connected clients.
- CORS proxy
  Allows [importing content](../features/import.html.md) from external URLs.
- Separate origin sandbox
  Runs code in a separate origin [sandboxed iframe](https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/) to prevent cross-site scripting.
- [404 page](https://livecodes.io/404)
  Custom 404 page for resources that are not found.
## Environment Variables
The app can be customized by setting different environment variables.
Environment variables can be defined in a `.env` file in the root of the repository (on the same level as `docker-compose.yml`).
```txt title=".env"
HOST_NAME=playground.website.com
```
Please note that some variables are used **during build**. So after setting environment variables, the app needs to be rebuilt. e.g.:
```sh
docker compose up --build -d
```
The following environment variables are supported:
| Variable | Description | Default |
| --- | --- | --- |
| `HOST_NAME` | Hostname of the app | `livecodes.localhost` |
| `PORT` | Port of the app | `443` |
| `SELF_HOSTED_SHARE` | Enable [share service](../features/share.html.md) | `true` |
| `SELF_HOSTED_BROADCAST` | Enable [broadcast server](../features/broadcast.html.md) | `true` |
| `BROADCAST_PORT` | Port of the broadcast server | `3030` |
| `BROADCAST_TOKENS` | Comma-separated list of broadcast [user tokens](../features/broadcast.html.md)#technical-details) | |
| `SANDBOX_HOST_NAME` | Hostname of the sandbox | `$HOST_NAME` |
| `SANDBOX_PORT` | Port of the sandbox | `8090` |
| `FIREBASE_CONFIG` | [Firebase config object](https://firebase.google.com/docs/web/learn-more#config-object) (JSON), used for [authentication](../features/github-integration.html.md) | |
| `DOCS_BASE_URL` | [Base URL](../features/self-hosting.html.md)#custom-build) of the documentation (e.g. `/docs/`) | `null` |
| `LOG_URL` | Full URL to send [server-side analytics](https://github.com/live-codes/livecodes/blob/develop/functions/index.ts) (e.g. `https://api.website.com/log`) | `null` |
:::info note
When running in a non-local environment (e.g. VPS),
setting the `HOST_NAME` environment variable is **required**. It should match the domain name set in [DNS records](#getting-started).
:::
## Volumes
The following docker [volumes](https://docs.docker.com/engine/storage/volumes/) are used:
- `./assets` - A [bind mount](https://docs.docker.com/engine/storage/bind-mounts/) for static assets that get served under the app URL (`/assets/`). This can be used to serve images, stylesheets, [custom modules](../features/module-resolution.html.md)#custom-module-resolution), [custom types](../features/intellisense.html.md)#custom-types), etc.
- `livecodes-share-data` - A [named volume](https://docs.docker.com/engine/storage/volumes/) where persistent data for the share service is saved. Make sure to **backup** this.
Example scripts to backup and restore Docker named volumes
```sh title="backup-volumes.sh"
#!/bin/bash
VOLUMES=("livecodes-share-data")
BACKUP_DIR="./backups"
mkdir -p $BACKUP_DIR
for VOLUME in "${VOLUMES[@]}"; do
  echo "Backing up $VOLUME..."
  docker run --rm \
    -v $VOLUME:/data \
    -v $(pwd)/$BACKUP_DIR:/backup \
    alpine \
    tar cvf /backup/$VOLUME.tar /data
done
echo "Backup complete. Files are in $BACKUP_DIR."
```
```sh title="restore-volumes.sh"
#!/bin/bash
VOLUMES=("livecodes-share-data")
BACKUP_DIR="./backups"
for VOLUME in "${VOLUMES[@]}"; do
  echo "Restoring $VOLUME..."
  docker volume create $VOLUME
  docker run --rm \
    -v $VOLUME:/data \
    -v $(pwd)/$BACKUP_DIR:/backup \
    alpine \
    tar xvf /backup/$VOLUME.tar -C /data --strip 1
done
echo "Restore complete."
```
## Deployment
For continuous deployment, you can use the included [GitHub Actions workflow](https://github.com/live-codes/livecodes/blob/develop/.github/workflows/docker-deploy.yml) to deploy to a VPS when a new commit is pushed (e.g. to the `main` branch).
This assumses that you have followed the [Getting Started](#getting-started) instructions and have cloned the repo to your VPS.
The workflow uses [secrets](https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions) and [variables](https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables) from your GitHub repo settings for SSH access and setting required [environment variables](#environment-variables).
---
# Languages
## Overview
The term "language" used in these documentations refer to any technology (in addition to web languages: HTML, CSS and JavaScript), that needs some form of transformation/compilation to run in the browser.
LiveCodes provides support for a wide range of languages, which include (but not limited to):
- Syntax used by web libraries/frameworks (e.g. JSX, TSX, Vue SFC, Svelte SFC, MDX, Astro).
- Languages that transpile to JavaScript (e.g. TypeScript, CoffeeScript, LiveScript, ReScript).
- Languages/frameworks that generate CSS (e.g. SCSS, Less, Stylus, Tailwind CSS, UnoCSS).
- CSS processors (e.g. PostCSS, Autoprefixer, Lightning CSS, CSS Modules, cssnano)
- Traditional programming languages (e.g. Python, Ruby, Go, PHP, C++, R, Lua, Scheme, Perl).
- Data manipulation/logic languages (e.g. SQL, Prolog).
- Authoring/templating languages (e.g Markdown, AsciiDoc, Pug, Handlebars, Haml).
- Low-code/visual editors (e.g. blockly, rich text editor).
- Modeling languages/diagram-as-code (e.g. Gnuplot, Graphviz, Mermaid, Vega, Plotly).
- Languages that target WebAssembly (e.g. AssemblyScript, WebAssembly Text Format)
- ... and others.
Below is the full list of supported languages with documentations for usage in LiveCodes.
## Language List
```mdx-code-block
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
 item.docId !== 'languages/index')}/>
```
---
# art-template
[art-template](https://aui.github.io/art-template/) is a high performance JavaScript templating engine.
## Usage
There are 2 modes for rendering:
### Pre-rendered (Default)
The values of the expressions are evaluated and added to the template during compilation of the [result page](../features/result.html.md).
The values of all expressions should be supplied in advance using [custom settings](../advanced/custom-settings.html.md) to the property `template.data` which accepts an object of key-value pairs.
Example: This provides the value of the expression `name`
```json title="Custom Settings"
{
  "template": {
    "data": {
      "name": "LiveCodes"
    }
  }
}
```
[Full example below](#pre-rendered)
### Dynamic
To use this mode, the property `template.prerender` in [custom settings](../advanced/custom-settings.html.md) should be set to `false`.
Example:
```json title="Custom Settings"
{
  "template": {
    "prerender": false
  }
}
```
In this mode, in addition to values supplied in custom settings (see above), expressions can have values that are evaluated during the [result page](../features/result.html.md) runtime.
This can be achieved in JavaScript (or any [language](../languages/index.html.md) that compiles to it) by assigning `window.livecodes.templateData` to an object with the data.
Please note that template rendering occurs on [page load](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event), so the assignment must occur before that.
Example:
```js title="Script Editor (JS)"
window.livecodes.templateData = { name: 'LiveCodes' };
```
[Full example below](#dynamic-1)
## Language Info
### Name
`art-template`
### Extensions
`.art`, `.art-template`
### Editor
`markup`
## Compiler
The official [art-template compiler](https://www.npmjs.com/package/art-template).
### Version
`art-template`: v4.13.2
## Code Formatting
Using [Prettier](https://prettier.io/).
## Custom Settings
[Custom settings](../advanced/custom-settings.html.md) added to the property `art-template` are passed as a JSON object to the [`compile`](https://aui.github.io/art-template/docs/api.html#compile-source-options) method during compile. Please check the [documentation](https://aui.github.io/art-template/docs/options.html) for full reference.
Please note that custom settings should be valid JSON (i.e. functions are not allowed).
**Example:**
```json title="Custom Settings"
{
  "art-template": {
    "minimize": false
  }
}
```
## Example Usage
import LiveCodes from '../../src/components/LiveCodes.tsx';
### Pre-rendered
export const config = {
  markup: { language: 'art-template', content: 'Hello {{name}}!' },
  customSettings: { template: { data: { name: 'LiveCodes' } } },
};
export const params = { compiled: 'open' };
Hello {name}!
```
---
### Dynamic
To enable runtime rendering, configure the page as a server-rendered route or use an Astro server adapter (e.g., Node, Deno, or Vercel).
In this mode, values can be provided dynamically during request handling.
**Example:** Create a server-side API endpoint:
```js
export async function GET() {
  return new Response(JSON.stringify({ name: 'LiveCodes' }), {
    headers: { 'Content-Type': 'application/json' },
  });
}
```
Then fetch and render it dynamically in Astro:
```astro
---
const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
const data = await res.json();
---
Hello {data.name}!
```
---
## Language Info
### Name
`astro`
### Extension
`astro`
## Editor
`markup`
## Compiler
Astro compiler
### Version
`@astrojs/compiler`: `v2.2.8`
## Code Formatting
Using [Prettier](https://prettier.io/).
---
## Example Usage
### Static Example
```astro
---
const message = "Hello from Astro!";
---
{message}
```
### Dynamic Example
```astro
---
const res = await fetch('https://api.example.com/data');
const data = await res.json();
---
{data.title}
```
## Links
- [Astro Documentation](https://docs.astro.build)
- [Astro Starter Template](https://livecodes.io/?template=astro)
---
# Autoprefixer
TODO...
---
# Babel
[Babel](https://babeljs.io/) is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.
## Language Info
### Name
`babel`
### Extensions
`.es`, `.babel`
### Editor
`script`
## Compiler
The official [`@babel/standalone` compiler](https://babeljs.io/docs/babel-standalone).
### Version
`@babel/standalone`: v7.24.7
## Custom Settings
[Custom settings](../advanced/custom-settings.html.md) added to the property `babel` are passed as a JSON object to the [`Babel.transform`](https://babeljs.io/docs/babel-standalone#api) method during compile. Please check the [documentation](https://babeljs.io/docs/babel-core/) for full reference.
By default, the following configuration is used:
```json
{
  "babel": { "presets": [["env", { "modules": false }], "typescript", "react"] }
}
```
Please note that custom settings should be valid JSON (i.e. functions are not allowed).
## Example Usage
import LiveCodes from '../../src/components/LiveCodes.tsx';
export const params = {
  babel:
    'export const numbers = [1, 2, 3].map((x) => x * 2);\n\nexport const Greet = (name: string) => <>Hello {name}!>;\n',
  compiled: 'open',
};
In LiveCodes, it runs in the browser using
[Cherry](https://github.com/squint-cljs/cherry).
:::info Note
Lisp language family supported in LiveCodes includes [Common Lisp](./commonlisp.html.md), [Scheme](./scheme.html.md), [ClojureScript](./clojurescript.html.md) and [Fennel](./fennel.html.md).
:::
## Language Info
### Name
`clojurescript`
### Extensions
`cljs`, `cljc`, `clj`, `edn`, `clojure`
### Editor
`script`
## Compiler
[Cherry](https://github.com/squint-cljs/cherry)
If `JSX` is used (using `#jsx` reader tag - [example](https://github.com/squint-cljs/cherry/blob/60adcf6e3a8fb940a80c6a193599da0272fe3058/examples/jsx/pages/component.cljs)), it is also compiled ([JSX](./jsx.html.md)). See [example usage](#example-usage).
### Version
`cherry-cljs`: v0.2.18
## Code Formatting
Using [Parinfer](https://shaunlebron.github.io/parinfer/).
## Example Usage
import LiveCodes from '../../src/components/LiveCodes.tsx';
export const params = {
  cljs: `(ns demo\n${'  '};; you can use npm modules\n${'  '}(:require ["canvas-confetti$default" :as confetti]))\n\n(let [el (js/document.getElementById "test")]\n${'  '}(.addEventListener el "click"\n ${'   '}(fn []\n ${'     '}(confetti)\n${'      '}(println "test"))))\n`,
  html: '',
  console: 'open',
};
  
```css
:global .page {
  padding: 20px;
}
.text {
  color: black;
  font-family: sans-serif;
}
.small-text {
  composes: text;
  font-size: 20px;
}
.large-text {
  composes: text;
  font-size: 40px;
}
.large-text:hover {
  color: red;
}
.title {
  composes: large-text;
  color: green;
}
```
   
  
```css
.page {
  padding: 20px;
}
._text_1ygro_9 {
  color: black;
  font-family: sans-serif;
}
._small-text_1ygro_19 {
  font-size: 20px;
}
._large-text_1ygro_29 {
  font-size: 40px;
}
._large-text_1ygro_29:hover {
  color: red;
}
._title_1ygro_47 {
  color: green;
}
```
   
  
```json
{
  "text": "_text_1ygro_9",
  "small-text": "_small-text_1ygro_19 _text_1ygro_9",
  "large-text": "_large-text_1ygro_29 _text_1ygro_9",
  "title": "_title_1ygro_47 _large-text_1ygro_29 _text_1ygro_9",
  "smallText": "_small-text_1ygro_19 _text_1ygro_9",
  "largeText": "_large-text_1ygro_29 _text_1ygro_9"
}
```
   
  
```html
  Page Title
  
    Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore earum blanditiis quidem non
    beatae ipsam autem maiores ut et delectus unde repudiandae, repellendus aut. Aspernatur
    similique facere facilis minima tempora.
  
```
   
  
```html
  Page Title
  
    Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore earum blanditiis quidem non
    beatae ipsam autem maiores ut et delectus unde repudiandae, repellendus aut. Aspernatur
    similique facere facilis minima tempora.
  
```
   
 
In the script editor, the JSON object representing the transformed classes can be imported from the relative URLs `'./style.module.css'` or `'./styles.module.css'`.
[Default](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#default_import), [named](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#named_import) and [namespace](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#namespace_import) imports are supported. Class names are also available in camelCase (e.g `.large-text` becomes `largeText`). This can be changed by setting [`localsConvention`](https://github.com/madyankin/postcss-modules#localsconvention) in [custom settings](#custom-settings).
**Example:**
```js title="In script editor (using JS in this case):"
import classes from './style.module.css';
import { smallText } from './styles.module.css';
import * as allClasses from './styles.module.css';
console.log(classes.title);
// .small-text -> smallText
console.log(smallText);
// .large-text -> largeText
console.log(allClasses.largeText);
// bracket notation for class with dash
console.log(allClasses['large-text']);
```
For full example, see [example usage](#example-usage) below.
:::info
CSS Modules has to be enabled (from style editor menu), to be able to import classes in the script editor.
Importing a URL that does not include `.module` (e.g. `./style.css`) gets the processed CSS **string** as the module's default export.
The extension of the style editor language can also be used, in addition to `.css`. For example, when using SCSS, importing from any of the following URLs is the same:
- `./style.module.css`
- `./styles.module.css`
- `./style.module.scss`
- `./styles.module.scss`
:::
## Language Info
### Name
`cssmodules`
### Type
[Processor](../features/css.html.md)#css-processors)
### Editor
`style`
## Compiler
The CSS Modules processor is provided using [postcss-modules](https://github.com/madyankin/postcss-modules) as a [PostCSS](./postcss.html.md) plugin.
### Version
`postcss-modules`: v6.0.1
## Custom Settings
[Custom settings](../advanced/custom-settings.html.md) added to the property `cssmodules` are passed as a JSON object to the `postcss-modules` plugin during compile. Please check the [documentation](https://github.com/madyankin/postcss-modules#usage) for full reference.
In addition, the following settings are available:
- `addClassesToHTML`
  Type: `boolean`. Default: `true`.
  The generated classes are injected into the HTML elements, so the styles are applied without having to assign them using JavaScript.
- `removeOriginalClasses`
  Type: `boolean`. Default: `false`.
  When enabled, the original classes are removed from HTML, keeping only the generated classes. Only applies if `addClassesToHTML` is enabled.
Please note that custom settings should be valid JSON (i.e. functions are not allowed).
**Example:**
```json
{
  "cssmodules": {
    "exportGlobals": true,
    "localsConvention": "camelCaseOnly",
    "addClassesToHTML": false
  }
}
```
## Limitations
Currently, loading external sources in [`composes`](https://github.com/css-modules/css-modules#composing-from-other-files) is not supported.
```css
/* you cannot do this */
.title {
  composes: title from 'https://example.com/styles.css';
}
```
If you get this working, [please create a pull request](https://github.com/live-codes/livecodes/pulls).
## Example Usage
import LiveCodes from '../../src/components/LiveCodes.tsx';
export const params = {
  activeEditor: 'style',
  html: '\n Page Title
\n Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore earum blanditiis quidem non beatae ipsam autem maiores ut et delectus unde repudiandae, repellendus aut. Aspernatur similique facere facilis minima tempora.
\n\n',
  css: ':global .page {\n padding: 20px;\n}\n\n.text {\n color: black;\n font-family: sans-serif;\n}\n\n.small-text {\n composes: text;\n font-size: 20px;\n}\n\n.large-text {\n composes: text;\n font-size: 40px;\n}\n\n.large-text:hover {\n color: red;\n}\n\n.title {\n composes: large-text;\n color: green;\n}\n',
  js: "import classes from './style.module.css';\n\ndocument.querySelector('h1').className = classes.title;\nconsole.log(classes);\n",
  processors: 'cssmodules',
  compiled: 'open',
};
Open starter template in LiveCodes 
## Usage
This code: (Steps
#### 1. Add a diagram target:
The target element should have a `data-src` attribute.
It can be an HTML element (the SVG of the diagram will be embedded as a child element)
```html
```
becomes
```html
```
or an HTML image element (the diagram will be added to its `src` attribute as a [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs))
```html
![]() ```
becomes
```html
```
becomes
```html
 ```
There can be more that one target element for the same diagram if they have the same `data-src` attribute.
```html
```
There can be more that one target element for the same diagram if they have the same `data-src` attribute.
```html
![]() ```
#### 2. Add a script element with the diagram syntax:
It should have:
- an attribute `type="application/diagram-{diagram type}"` that specifies the diagram type (e.g. `type="application/diagram-mermaid"`).
- a `data-output` attribute that matches the `data-src` attribute of the target element.
- the syntax of the diagram is the content of the script element or the content of a file linked by the `src` attribute.
```html
```
## Supported Libraries
### [Cytoscape](https://js.cytoscape.org/)
The diagram syntax is JSON representing [Cytoscape options](https://js.cytoscape.org/#getting-started/specifying-basic-options).
Please note that reference to JavaScript objects cannot be used.
```
#### 2. Add a script element with the diagram syntax:
It should have:
- an attribute `type="application/diagram-{diagram type}"` that specifies the diagram type (e.g. `type="application/diagram-mermaid"`).
- a `data-output` attribute that matches the `data-src` attribute of the target element.
- the syntax of the diagram is the content of the script element or the content of a file linked by the `src` attribute.
```html
```
## Supported Libraries
### [Cytoscape](https://js.cytoscape.org/)
The diagram syntax is JSON representing [Cytoscape options](https://js.cytoscape.org/#getting-started/specifying-basic-options).
Please note that reference to JavaScript objects cannot be used.
 e.g. do not use `{container: document.getElementById('cy')}`.
Example: (
ELK text format is not supported! (You may use [this tool](https://rtsys.informatik.uni-kiel.de/elklive/conversion.html) to convert formats)
Example: ().
Fennel code is compiled to Lua, which then runs in the browser using [Fengari](https://fengari.io/). See documentation for Lua language support in LiveCodes [here](./lua.html.md).
:::info Note
Lisp language family supported in LiveCodes includes [Common Lisp](./commonlisp.html.md), [Scheme](./scheme.html.md), [ClojureScript](./clojurescript.html.md) and [Fennel](./fennel.html.md).
:::
## Usage
JavaScript interoperability and DOM access is achieved using [`"js"` module](https://github.com/fengari-lua/fengari-interop).
import LiveCodes from '../../src/components/LiveCodes.tsx';
This example demonstrates usage, JavaScript interoperability and DOM access:
Hello, LiveCodes!
This is a paragraph in HTML.
  - Simple
- Structured
- Semantic
`,
  },
}You clicked {count} times.
  
`,
};
Custom Root Element
...other page content
`,
  },
  script: {
    language: 'svelte',
    content: `\n
I'm a {name} component
`,
  },
};
You clicked {{ count }} times.
\n    \n  \n\n`,
};
Custom Root Element
...other page content
`,
  },
  script: {
    language: 'vue',
    content: `I'm a Vue SFC`,
  },
};
Hello, World!
  
  
`,
  css: `.container {
  max-width: 600px;
  margin: 50px auto;
  text-align: center;
  font-family: Arial, sans-serif;
}
h1 {
  color: #007bff;
  font-size: 2.5rem;
}
input {
  padding: 10px;
  font-size: 1rem;
  margin: 10px;
  border: 2px solid #007bff;
  border-radius: 5px;
}
button {
  padding: 10px 20px;
  font-size: 1rem;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
button:hover {
  background-color: #0056b3;
}
`,
  js: `const greeting = document.getElementById('greeting');
const nameInput = document.getElementById('nameInput');
const greetBtn = document.getElementById('greetBtn');
greetBtn.addEventListener('click', () => {
  const name = nameInput.value.trim();
  if (name) {
    greeting.textContent = \`Hello, \${name}!\`;
  } else {
    greeting.textContent = 'Hello, World!';
  }
});
`,
};
# Getting Started Guide
This guide will walk you through creating your first project in LiveCodes.
Try the completed project below:
{gettingStartedParams.html} 
### CSS Panel
{gettingStartedParams.css} 
### JavaScript Panel
{gettingStartedParams.js} 
## Step 3: See Your Results
The result panel automatically updates as you type. Try:
- Entering your name in the input field
- Clicking the "Greet Me!" button
- Modifying the colors in the CSS
## Step 4: Save Your Project
1. Click on the "**Project**" menu button in the toolbar
2. Click "**Save**" to save the project (on this device)
3. You can open it later from "**Project menu > Open**"
4. Use "**Project menu > Share**" to get a permanent URL to your project that you can share
## Congratulations!
You've just built your first interactive app with LiveCodes!
Compare your version with the completed project above. Did you add any personal touches?
Color Generator
  
    #3498db
  
  
  Click the button to generate a random color!
`,
  css: `body {
  margin: 0;
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: #3498db;
  transition: background 0.5s ease;
}
.container {
  text-align: center;
  background: white;
  padding: 40px;
  border-radius: 20px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
h1 {
  margin: 0 0 30px 0;
  color: #333;
}
.color-display {
  background: #f0f0f0;
  padding: 30px;
  border-radius: 10px;
  margin-bottom: 30px;
}
#colorCode {
  font-size: 2rem;
  font-weight: bold;
  font-family: 'Courier New', monospace;
  color: #333;
}
#generateBtn {
  background: #333;
  color: white;
  border: none;
  padding: 15px 40px;
  font-size: 1.1rem;
  border-radius: 10px;
  cursor: pointer;
  transition: transform 0.2s;
}
#generateBtn:hover {
  transform: scale(1.05);
}
#generateBtn:active {
  transform: scale(0.95);
}
.hint {
  margin-top: 20px;
  color: #666;
  font-size: 0.9rem;
}
`,
  js: `const colorDisplay = document.getElementById('colorDisplay');
const colorCode = document.getElementById('colorCode');
const generateBtn = document.getElementById('generateBtn');
function getRandomColor() {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}
function updateColor() {
  const newColor = getRandomColor();
  document.body.style.background = newColor;
  colorCode.textContent = newColor;
}
generateBtn.addEventListener('click', updateColor);
// Generate a color on page load
updateColor();
`,
};
# Building Your First App
Learn how to build a simple color generator app using LiveCodes. This app will let users click a button to generate random background colors.
Try the completed project below:
{colorGeneratorParams.html} 
### Styling
{colorGeneratorParams.css} 
### JavaScript Logic
{colorGeneratorParams.js} 
## How It Works
1. **HTML**: Creates a simple layout with a color display and button
2. **CSS**: Styles the interface and adds smooth transitions
3. **JavaScript**:
   - `getRandomColor()`: Generates a random hex color
   - `updateColor()`: Changes the background and displays the color code
   - Event listener: Triggers color change on button click
## Testing Your App
Try these features:
1. Click "Generate Color" multiple times
2. Watch the smooth color transitions
3. See the color code update
4. Notice the button hover and click effects
## Challenge: Enhance Your App
Try adding these features:
- Copy color code to clipboard when clicked
- Add a history of recent colors
- Let users save their favorite colors
- Add different color format options (RGB, HSL)
## Congratulations!
You've just built your color generator app with LiveCodes!
Compare your version with the completed project above. Did you add any personal touches?
or manually create a new bookmark in your browser and add this code as its URL:
```js
javascript:(()=>{window.open("https://livecodes.io/?x="+encodeURIComponent(location.href),"_blank");})();
```
## Example Usage
After adding the bookmarklet to your browser (see above), open this GitHub directory:
https://github.com/bradtraversy/50projects50days/tree/master/expanding-cards
Then click on the bookmarklet.
LiveCodes playground should open in a new window and [import](./features/import.html.md) the directory files (each file in the appropriate editor). It just works!
---
# GitHub Action ⚡
The [Preview in LiveCodes](https://github.com/live-codes/preview-in-livecodes) GitHub Action generates preview links to playgrounds for code changes in pull requests and posts them as pull request comments.
Once added to a repo, it runs when a pull request is created or updated. The new code is optionally built. The action posts in a pull request comment links to playgrounds that can use the new code.
**Screenshot:**

For usage and more information, see the [action docs](https://github.com/live-codes/preview-in-livecodes) on GitHub. Also check the [example repo](https://github.com/hatemhosny/preview-in-livecodes-demo) for a working demo.
---
# Markdown to LiveCodes
Markdown and MDX code blocks can be easily converted to interactive LiveCodes playgrounds.
The playgrounds can run any of the supported [languages](./languages/index.html.md) in LiveCodes, and can be customized to any of the [configuration options](./configuration/index.html.md).
A fenced code block in Markdown can be rendered as a LiveCodes playground by adding the `livecodes` parameter to the code block language meta.
This is provided as [plugins](#packages) for [markdown-it](https://github.com/markdown-it/markdown-it), [marked](https://github.com/markedjs/marked) and [remark](https://github.com/remarkjs/remark).
These plugins allow the seamless integration with most of the popular frameworks like Astro, Docusaurus, Next.js, Storybook, VitePress, etc. See the section "[Using with Frameworks](#using-with-frameworks)" for getting started.
## Demo
This is an example code block:
````md
```jsx
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
````
The above code block is normally rendered like this:
```jsx
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
The code block can instead be rendered as an interactive playground by adding the `livecodes` parameter to the code block language meta:
````md {1}
```jsx livecodes
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
````
to be displayed like this:
```jsx livecodes
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
The playground can be customized by setting [options](#options) that are applied to all code blocks or by [meta parameters](#meta-parameters) that are applied to individual code blocks.
Alternatively, the code block can be kept as it is, and a button or a link (**Edit in LiveCodes**) is appended, below the code block, that opens the code in a LiveCodes playground.
This is achieved by adding the `render=button` or `render=link` parameter to the code block language meta.
This displays a button:
````md {1}
```jsx livecodes render=button
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
````
```jsx livecodes render=button
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
While this displays a link:
````md {1}
```jsx livecodes render=link
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
````
```jsx livecodes render=link
import { useState } from "react";
function App() {
  const [count, setCount] = useState(0);
  return (
    
      You clicked {count} times.
      
    
  );
}
export default App;
```
## Packages
All the functionality described here can be achieved using *any* of the following packages:
- [`markdown-it-livecodes`](https://www.npmjs.com/package/markdown-it-livecodes): A [markdown-it](https://github.com/markdown-it/markdown-it) plugin.
- [`marked-livecodes`](https://www.npmjs.com/package/marked-livecodes): A [marked](https://github.com/markedjs/marked) plugin.
- [`remark-livecodes`](https://www.npmjs.com/package/remark-livecodes): A [remark](https://github.com/remarkjs/remark) plugin.
- [`gatsby-remark-livecodes`](https://www.npmjs.com/package/gatsby-remark-livecodes): A [gatsby](https://github.com/gatsbyjs/gatsby) plugin.
See the section "[Using with Frameworks](#using-with-frameworks)" for using the plugins with popular frameworks like Astro, Docusaurus, Next.js, Storybook, VitePress, etc.
## Usage
### markdown-it-livecodes
To use the `markdown-it-livecodes` plugin, first install it:
```bash npm2yarn
npm install markdown-it markdown-it-livecodes
```
Then it can be used like this:
````js
import markdownIt from "markdown-it";
import markdownItLivecodes from "markdown-it-livecodes";
const input = "```js livecodes \nconsole.log('Hello World!');\n```";
const output = markdownIt()
  .use(markdownItLivecodes, {
    /* options */
  })
  .render(input);
console.log(output); // 
````
### marked-livecodes
To use the `marked-livecodes` plugin, first install it:
```bash npm2yarn
npm install marked marked-livecodes
```
Then it can be used like this:
````js
import marked from "marked";
import markedLivecodes from "marked-livecodes";
const input = "```js livecodes \nconsole.log('Hello World!');\n```";
const output = await marked
  .use(markedLivecodes, {
    /* options */
  })
  .parse(input);
console.log(output); // 
````
### remark-livecodes
To use the `remark-livecodes` plugin, first install it:
```bash npm2yarn
npm install remark remark-livecodes
```
Then it can be used like this:
````js
import { remark } from "remark";
import remarkLivecodes from "remark-livecodes";
const input = "```js livecodes \nconsole.log('Hello World!');\n```";
const output = await remark()
  .use(remarkLivecodes, {
    /* options */
  })
  .process(input);
console.log(String(output)); // 
````
### gatsby-remark-livecodes
See usage with [Gatsby](#gatsby).
## Options
Options can be passed to the plugins. These options apply to all code blocks.
These options include LiveCodes SDK [embed options](./sdk/js-ts.html.md)#embed-options) (except `headless`).
Example:
````js
const output = await remark()
  .use(remarkLivecodes, {
    // highlight-start
    loading: "click",
    params: {
      console: "open"
      theme: "light",
    }
    // highlight-end
  })
  .process(input);
````
In addition, the following options are also available:
- `render`: The render mode for the LiveCodes playgrounds. This can be one of the following:
  - `playground` (default): Replaces the code block with an iframe that displays the LiveCodes playground. By default, [`"simple"` mode](./features/display-modes.html.md) is used, but this can be changed in [options](#options) or [meta parameters](#meta-parameters).
  - `link`: Keeps the code block as it is, and appends a link (**Edit in LiveCodes**), below the code block, that opens the code in a LiveCodes playground.
  - `button`: Keeps the code block as it is, and appends a button (Edit in LiveCodes), below the code block, that opens the code in a LiveCodes playground.
     - `meta`: Keeps the code block as it is, and adds the URL of the playground to the `data-livecodes-url` attribute of the `
  - `meta`: Keeps the code block as it is, and adds the URL of the playground to the `data-livecodes-url` attribute of the `` element. In addition, in `remark-livecodes` the URL is added to the AST (`node.data.livecodesUrl` and `node.data.hProperties.dataLivecodesUrl`). In `markdown-it-livecodes` the URL is added to `env.livecodesUrl`.
    This can be used by other plugins (e.g. to display a custom run button overlying the code block).
- `height`: The height of the playground iframe.
- `className`: The class name to be applied to the iframe, link or button.
  Note: If the class name of the button contains `"dark"` (e.g. `"dark-btn"`), the dark button will be used.
   - `auto`: When set to `true`, it automatically enables the `livecodes` parameter for all code blocks without having to explicitly add it.
  This is useful when you have a large number of code blocks and don't want to add the `livecodes` parameter to each code block.
  To disable this for a specific code block, add the `livecodes=false` [meta parameter](#meta-parameters) to the code block.
## Meta Parameters
Individual code blocks can be configured using meta parameters. These are key/value pairs, separated by spaces, that are added after the language name.
Meta parameters of code blocks override the [options](#options) passed to the plugin.
Example:
````markdown {1}
```jsx livecodes render=button className=dark-btn console=open
import { useState, useEffect } from "react";
export default () => {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log("count:", count);
  }, [count]);
  return (
- `auto`: When set to `true`, it automatically enables the `livecodes` parameter for all code blocks without having to explicitly add it.
  This is useful when you have a large number of code blocks and don't want to add the `livecodes` parameter to each code block.
  To disable this for a specific code block, add the `livecodes=false` [meta parameter](#meta-parameters) to the code block.
## Meta Parameters
Individual code blocks can be configured using meta parameters. These are key/value pairs, separated by spaces, that are added after the language name.
Meta parameters of code blocks override the [options](#options) passed to the plugin.
Example:
````markdown {1}
```jsx livecodes render=button className=dark-btn console=open
import { useState, useEffect } from "react";
export default () => {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log("count:", count);
  }, [count]);
  return (
    
      You clicked {count} times.
      
    
  );
};
```
````
All LiveCodes [configuration query parameters](./configuration/query-params.html.md) can be used as code block meta parameters (e.g. ` ```js livecodes console=open theme=light`). See the [LiveCodes configuration docs](./configuration/configuration-object.html.md) for more information.
In addition, the following meta parameters are available:
- `livecodes`: Enables the LiveCodes playground for the code block. This can be omitted if the `auto` option is set to `true`. When `livecodes` is set to `false`, the code block is not handled by the plugin.
- `render`: The render mode. See the [Options](#options) section for more information.
- `height`: The height of the playground iframe.
- `className`: The class name for the playground iframe, link or button.
- `lang`: This overrides the language of the code block (e.g. ` ```jsx livecodes lang=react` or ` ```py livecodes lang=py-wasm`). See the [Languages](./languages/index.html.md) docs for more language information.
## Using with Frameworks
This guide shows how to use the suitable plugin in different frameworks.
### Astro
([demo](https://markdown-to-livecodes-astro.pages.dev/) - [code on GitHub](https://github.com/hatemhosny/markdown-to-livecodes-astro))
Install the `remark-livecodes` plugin:
```bash npm2yarn
npm install -D remark-livecodes
```
This is an example for adding the `remark-livecodes` plugin to `astro.config.mjs` file:
```js title="astro.config.js"
import { defineConfig } from "astro/config";
import mdx from "@astrojs/mdx";
import remarkLivecodes from "remark-livecodes";
export default defineConfig({
  // ...
  integrations: [mdx()],
  markdown: {
    remarkPlugins: [
      [remarkLivecodes, { /* options */ }],
    ],
  },
});
```
### Docusaurus
([demo](https://markdown-to-livecodes-docusaurus.pages.dev/) - [code on GitHub](https://github.com/hatemhosny/markdown-to-livecodes-docusaurus))
Install the `remark-livecodes` plugin:
```bash npm2yarn
npm install -D remark-livecodes
```
This is an example for adding the `remark-livecodes` plugin to `docusaurus.config.js` file:
```js title="docusaurus.config.js"
export default {
  presets: [
    [
      'classic',
      {
        docs: {
          // ...
          remarkPlugins: [
            [require('remark-livecodes'), { /* options */ }],
          ],
        },
      },
    ],
  ],
  // ...
};
```
### Eleventy
([demo](https://markdown-to-livecodes-11ty.pages.dev/) - [code on GitHub](https://github.com/hatemhosny/markdown-to-livecodes-11ty))
Install the `markdown-it-livecodes` plugin:
```bash npm2yarn
npm install -D markdown-it-livecodes
```
This is an example for adding the `markdown-it-livecodes` plugin to `eleventy.config.js` file:
```js title="eleventy.config.js"
import markdownItLivecodes from "markdown-it-livecodes";
export default async function (eleventyConfig) {
  eleventyConfig.amendLibrary("md", (mdLib) =>
    mdLib.use(markdownItLivecodes, { /* options */ }),
  );
  // ...
}
```
### Gatsby
([demo](https://markdown-to-livecodes-gatsby.pages.dev/markdown-to-livecodes/) - [code on GitHub](https://github.com/hatemhosny/markdown-to-livecodes-gatsby))
Install the `gatsby-remark-livecodes` plugin:
```bash npm2yarn
npm install -D gatsby-remark-livecodes
```
This is an example for adding the `gatsby-remark-livecodes` plugin to `gatsby-config.js` file:
```js title="gatsby-config.js"
module.exports = {
  // ...
  plugins: [
    // ...
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        plugins: [
          {
            resolve: 'gatsby-remark-livecodes',
            options: { /* options */ },
          },
        ],
      },
    },
  ],
};
```
### Next.js
([demo](https://markdown-to-livecodes-nextjs.pages.dev/mdx-page) - [code on GitHub](https://github.com/hatemhosny/markdown-to-livecodes-nextjs))
See [Next.js docs](https://nextjs.org/docs/app/guides/mdx) for using markdown and MDX in Next.js.
Install the `remark-livecodes` plugin:
```bash npm2yarn
npm install -D remark-livecodes
```
This is an example for adding the `remark-livecodes` plugin to `next.config.js` file:
```js title="next.config.js"
import createMDX from "@next/mdx";
import remarkLivecodes from "remark-livecodes";
const nextConfig = {
  // ...
  pageExtensions: ["js", "jsx", "md", "mdx", "ts", "tsx"],
};
const withMDX = createMDX({
  options: {
    remarkPlugins: [
      [remarkLivecodes, { /* other options */ }],
    ],
  },
});
export default withMDX(nextConfig);
```
When using Turbopack for local development, check the guide for [using plugins with Turbopack](https://nextjs.org/docs/app/guides/mdx#using-plugins-with-turbopack).
### react-markdown
`react-markdown` is a React component to render markdown.
This is an example for using the `remark-livecodes` plugin with `react-markdown`:
Install the `remark-livecodes` plugin:
```bash npm2yarn
npm install remark-livecodes
```
```jsx title="App.jsx" livecodes render=button
import Markdown from 'react-markdown';
import remarkLivecodes from 'remark-livecodes';
const markdown =
  '```jsx livecodes\nexport default () => Hello World
\n```';
export default () => (
  
    {markdown}
   
);
```
### Storybook
([demo](https://markdown-to-livecodes-storybook.pages.dev/) - [code on GitHub](https://github.com/hatemhosny/markdown-to-livecodes-storybook))
Install the `remark-livecodes` plugin:
```bash npm2yarn
npm install -D remark-livecodes
```
This is an example for adding the `remark-livecodes` plugin to `storybook/main.js` file:
```js title="storybook/main.js"
import remarkLivecodes from "remark-livecodes";
export default {
  // ...
  addons: [
    // ...
    {
      name: "@storybook/addon-docs",
      options: {
        mdxPluginOptions: {
          mdxCompileOptions: {
            remarkPlugins: [
              [remarkLivecodes, { /* options */ }],
            ],
          },
        },
      },
    },
  ],
};
```
### VitePress
([demo](https://markdown-to-livecodes-vitepress.pages.dev/) - [code on GitHub](https://github.com/hatemhosny/markdown-to-livecodes-vitepress))
Install the `markdown-it-livecodes` plugin:
```bash npm2yarn
npm install -D markdown-it-livecodes
```
This is an example for adding the `markdown-it-livecodes` plugin to `vitepress.config.js` file:
```js title=".vitepress/config.js"
import { defineConfig } from "vitepress";
import markDownItLivecodes from "markdown-it-livecodes";
export default defineConfig({
  // ...
  markdown: {
    config: (md) => {
      md.use(markDownItLivecodes, { /* options */ });
    },
  },
});
```
---
# Contribution
Contributions are always welcome, no matter how large or small. Before contributing,
please read the [code of conduct](https://github.com/live-codes/livecodes/blob/HEAD/CODE_OF_CONDUCT.md).
For code contribution, please refer to the [contribution guide](https://github.com/live-codes/livecodes/blob/HEAD/CONTRIBUTING.md)
.
For financial and in-kind contributions, please refer to the [sponsor page](./sponsor.html.md).
You can always support the project by [giving feedback](https://github.com/live-codes/livecodes/discussions), [reporting issues, suggesting features](https://github.com/live-codes/livecodes/issues) and spreading the word.
Thank you :)
---
# Credits
## Services
LiveCodes uses services that are generously provided by:
## Third Party Packages
Packages used by LiveCodes and their licenses are [listed here](https://github.com/live-codes/livecodes/blob/develop/vendor-licenses.html.md).
## Prior Art
Many of LiveCodes features/ideas were inspired by:
- [CodePen](https://codepen.io/)
- [JSFiddle](https://jsfiddle.net/)
- [JS Bin](https://jsbin.com/)
- [CodeSandbox](https://codesandbox.io/)
- [Replit](https://replit.com/)
- [VS Code](https://code.visualstudio.com/)
- [Monacode](https://github.com/lukejacksonn/monacode/)
Thank you ❤️
---
# License
LiveCodes is released under the permissive [MIT License](https://github.com/live-codes/livecodes/blob/develop/LICENSE) © [Hatem Hosny](https://github.com/hatemhosny).
Third party packages used in LiveCodes and their licenses are [listed here](https://github.com/live-codes/livecodes/blob/develop/vendor-licenses.md).
The source code is available on [GitHub](https://github.com/live-codes/livecodes).
Please consider [sponsoring LiveCodes](./sponsor.html.md) to support its maintenance and continued development.
---
import MailLink from '../src/components/MailLink.tsx';
# Sponsor LiveCodes
Thank you for considering becoming a sponsor of LiveCodes! 💚
LiveCodes is a feature-rich, open source code playground with a wide range of language support. With LiveCodes, learning, prototyping, experimenting, documenting, teaching, and sharing code is easier and more enjoyable than ever.
LiveCodes is free, with no limits for use, no ads and no account required. The MIT license allows anyone to use (including commercial use), modify, and distribute.
As a sponsor of LiveCodes, you will be supporting the ongoing development and maintenance of the project, as well as helping to ensure that it remains a valuable resource for the developer community. In return, you will receive recognition as a sponsor on the documentation website, GitHub repo and social media channels, as well as the opportunity to engage with our community of users and contributors.
There are several ways to support LiveCodes as a sponsor:
### Financial Contributions
LiveCodes relies on the support of sponsors like you to fund its ongoing development and maintenance. Your financial contribution will help to ensure that the project remains sustainable in the long term.
Payments can be done via:
- [GitHub Sponsors](https://github.com/sponsors/live-codes/)
- [PayPal](https://paypal.me/hatemhosni)
- [Ko-fi](https://ko-fi.com/hatemhosny)
Both monthly-recurring sponsorships and one-time donations are accepted. Recurring sponsorships are entitled to logo placements as specified in [Sponsorship Benefits](#sponsorship-benefits).
If you have questions, please reach out to  
If you are interested in becoming a sponsor of LiveCodes, please don't hesitate to 
---
# Display Mode: full
import LiveCodes from '../../../src/components/LiveCodes.tsx';
 & string) \| undefined; headless?: boolean \| undefined; import?: string \| undefined; ... 485 more ...; compiled?: "" \| ... 5 more ... \| undefined; \} \| undefined
An object that represents the [URL Query parameters](https://livecodes.io/docs/configuration/query-params), that can be used to configure the playground.
These 2 snippets produce similar output:
```js
import { createPlayground } from 'livecodes';
// use config
createPlayground('#container', {
  config: {
    markup: {
      language: 'markdown',
      content: '# Hello World!',
    },
  },
});
// use params
createPlayground('#container', { params: { md: '# Hello World!' } });
```
#### perl
> **perl**: `undefined` \| `string`
#### perl-selector
> **perl-selector**: `undefined` \| `string`
#### pg
> **pg**: `undefined` \| `string`
#### pg-selector
> **pg-selector**: `undefined` \| `string`
#### pg.sql
> **sql**: `undefined` \| `string`
#### pg.sql-selector
> **sql-selector**: `undefined` \| `string`
#### pglite
> **pglite**: `undefined` \| `string`
#### pglite-selector
> **pglite-selector**: `undefined` \| `string`
#### pglite.sql
> **sql**: `undefined` \| `string`
#### pglite.sql-selector
> **sql-selector**: `undefined` \| `string`
#### pgsql
> **pgsql**: `undefined` \| `string`
#### pgsql-selector
> **pgsql-selector**: `undefined` \| `string`
#### pgsql.sql
> **sql**: `undefined` \| `string`
#### pgsql.sql-selector
> **sql-selector**: `undefined` \| `string`
#### php
> **php**: `undefined` \| `string`
#### php-selector
> **php-selector**: `undefined` \| `string`
#### php-wasm
> **php-wasm**: `undefined` \| `string`
#### php-wasm-selector
> **php-wasm-selector**: `undefined` \| `string`
#### phpwasm
> **phpwasm**: `undefined` \| `string`
#### phpwasm-selector
> **phpwasm-selector**: `undefined` \| `string`
#### pintora
> **pintora**: `undefined` \| `string`
#### pintora-selector
> **pintora-selector**: `undefined` \| `string`
#### pl
> **pl**: `undefined` \| `string`
#### pl-selector
> **pl-selector**: `undefined` \| `string`
#### plt
> **plt**: `undefined` \| `string`
#### plt-selector
> **plt-selector**: `undefined` \| `string`
#### pm
> **pm**: `undefined` \| `string`
#### pm-selector
> **pm-selector**: `undefined` \| `string`
#### postcss
> **postcss**: `undefined` \| `string`
#### postcss-selector
> **postcss-selector**: `undefined` \| `string`
#### postgre.sql
> **sql**: `undefined` \| `string`
#### postgre.sql-selector
> **sql-selector**: `undefined` \| `string`
#### postgres
> **postgres**: `undefined` \| `string`
#### postgres-selector
> **postgres-selector**: `undefined` \| `string`
#### postgresql
> **postgresql**: `undefined` \| `string`
#### postgresql-selector
> **postgresql-selector**: `undefined` \| `string`
#### postgresql.sql
> **sql**: `undefined` \| `string`
#### postgresql.sql-selector
> **sql-selector**: `undefined` \| `string`
#### preview?
> `optional` **preview**: `boolean`
#### processors?
> `optional` **processors**: `string`
#### prolog
> **prolog**: `undefined` \| `string`
#### prolog-selector
> **prolog-selector**: `undefined` \| `string`
#### prolog.pl
> **pl**: `undefined` \| `string`
#### prolog.pl-selector
> **pl-selector**: `undefined` \| `string`
#### pug
> **pug**: `undefined` \| `string`
#### pug-selector
> **pug-selector**: `undefined` \| `string`
#### py
> **py**: `undefined` \| `string`
#### py-selector
> **py-selector**: `undefined` \| `string`
#### py-wasm
> **py-wasm**: `undefined` \| `string`
#### py-wasm-selector
> **py-wasm-selector**: `undefined` \| `string`
#### py3
> **py3**: `undefined` \| `string`
#### py3-selector
> **py3-selector**: `undefined` \| `string`
#### pyodide
> **pyodide**: `undefined` \| `string`
#### pyodide-selector
> **pyodide-selector**: `undefined` \| `string`
#### python
> **python**: `undefined` \| `string`
#### python-selector
> **python-selector**: `undefined` \| `string`
#### python-wasm
> **python-wasm**: `undefined` \| `string`
#### python-wasm-selector
> **python-wasm-selector**: `undefined` \| `string`
#### pythonwasm
> **pythonwasm**: `undefined` \| `string`
#### pythonwasm-selector
> **pythonwasm-selector**: `undefined` \| `string`
#### pywasm
> **pywasm**: `undefined` \| `string`
#### pywasm-selector
> **pywasm-selector**: `undefined` \| `string`
#### r
> **r**: `undefined` \| `string`
#### r-selector
> **r-selector**: `undefined` \| `string`
#### r-wasm
> **r-wasm**: `undefined` \| `string`
#### r-wasm-selector
> **r-wasm-selector**: `undefined` \| `string`
#### raw?
> `optional` **raw**: [`Language`](../type-aliases/Language.md)
#### rb
> **rb**: `undefined` \| `string`
#### rb-selector
> **rb-selector**: `undefined` \| `string`
#### re
> **re**: `undefined` \| `string`
#### re-selector
> **re-selector**: `undefined` \| `string`
#### react
> **react**: `undefined` \| `string`
#### react-jsx
> **react-jsx**: `undefined` \| `string`
#### react-jsx-selector
> **react-jsx-selector**: `undefined` \| `string`
#### react-native
> **react-native**: `undefined` \| `string`
#### react-native-selector
> **react-native-selector**: `undefined` \| `string`
#### react-native-tsx
> **react-native-tsx**: `undefined` \| `string`
#### react-native-tsx-selector
> **react-native-tsx-selector**: `undefined` \| `string`
#### react-native.jsx
> **jsx**: `undefined` \| `string`
#### react-native.jsx-selector
> **jsx-selector**: `undefined` \| `string`
#### react-native.tsx
> **tsx**: `undefined` \| `string`
#### react-native.tsx-selector
> **tsx-selector**: `undefined` \| `string`
#### react-selector
> **react-selector**: `undefined` \| `string`
#### react-tsx
> **react-tsx**: `undefined` \| `string`
#### react-tsx-selector
> **react-tsx-selector**: `undefined` \| `string`
#### react.jsx
> **jsx**: `undefined` \| `string`
#### react.jsx-selector
> **jsx-selector**: `undefined` \| `string`
#### react.tsx
> **tsx**: `undefined` \| `string`
#### react.tsx-selector
> **tsx-selector**: `undefined` \| `string`
#### readonly?
> `optional` **readonly**: `boolean`
If `true`, editors are loaded in read-only mode, where the user is not allowed to change the code.
By default, when readonly is set to true, the light-weight code editor [CodeJar](https://livecodes.io/docs/features/editor-settings#code-editor) is used.
If you wish to use another editor, set the [editor](https://livecodes.io/docs/configuration/configuration-object#editor) property.
##### Default
```ts
false
```
#### reason
> **reason**: `undefined` \| `string`
#### reason-selector
> **reason-selector**: `undefined` \| `string`
#### recoverUnsaved?
> `optional` **recoverUnsaved**: `boolean`
Enables [recovering last unsaved project](https://livecodes.io/docs/features/recover) when the app is reopened.
##### Default
```ts
true
```
#### rei
> **rei**: `undefined` \| `string`
#### rei-selector
> **rei-selector**: `undefined` \| `string`
#### res
> **res**: `undefined` \| `string`
#### res-selector
> **res-selector**: `undefined` \| `string`
#### rescript
> **rescript**: `undefined` \| `string`
#### rescript-selector
> **rescript-selector**: `undefined` \| `string`
#### resi
> **resi**: `undefined` \| `string`
#### resi-selector
> **resi-selector**: `undefined` \| `string`
#### rich
> **rich**: `undefined` \| `string`
#### rich-selector
> **rich-selector**: `undefined` \| `string`
#### richtext
> **richtext**: `undefined` \| `string`
#### richtext-selector
> **richtext-selector**: `undefined` \| `string`
#### riot
> **riot**: `undefined` \| `string`
#### riot-selector
> **riot-selector**: `undefined` \| `string`
#### riotjs
> **riotjs**: `undefined` \| `string`
#### riotjs-selector
> **riotjs-selector**: `undefined` \| `string`
#### ripple
> **ripple**: `undefined` \| `string`
#### ripple-selector
> **ripple-selector**: `undefined` \| `string`
#### ripplejs
> **ripplejs**: `undefined` \| `string`
#### ripplejs-selector
> **ripplejs-selector**: `undefined` \| `string`
#### rlang
> **rlang**: `undefined` \| `string`
#### rlang-selector
> **rlang-selector**: `undefined` \| `string`
#### rstats
> **rstats**: `undefined` \| `string`
#### rstats-selector
> **rstats-selector**: `undefined` \| `string`
#### rte
> **rte**: `undefined` \| `string`
#### rte-selector
> **rte-selector**: `undefined` \| `string`
#### rte.html
> **html**: `undefined` \| `string`
#### rte.html-selector
> **html-selector**: `undefined` \| `string`
#### ruby
> **ruby**: `undefined` \| `string`
#### ruby-selector
> **ruby-selector**: `undefined` \| `string`
#### ruby-wasm
> **ruby-wasm**: `undefined` \| `string`
#### ruby-wasm-selector
> **ruby-wasm-selector**: `undefined` \| `string`
#### rubywasm
> **rubywasm**: `undefined` \| `string`
#### rubywasm-selector
> **rubywasm-selector**: `undefined` \| `string`
#### sass
> **sass**: `undefined` \| `string`
#### sass-selector
> **sass-selector**: `undefined` \| `string`
#### scheme
> **scheme**: `undefined` \| `string`
#### scheme-selector
> **scheme-selector**: `undefined` \| `string`
#### scm
> **scm**: `undefined` \| `string`
#### scm-selector
> **scm-selector**: `undefined` \| `string`
#### screen?
> `optional` **screen**: `"new"` \| `"open"` \| `"embed"` \| `"sync"` \| `"about"` \| `"welcome"` \| `"add-snippet"` \| `"login"` \| `"info"` \| `"assets"` \| `"add-asset"` \| `"snippets"` \| `"import"` \| `"resources"` \| `"share"` \| `"deploy"` \| `"backup"` \| `"broadcast"` \| `"custom-settings"` \| `"editor-settings"` \| `"code-to-image"` \| `"test-editor"` \| `"keyboard-shortcuts"`
#### script?
> `optional` **script**: `object`
An object that configures the language and content of the script editor.
See [docs](https://livecodes.io/docs/configuration/configuration-object/#markup) for details.
##### Default
```ts
{ language: "javascript", content: "" }
```
#### script.content?
> `optional` **content**: `string`
The initial content of the code editor.
##### Default
```ts
""
```
#### script.contentUrl?
> `optional` **contentUrl**: `string`
A URL to load `content` from. It has to be a valid URL that is CORS-enabled.
The URL is only fetched if `content` property had no value.
#### script.foldedLines?
> `optional` **foldedLines**: `object`[]
Lines that get folded when the editor loads.
This can be used for less relevant content.
##### Example
```ts
[{ from: 5, to: 8 }, { from: 15, to: 20 }]
```
#### script.hiddenContent?
> `optional` **hiddenContent**: `string`
Hidden content that gets evaluated without being visible in the code editor.
This can be useful in embedded playgrounds (e.g. for adding helper functions, utilities or tests)
#### script.hiddenContentUrl?
> `optional` **hiddenContentUrl**: `string`
A URL to load `hiddenContent` from. It has to be a valid URL that is CORS-enabled.
The URL is only fetched if `hiddenContent` property had no value.
#### script.hideTitle?
> `optional` **hideTitle**: `boolean`
If `true`, the title of the code editor is hidden, however its code is still evaluated.
This can be useful in embedded playgrounds (e.g. for hiding unnecessary code).
#### script.language
> **language**: [`Language`](../type-aliases/Language.md)
A language name, extension or alias (as defined in [language documentations](https://livecodes.io/docs/languages/)).
For the list of supported values, see [Language](https://livecodes.io/docs/api/type-aliases/Language)
#### script.order?
> `optional` **order**: `number`
The order of the editor in the UI.
##### Default
```ts
0
```
#### script.position?
> `optional` **position**: [`EditorPosition`](../internal/interfaces/EditorPosition.md)
The initial position of the cursor in the code editor.
##### Example
```ts
{lineNumber: 5, column: 10}
```
#### script.selector?
> `optional` **selector**: `string`
A CSS selector to load content from [DOM import](https://livecodes.io/docs/features/import#import-code-from-dom).
#### script.title?
> `optional` **title**: `string`
If set, this is used as the title of the editor in the UI,
overriding the default title set to the language name
(e.g. `"Python"` can be used instead of `"Py (Wasm)"`).
#### scripts?
> `optional` **scripts**: `string`
#### scrollPosition?
> `optional` **scrollPosition**: `boolean`
#### scss
> **scss**: `undefined` \| `string`
#### scss-selector
> **scss-selector**: `undefined` \| `string`
#### sdkVersion?
> `optional` **sdkVersion**: `string`
#### semicolons?
> `optional` **semicolons**: `boolean`
Configures Prettier [code formatter](https://livecodes.io/docs/features/code-format) to use semi-colons.
##### Default
```ts
true
```
#### showSpacing?
> `optional` **showSpacing**: `boolean`
Enables [showing element spacing](https://livecodes.io/docs/features/result#show-spacings) in the result page.
##### Default
```ts
false
```
#### singleQuote?
> `optional` **singleQuote**: `boolean`
Configures Prettier [code formatter](https://livecodes.io/docs/features/code-format) to use single quotes instead of double quotes.
##### Default
```ts
false
```
#### solid
> **solid**: `undefined` \| `string`
#### solid-selector
> **solid-selector**: `undefined` \| `string`
#### solid.jsx
> **jsx**: `undefined` \| `string`
#### solid.jsx-selector
> **jsx-selector**: `undefined` \| `string`
#### solid.tsx
> **tsx**: `undefined` \| `string`
#### solid.tsx-selector
> **tsx-selector**: `undefined` \| `string`
#### sql
> **sql**: `undefined` \| `string`
#### sql-selector
> **sql-selector**: `undefined` \| `string`
#### sqlite
> **sqlite**: `undefined` \| `string`
#### sqlite-selector
> **sqlite-selector**: `undefined` \| `string`
#### sqlite3
> **sqlite3**: `undefined` \| `string`
#### sqlite3-selector
> **sqlite3-selector**: `undefined` \| `string`
#### stencil
> **stencil**: `undefined` \| `string`
#### stencil-selector
> **stencil-selector**: `undefined` \| `string`
#### stencil.tsx
> **tsx**: `undefined` \| `string`
#### stencil.tsx-selector
> **tsx-selector**: `undefined` \| `string`
#### styl
> **styl**: `undefined` \| `string`
#### styl-selector
> **styl-selector**: `undefined` \| `string`
#### style?
> `optional` **style**: `object`
An object that configures the language and content of the style editor.
See [docs](https://livecodes.io/docs/configuration/configuration-object/#markup) for details.
##### Default
```ts
{ language: "css", content: "" }
```
#### style.content?
> `optional` **content**: `string`
The initial content of the code editor.
##### Default
```ts
""
```
#### style.contentUrl?
> `optional` **contentUrl**: `string`
A URL to load `content` from. It has to be a valid URL that is CORS-enabled.
The URL is only fetched if `content` property had no value.
#### style.foldedLines?
> `optional` **foldedLines**: `object`[]
Lines that get folded when the editor loads.
This can be used for less relevant content.
##### Example
```ts
[{ from: 5, to: 8 }, { from: 15, to: 20 }]
```
#### style.hiddenContent?
> `optional` **hiddenContent**: `string`
Hidden content that gets evaluated without being visible in the code editor.
This can be useful in embedded playgrounds (e.g. for adding helper functions, utilities or tests)
#### style.hiddenContentUrl?
> `optional` **hiddenContentUrl**: `string`
A URL to load `hiddenContent` from. It has to be a valid URL that is CORS-enabled.
The URL is only fetched if `hiddenContent` property had no value.
#### style.hideTitle?
> `optional` **hideTitle**: `boolean`
If `true`, the title of the code editor is hidden, however its code is still evaluated.
This can be useful in embedded playgrounds (e.g. for hiding unnecessary code).
#### style.language
> **language**: [`Language`](../type-aliases/Language.md)
A language name, extension or alias (as defined in [language documentations](https://livecodes.io/docs/languages/)).
For the list of supported values, see [Language](https://livecodes.io/docs/api/type-aliases/Language)
#### style.order?
> `optional` **order**: `number`
The order of the editor in the UI.
##### Default
```ts
0
```
#### style.position?
> `optional` **position**: [`EditorPosition`](../internal/interfaces/EditorPosition.md)
The initial position of the cursor in the code editor.
##### Example
```ts
{lineNumber: 5, column: 10}
```
#### style.selector?
> `optional` **selector**: `string`
A CSS selector to load content from [DOM import](https://livecodes.io/docs/features/import#import-code-from-dom).
#### style.title?
> `optional` **title**: `string`
If set, this is used as the title of the editor in the UI,
overriding the default title set to the language name
(e.g. `"Python"` can be used instead of `"Py (Wasm)"`).
#### stylesheets?
> `optional` **stylesheets**: `string`
#### stylis
> **stylis**: `undefined` \| `string`
#### stylis-selector
> **stylis-selector**: `undefined` \| `string`
#### stylus
> **stylus**: `undefined` \| `string`
#### stylus-selector
> **stylus-selector**: `undefined` \| `string`
#### sucrase
> **sucrase**: `undefined` \| `string`
#### sucrase-selector
> **sucrase-selector**: `undefined` \| `string`
#### svelte
> **svelte**: `undefined` \| `string`
#### svelte-app
> **svelte-app**: `undefined` \| `string`
#### svelte-app-selector
> **svelte-app-selector**: `undefined` \| `string`
#### svelte-selector
> **svelte-selector**: `undefined` \| `string`
#### tabSize?
> `optional` **tabSize**: `number`
The number of spaces per indentation-level.
Also used in [code formatting](https://livecodes.io/docs/features/code-format).
##### Default
```ts
2
```
#### tags?
> `optional` **tags**: `string` \| `string`[]
#### tcl
> **tcl**: `undefined` \| `string`
#### tcl-selector
> **tcl-selector**: `undefined` \| `string`
#### teal
> **teal**: `undefined` \| `string`
#### teal-selector
> **teal-selector**: `undefined` \| `string`
#### template?
> `optional` **template**: [`TemplateName`](../internal/type-aliases/TemplateName.md)
A [starter template](https://livecodes.io/docs/features/templates) to load.
Allowed valued can be found [here](https://livecodes.io/docs/api/internal/type-aliases/TemplateName).
#### tests?
> `optional` **tests**: (\{ language?: Language \| undefined; content?: string \| undefined; contentUrl?: string \| undefined; hiddenContent?: string \| undefined; hiddenContentUrl?: string \| undefined; ... 5 more ...; position?: EditorPosition \| undefined; \} \| undefined) & ("" \| ... 4 more ... \| "full")
Configures the [language](https://livecodes.io/docs/features/tests#supported-languages)
and content of [tests](https://livecodes.io/docs/features/tests).
#### theme?
> `optional` **theme**: [`Theme`](../internal/type-aliases/Theme.md)
Sets the app [theme](https://livecodes.io/docs/features/themes) to light/dark mode.
##### Default
```ts
"dark"
```
#### themeColor?
> `optional` **themeColor**: `string`
Sets the app theme color.
If `undefined`, it is set to `"hsl(214, 40%, 50%)"`.
##### Default
```ts
undefined
```
#### title?
> `optional` **title**: `string`
Project title.
This is used as [result page](https://livecodes.io/docs/features/result) title and title meta tag.
Also used in project search.
##### Default
```ts
"Untitled Project"
```
#### tl
> **tl**: `undefined` \| `string`
#### tl-selector
> **tl-selector**: `undefined` \| `string`
#### tools?
> `optional` **tools**: `"none"` \| `"closed"` \| `"open"` \| `"full"` \| `"console"` \| `"compiled"` \| `"tests"` \| "console\|undefined" \| "console\|" \| "console\|none" \| "console\|closed" \| "console\|open" \| "console\|full" \| "compiled\|undefined" \| "compiled\|" \| "compiled\|none" \| "compiled\|closed" \| "compiled\|open" \| "compiled\|full" \| "tests\|undefined" \| "tests\|" \| "tests\|none" \| "tests\|closed" \| "tests\|open" \| "tests\|full" \| "console,console\|undefined" \| "console,console\|" \| "console,console\|none" \| "console,console\|closed" \| "console,console\|open" \| "console,console\|full" \| "console,compiled\|undefined" \| "console,compiled\|" \| "console,compiled\|none" \| "console,compiled\|closed" \| "console,compiled\|open" \| "console,compiled\|full" \| "console,tests\|undefined" \| "console,tests\|" \| "console,tests\|none" \| "console,tests\|closed" \| "console,tests\|open" \| "console,tests\|full" \| "compiled,console\|undefined" \| "compiled,console\|" \| "compiled,console\|none" \| "compiled,console\|closed" \| "compiled,console\|open" \| "compiled,console\|full" \| "compiled,compiled\|undefined" \| "compiled,compiled\|" \| "compiled,compiled\|none" \| "compiled,compiled\|closed" \| "compiled,compiled\|open" \| "compiled,compiled\|full" \| "compiled,tests\|undefined" \| "compiled,tests\|" \| "compiled,tests\|none" \| "compiled,tests\|closed" \| "compiled,tests\|open" \| "compiled,tests\|full" \| "tests,console\|undefined" \| "tests,console\|" \| "tests,console\|none" \| "tests,console\|closed" \| "tests,console\|open" \| "tests,console\|full" \| "tests,compiled\|undefined" \| "tests,compiled\|" \| "tests,compiled\|none" \| "tests,compiled\|closed" \| "tests,compiled\|open" \| "tests,compiled\|full" \| "tests,tests\|undefined" \| "tests,tests\|" \| "tests,tests\|none" \| "tests,tests\|closed" \| "tests,tests\|open" \| "tests,tests\|full" \| "console,console,console\|undefined" \| "console,console,console\|" \| "console,console,console\|none" \| "console,console,console\|closed" \| "console,console,console\|open" \| "console,console,console\|full" \| "console,console,compiled\|undefined" \| "console,console,compiled\|" \| "console,console,compiled\|none" \| "console,console,compiled\|closed" \| "console,console,compiled\|open" \| "console,console,compiled\|full" \| "console,console,tests\|undefined" \| "console,console,tests\|" \| "console,console,tests\|none" \| "console,console,tests\|closed" \| "console,console,tests\|open" \| "console,console,tests\|full" \| "console,compiled,console\|undefined" \| "console,compiled,console\|" \| "console,compiled,console\|none" \| "console,compiled,console\|closed" \| "console,compiled,console\|open" \| "console,compiled,console\|full" \| "console,compiled,compiled\|undefined" \| "console,compiled,compiled\|" \| "console,compiled,compiled\|none" \| "console,compiled,compiled\|closed" \| "console,compiled,compiled\|open" \| "console,compiled,compiled\|full" \| "console,compiled,tests\|undefined" \| "console,compiled,tests\|" \| "console,compiled,tests\|none" \| "console,compiled,tests\|closed" \| "console,compiled,tests\|open" \| "console,compiled,tests\|full" \| "console,tests,console\|undefined" \| "console,tests,console\|" \| "console,tests,console\|none" \| "console,tests,console\|closed" \| "console,tests,console\|open" \| "console,tests,console\|full" \| "console,tests,compiled\|undefined" \| "console,tests,compiled\|" \| "console,tests,compiled\|none" \| "console,tests,compiled\|closed" \| "console,tests,compiled\|open" \| "console,tests,compiled\|full" \| "console,tests,tests\|undefined" \| "console,tests,tests\|" \| "console,tests,tests\|none" \| "console,tests,tests\|closed" \| "console,tests,tests\|open" \| "console,tests,tests\|full" \| "compiled,console,console\|undefined" \| "compiled,console,console\|" \| "compiled,console,console\|none" \| "compiled,console,console\|closed" \| "compiled,console,console\|open" \| "compiled,console,console\|full" \| "compiled,console,compiled\|undefined" \| "compiled,console,compiled\|" \| "compiled,console,compiled\|none" \| "compiled,console,compiled\|closed" \| "compiled,console,compiled\|open" \| "compiled,console,compiled\|full" \| "compiled,console,tests\|undefined" \| "compiled,console,tests\|" \| "compiled,console,tests\|none" \| "compiled,console,tests\|closed" \| "compiled,console,tests\|open" \| "compiled,console,tests\|full" \| "compiled,compiled,console\|undefined" \| "compiled,compiled,console\|" \| "compiled,compiled,console\|none" \| "compiled,compiled,console\|closed" \| "compiled,compiled,console\|open" \| "compiled,compiled,console\|full" \| "compiled,compiled,compiled\|undefined" \| "compiled,compiled,compiled\|" \| "compiled,compiled,compiled\|none" \| "compiled,compiled,compiled\|closed" \| "compiled,compiled,compiled\|open" \| "compiled,compiled,compiled\|full" \| "compiled,compiled,tests\|undefined" \| "compiled,compiled,tests\|" \| "compiled,compiled,tests\|none" \| "compiled,compiled,tests\|closed" \| "compiled,compiled,tests\|open" \| "compiled,compiled,tests\|full" \| "compiled,tests,console\|undefined" \| "compiled,tests,console\|" \| "compiled,tests,console\|none" \| "compiled,tests,console\|closed" \| "compiled,tests,console\|open" \| "compiled,tests,console\|full" \| "compiled,tests,compiled\|undefined" \| "compiled,tests,compiled\|" \| "compiled,tests,compiled\|none" \| "compiled,tests,compiled\|closed" \| "compiled,tests,compiled\|open" \| "compiled,tests,compiled\|full" \| "compiled,tests,tests\|undefined" \| "compiled,tests,tests\|" \| "compiled,tests,tests\|none" \| "compiled,tests,tests\|closed" \| "compiled,tests,tests\|open" \| "compiled,tests,tests\|full" \| "tests,console,console\|undefined" \| "tests,console,console\|" \| "tests,console,console\|none" \| "tests,console,console\|closed" \| "tests,console,console\|open" \| "tests,console,console\|full" \| "tests,console,compiled\|undefined" \| "tests,console,compiled\|" \| "tests,console,compiled\|none" \| "tests,console,compiled\|closed" \| "tests,console,compiled\|open" \| "tests,console,compiled\|full" \| "tests,console,tests\|undefined" \| "tests,console,tests\|" \| "tests,console,tests\|none" \| "tests,console,tests\|closed" \| "tests,console,tests\|open" \| "tests,console,tests\|full" \| "tests,compiled,console\|undefined" \| "tests,compiled,console\|" \| "tests,compiled,console\|none" \| "tests,compiled,console\|closed" \| "tests,compiled,console\|open" \| "tests,compiled,console\|full" \| "tests,compiled,compiled\|undefined" \| "tests,compiled,compiled\|" \| "tests,compiled,compiled\|none" \| "tests,compiled,compiled\|closed" \| "tests,compiled,compiled\|open" \| "tests,compiled,compiled\|full" \| "tests,compiled,tests\|undefined" \| "tests,compiled,tests\|" \| "tests,compiled,tests\|none" \| "tests,compiled,tests\|closed" \| "tests,compiled,tests\|open" \| "tests,compiled,tests\|full" \| "tests,tests,console\|undefined" \| "tests,tests,console\|" \| "tests,tests,console\|none" \| "tests,tests,console\|closed" \| "tests,tests,console\|open" \| "tests,tests,console\|full" \| "tests,tests,compiled\|undefined" \| "tests,tests,compiled\|" \| "tests,tests,compiled\|none" \| "tests,tests,compiled\|closed" \| "tests,tests,compiled\|open" \| "tests,tests,compiled\|full" \| "tests,tests,tests\|undefined" \| "tests,tests,tests\|" \| "tests,tests,tests\|none" \| "tests,tests,tests\|closed" \| "tests,tests,tests\|open" \| "tests,tests,tests\|full"
#### trailingComma?
> `optional` **trailingComma**: `boolean`
Configures Prettier [code formatter](https://livecodes.io/docs/features/code-format) to use [trailing commas](https://prettier.io/docs/en/options.html#trailing-commas).
##### Default
```ts
true
```
#### ts
> **ts**: `undefined` \| `string`
#### ts-selector
> **ts-selector**: `undefined` \| `string`
#### tsx
> **tsx**: `undefined` \| `string`
#### tsx-selector
> **tsx-selector**: `undefined` \| `string`
#### twig
> **twig**: `undefined` \| `string`
#### twig-selector
> **twig-selector**: `undefined` \| `string`
#### types?
> `optional` **types**: `object`
Allows providing custom TypeScript type declarations for better [editor intellisense](https://livecodes.io/docs/features/intellisense).
It is an object where each key represents module name and value represents the types.
See docs for [Types](https://livecodes.io/docs/configuration/configuration-object#types)
and [Custom Types](https://livecodes.io/docs/features/intellisense#custom-types)
##### Examples
```js
{
  "types": {
    "my-demo-lib": "https://my-custom-domain/my-type-declarations.d.ts"
  }
}
```
```
{
  "types": {
    "my-demo-lib": {
      "url": "https://my-custom-domain/types.d.ts",
      "autoload": true,
      "declareAsModule": true
    }
}
```
#### typescript
> **typescript**: `undefined` \| `string`
#### typescript-selector
> **typescript-selector**: `undefined` \| `string`
#### useTabs?
> `optional` **useTabs**: `boolean`
If `true`, lines are indented with tabs instead of spaces.
Also used in [code formatting](https://livecodes.io/docs/features/code-format).
##### Default
```ts
false
```
#### vento
> **vento**: `undefined` \| `string`
#### vento-selector
> **vento-selector**: `undefined` \| `string`
#### version?
> `readonly` `optional` **version**: `string`
This is a read-only property which specifies the current LiveCodes version.
Version specified in [exported](https://livecodes.io/docs/features/export) projects allows automatically upgrading the project configuration when imported by an app with a newer version.
#### ~~view?~~
> `optional` **view**: `"split"` \| `"result"` \| `"editor"`
##### Deprecated
The `view` option has been moved to `config.view`.
For headless mode use `headless: true`.
The [default view](https://livecodes.io/docs/features/default-view) for the playground.
When set to `"headless"`, the playground is loaded in [headless mode](https://livecodes.io/docs/sdk/headless).
##### Default
```ts
"split"
```
#### vto
> **vto**: `undefined` \| `string`
#### vto-selector
> **vto-selector**: `undefined` \| `string`
#### vue
> **vue**: `undefined` \| `string`
#### vue-app
> **vue-app**: `undefined` \| `string`
#### vue-app-selector
> **vue-app-selector**: `undefined` \| `string`
#### vue-selector
> **vue-selector**: `undefined` \| `string`
#### vue2
> **vue2**: `undefined` \| `string`
#### vue2-selector
> **vue2-selector**: `undefined` \| `string`
#### vue3
> **vue3**: `undefined` \| `string`
#### vue3-selector
> **vue3-selector**: `undefined` \| `string`
#### wasm
> **wasm**: `undefined` \| `string`
#### wasm-selector
> **wasm-selector**: `undefined` \| `string`
#### wasm.cpp
> **cpp**: `undefined` \| `string`
#### wasm.cpp-selector
> **cpp-selector**: `undefined` \| `string`
#### wasm.cs
> **cs**: `undefined` \| `string`
#### wasm.cs-selector
> **cs-selector**: `undefined` \| `string`
#### wasm.go
> **go**: `undefined` \| `string`
#### wasm.go-selector
> **go-selector**: `undefined` \| `string`
#### wasm.lua
> **lua**: `undefined` \| `string`
#### wasm.lua-selector
> **lua-selector**: `undefined` \| `string`
#### wasm.php
> **php**: `undefined` \| `string`
#### wasm.php-selector
> **php-selector**: `undefined` \| `string`
#### wasm.py
> **py**: `undefined` \| `string`
#### wasm.py-selector
> **py-selector**: `undefined` \| `string`
#### wasm.rb
> **rb**: `undefined` \| `string`
#### wasm.rb-selector
> **rb-selector**: `undefined` \| `string`
#### wast
> **wast**: `undefined` \| `string`
#### wast-selector
> **wast-selector**: `undefined` \| `string`
#### wat
> **wat**: `undefined` \| `string`
#### wat-selector
> **wat-selector**: `undefined` \| `string`
#### webassembly
> **webassembly**: `undefined` \| `string`
#### webassembly-selector
> **webassembly-selector**: `undefined` \| `string`
#### welcome?
> `optional` **welcome**: `boolean`
If `true`, the [welcome screen](https://livecodes.io/docs/features/welcome) is displayed when the app loads.
#### wordWrap?
> `optional` **wordWrap**: `boolean`
Enables word-wrap for long lines.
##### Default
```ts
false
```
#### x?
> `optional` **x**: `string`
#### xht
> **xht**: `undefined` \| `string`
#### xht-selector
> **xht-selector**: `undefined` \| `string`
#### xml
> **xml**: `undefined` \| `string`
#### xml-selector
> **xml-selector**: `undefined` \| `string`
#### zoom?
> `optional` **zoom**: `1` \| `0.5` \| `0.25`
Sets result page [zoom level](https://livecodes.io/docs/features/result#result-page-zoom).
#### Defined in
[models.ts:338](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L338)
***
### template?
> `optional` **template**: [`TemplateName`](../internal/type-aliases/TemplateName.md)
A [starter template](https://livecodes.io/docs/features/templates) to load.
Allowed valued can be found [here](https://livecodes.io/docs/api/internal/type-aliases/TemplateName).
#### Defined in
[models.ts:383](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L383)
***
### ~~view?~~
> `optional` **view**: `"split"` \| `"result"` \| `"editor"` \| `"headless"`
#### Deprecated
The `view` option has been moved to `config.view`.
For headless mode use `headless: true`.
The [default view](https://livecodes.io/docs/features/default-view) for the playground.
When set to `"headless"`, the playground is loaded in [headless mode](https://livecodes.io/docs/sdk/headless).
#### Default
```ts
"split"
```
#### Defined in
[models.ts:396](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L396)
---
# Interface: Playground
An object that represents the LiveCodes playground instance.
The object exposes multiple [methods](https://livecodes.io/docs/sdk/js-ts/#sdk-methods) that can be used to interact with the playground.
See [docs](https://livecodes.io/docs/sdk/js-ts) for details.
## Extends
- [`API`](../internal/interfaces/API.md)
## Properties
### destroy()
> **destroy**: () => `Promise`\<`void`\>
Destroys the playground instance, and removes event listeners.
Further call to any SDK methods throws an error.
#### Returns
`Promise`\<`void`\>
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  await playground.destroy();
  // playground destroyed
  // any further SDK call throws an error
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`destroy`](../internal/interfaces/API.md#destroy)
#### Defined in
[models.ts:211](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L211)
***
### exec()
> **exec**: (`command`, ...`args`) => `Promise`\<`object` \| `object`\>
Executes custom commands, including: `"setBroadcastToken"` and `"showVersion"`.
See [docs](https://livecodes.io/docs/sdk/js-ts#exec) for details.
#### Parameters
• **command**: [`APICommands`](../internal/type-aliases/APICommands.md)
• ...**args**: `any`[]
#### Returns
`Promise`\<`object` \| `object`\>
#### Inherited from
[`API`](../internal/interfaces/API.md).[`exec`](../internal/interfaces/API.md#exec)
#### Defined in
[models.ts:194](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L194)
***
### format()
> **format**: (`allEditors`?) => `Promise`\<`void`\>
Formats the code.
By default, the code in all editors (markup, style and script) is formatted.
To format only the active editor, the value `false` should be passed as an argument.
#### Parameters
• **allEditors?**: `boolean`
#### Returns
`Promise`\<`void`\>
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  await playground.format();
  // code in editors is formatted
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`format`](../internal/interfaces/API.md#format)
#### Defined in
[models.ts:31](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L31)
***
### getCode()
> **getCode**: () => `Promise`\<[`Code`](Code.md)\>
Gets the playground code (including source code, source language and compiled code) for each editor (markup, style, script), in addition to result page HTML.
See [Code](https://livecodes.io/docs/api/interfaces/Code) for the structure of the returned object.
#### Returns
`Promise`\<[`Code`](Code.md)\>
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  const code = await playground.getCode();
  // source code, language and compiled code for the script editor
  const { content, language, compiled } = code.script;
  // result page HTML
  const result = code.result;
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`getCode`](../internal/interfaces/API.md#getcode)
#### Defined in
[models.ts:105](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L105)
***
### getConfig()
> **getConfig**: (`contentOnly`?) => `Promise`\<[`Config`](Config.md)\>
Gets a [configuration object](https://livecodes.io/docs/configuration/configuration-object) representing the playground state.
This can be used to restore state if passed as an [EmbedOptions](https://livecodes.io/docs/sdk/js-ts#embed-options) property when [creating playgrounds](https://livecodes.io/docs/sdk/js-ts/#createplayground),
or can be manipulated and loaded in run-time using [`setConfig`](https://livecodes.io/docs/sdk/js-ts#setconfig) method.
#### Parameters
• **contentOnly?**: `boolean`
#### Returns
`Promise`\<[`Config`](Config.md)\>
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  const config = await playground.getConfig();
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`getConfig`](../internal/interfaces/API.md#getconfig)
#### Defined in
[models.ts:64](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L64)
***
### getShareUrl()
> **getShareUrl**: (`shortUrl`?) => `Promise`\<`string`\>
Gets a [share url](https://livecodes.io/docs/features/share) for the current project.
By default, the url has a long query string representing the compressed encoded config object.
If the argument `shortUrl` was set to `true`, a short url is generated.
#### Parameters
• **shortUrl?**: `boolean`
#### Returns
`Promise`\<`string`\>
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  const longUrl = await playground.getShareUrl();
  const shortUrl = await playground.getShareUrl(true);
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`getShareUrl`](../internal/interfaces/API.md#getshareurl)
#### Defined in
[models.ts:48](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L48)
***
### load()
> **load**: () => `Promise`\<`void`\>
Loads the playground, if not already loaded.
When the embed option [loading](https://livecodes.io/docs/sdk/js-ts#loading) is set to `"click"`, the playground is not loaded automatically.
Instead, a screen is shown with "Click to load" button. Calling the SDK method `load()` allows loading the playground.
If the playground was not loaded, calling any other method will load the playground first before executing.
#### Returns
`Promise`\<`void`\>
#### Defined in
[models.ts:298](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L298)
***
### ~~onChange()~~
> **onChange**: (`fn`) => `object`
Runs a callback function when code changes.
#### Parameters
• **fn**
#### Returns
`object`
##### ~~remove()~~
> **remove**: () => `void`
###### Returns
`void`
#### Deprecated
Use [`watch`](https://livecodes.io/docs/sdk/js-ts#watch) method instead.
#### Inherited from
[`API`](../internal/interfaces/API.md).[`onChange`](../internal/interfaces/API.md#onchange)
#### Defined in
[models.ts:142](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L142)
***
### run()
> **run**: () => `Promise`\<`void`\>
Runs the [result page](https://livecodes.io/docs/features/result) (after any required compilation for code).
#### Returns
`Promise`\<`void`\>
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  await playground.run();
  // new result page is displayed
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`run`](../internal/interfaces/API.md#run)
#### Defined in
[models.ts:14](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L14)
***
### runTests()
> **runTests**: () => `Promise`\<`object`\>
Runs project [tests](https://livecodes.io/docs/features/tests) (if present) and gets test results.
#### Returns
`Promise`\<`object`\>
##### results
> **results**: [`TestResult`](../internal/interfaces/TestResult.md)[]
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  const { results } = await playground.runTests();
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`runTests`](../internal/interfaces/API.md#runtests)
#### Defined in
[models.ts:135](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L135)
***
### setConfig()
> **setConfig**: (`config`) => `Promise`\<[`Config`](Config.md)\>
Loads a new project using the passed configuration object.
#### Parameters
• **config**: `Partial`\<[`Config`](Config.md)\>
#### Returns
`Promise`\<[`Config`](Config.md)\>
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then(async (playground) => {
  const config = {
    markup: {
      language: "html",
      content: "Hello World!",
    },
  };
  const newConfig = await playground.setConfig(config);
  // new project loaded
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`setConfig`](../internal/interfaces/API.md#setconfig)
#### Defined in
[models.ts:84](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L84)
***
### show()
> **show**: (`panel`, `options`?) => `Promise`\<`void`\>
Shows the selected panel.
See [docs](https://livecodes.io/docs/sdk/js-ts#show) for details.
#### Parameters
• **panel**: `"result"` \| [`EditorId`](../internal/type-aliases/EditorId.md) \| `"console"` \| `"compiled"` \| `"tests"` \| `"editor"` \| `"toggle-result"`
• **options?**
• **options.column?**: `number`
• **options.full?**: `boolean`
• **options.line?**: `number`
• **options.zoom?**: `1` \| `0.5` \| `0.25`
#### Returns
`Promise`\<`void`\>
#### Example
```ts
await playground.show("style");
await playground.show("toggle-result");
await playground.show("result", { full: true });
await playground.show("script");
await playground.show("result", { zoom: 0.5 });
await playground.show("console", { full: true });
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`show`](../internal/interfaces/API.md#show)
#### Defined in
[models.ts:119](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L119)
***
### watch
> **watch**: [`WatchLoad`](../internal/type-aliases/WatchLoad.md) & [`WatchReady`](../internal/type-aliases/WatchReady.md) & [`WatchCode`](../internal/type-aliases/WatchCode.md) & [`WatchConsole`](../internal/type-aliases/WatchConsole.md) & [`WatchTests`](../internal/type-aliases/WatchTests.md) & [`WatchDestroy`](../internal/type-aliases/WatchDestroy.md)
Allows to watch for various playground events.
It takes 2 arguments: event name and a callback function that will be called on every event.
event name can be one of: `"load" | "ready" | "code" | "console" | "tests" | "destroy"`
In some events, the callback function will be called with an object that supplies relevant data to the callback function (e.g. code, console output, test results).
The watch method returns an object with a single method (`remove`), which when called will remove the callback from watching further events.
See [docs](https://livecodes.io/docs/sdk/js-ts#watch) for details.
#### Example
```ts
import { createPlayground } from "livecodes";
createPlayground("#container").then((playground) => {
  const codeWatcher = playground.watch("code", ({ code, config }) => {
    // this will run on every code change
    console.log("code:", code);
    console.log("config:", config);
  });
  const consoleWatcher = playground.watch("console", ({ method, args }) => {
    // this will run on every console output
    console[method](...args);
  });
  const testsWatcher = playground.watch("tests", ({ results }) => {
    // this will run when tests run
    results.forEach((testResult) => {
      console.log("status:", testResult.status); // "pass", "fail" or "skip"
      console.log(testResult.errors); // array of errors as strings
    });
  });
  // then later
  codeWatcher.remove();
  consoleWatcher.remove();
  testsWatcher.remove();
  // events are no longer watched
});
```
#### Inherited from
[`API`](../internal/interfaces/API.md).[`watch`](../internal/interfaces/API.md#watch)
#### Defined in
[models.ts:187](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L187)
---
# Type Alias: Language
> **Language**: `"html"` \| `"htm"` \| `"markdown"` \| `"md"` \| `"mdown"` \| `"mkdn"` \| `"mdx"` \| `"astro"` \| `"pug"` \| `"jade"` \| `"haml"` \| `"asciidoc"` \| `"adoc"` \| `"asc"` \| `"mustache"` \| `"handlebars"` \| `"hbs"` \| `"ejs"` \| `"eta"` \| `"nunjucks"` \| `"njk"` \| `"liquid"` \| `"liquidjs"` \| `"dot"` \| `"twig"` \| `"vento"` \| `"vto"` \| `"art-template"` \| `"art"` \| `"jinja"` \| `"bbcode"` \| `"bb"` \| `"mjml"` \| `"diagrams"` \| `"diagram"` \| `"graph"` \| `"plt"` \| `"richtext"` \| `"rte"` \| `"rich"` \| `"rte.html"` \| `"css"` \| `"scss"` \| `"sass"` \| `"less"` \| `"stylus"` \| `"styl"` \| `"stylis"` \| `"postcss"` \| `"javascript"` \| `"js"` \| `"json"` \| `"babel"` \| `"es"` \| `"sucrase"` \| `"typescript"` \| `"flow"` \| `"ts"` \| `"jsx"` \| `"tsx"` \| `"react"` \| `"react-jsx"` \| `"react.jsx"` \| `"react-tsx"` \| `"react.tsx"` \| `"react-native"` \| `"react-native.jsx"` \| `"react-native-tsx"` \| `"react-native.tsx"` \| `"vue"` \| `"vue3"` \| `"vue2"` \| `"vue-app"` \| `"app.vue"` \| `"svelte"` \| `"svelte-app"` \| `"app.svelte"` \| `"stencil"` \| `"stencil.tsx"` \| `"solid"` \| `"solid.jsx"` \| `"solid.tsx"` \| `"riot"` \| `"riotjs"` \| `"malina"` \| `"malinajs"` \| `"ripple"` \| `"ripplejs"` \| `"xht"` \| `"coffeescript"` \| `"coffee"` \| `"livescript"` \| `"ls"` \| `"civet"` \| `"clio"` \| `"imba"` \| `"assemblyscript"` \| `"as"` \| `"python"` \| `"py"` \| `"pyodide"` \| `"python-wasm"` \| `"py-wasm"` \| `"pythonwasm"` \| `"pywasm"` \| `"py3"` \| `"wasm.py"` \| `"r"` \| `"rlang"` \| `"rstats"` \| `"r-wasm"` \| `"ruby"` \| `"rb"` \| `"ruby-wasm"` \| `"wasm.rb"` \| `"rubywasm"` \| `"go"` \| `"golang"` \| `"go-wasm"` \| `"wasm.go"` \| `"gowasm"` \| `"php"` \| `"php-wasm"` \| `"phpwasm"` \| `"wasm.php"` \| `"cpp"` \| `"c"` \| `"C"` \| `"cp"` \| `"cxx"` \| `"c++"` \| `"cppm"` \| `"ixx"` \| `"ii"` \| `"hpp"` \| `"h"` \| `"cpp-wasm"` \| `"cppwasm"` \| `"cwasm"` \| `"wasm.cpp"` \| `"clang"` \| `"clang.cpp"` \| `"java"` \| `"csharp"` \| `"csharp-wasm"` \| `"cs"` \| `"cs-wasm"` \| `"wasm.cs"` \| `"perl"` \| `"pl"` \| `"pm"` \| `"lua"` \| `"lua-wasm"` \| `"luawasm"` \| `"wasm.lua"` \| `"teal"` \| `"tl"` \| `"fennel"` \| `"fnl"` \| `"julia"` \| `"jl"` \| `"scheme"` \| `"scm"` \| `"commonlisp"` \| `"common-lisp"` \| `"lisp"` \| `"clojurescript"` \| `"clojure"` \| `"cljs"` \| `"clj"` \| `"cljc"` \| `"edn"` \| `"gleam"` \| `"rescript"` \| `"res"` \| `"resi"` \| `"reason"` \| `"re"` \| `"rei"` \| `"ocaml"` \| `"ml"` \| `"mli"` \| `"tcl"` \| `"wat"` \| `"wast"` \| `"webassembly"` \| `"wasm"` \| `"Binary"` \| `"sql"` \| `"sqlite"` \| `"sqlite3"` \| `"pg.sql"` \| `"pgsql.sql"` \| `"pgsql"` \| `"pg"` \| `"pglite"` \| `"pglite.sql"` \| `"postgresql"` \| `"postgres"` \| `"postgre.sql"` \| `"postgresql.sql"` \| `"prolog.pl"` \| `"prolog"` \| `"blockly"` \| `"blockly.xml"` \| `"xml"` \| `"pintora"`
Language name, alias or extension.
## Defined in
[models.ts:884](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/models.ts#L884)
---
# Function: createPlayground()
## createPlayground(container, options)
> **createPlayground**(`container`, `options`?): `Promise`\<[`Playground`](../interfaces/Playground.md)\>
Creates a LiveCodes playground.
### Parameters
• **container**: `string` \| `HTMLElement`
`HTMLElement` or a string representing a CSS selector. This is the container where the playground is rendered.
 If not found, an error is thrown (except in [headless mode](https://livecodes.io/docs/sdk/headless), in which this parameter is optional and can be omitted).
• **options?**: [`EmbedOptions`](../interfaces/EmbedOptions.md)
The [embed options](https://livecodes.io/docs/sdk/js-ts#embed-options) for the playground (optional).
### Returns
`Promise`\<[`Playground`](../interfaces/Playground.md)\>
- A promise that resolves to a [`Playground`](https://livecodes.io/docs/api/interfaces/Playground/) object which exposes many [SDK methods](https://livecodes.io/docs/sdk/js-ts/#sdk-methods) that can be used to interact with the playground.
### Defined in
[index.ts:26](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/index.ts#L26)
## createPlayground(options)
> **createPlayground**(`options`): `Promise`\<[`Playground`](../interfaces/Playground.md)\>
### Parameters
• **options**: [`EmbedOptions`](../interfaces/EmbedOptions.md) & `object`
### Returns
`Promise`\<[`Playground`](../interfaces/Playground.md)\>
### Defined in
[index.ts:30](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/index.ts#L30)
---
# Function: getPlaygroundUrl()
> **getPlaygroundUrl**(`options`): `string`
Gets the URL to a LiveCodes playground (as a string) from the provided [options](https://livecodes.io/docs/sdk/js-ts#embed-options).
This can be useful for providing links to run code in playgrounds.
## Parameters
• **options**: [`EmbedOptions`](../interfaces/EmbedOptions.md) = `{}`
The [options](https://livecodes.io/docs/sdk/js-ts#embed-options) for the playground.
## Returns
`string`
- The URL of the playground (as a string).
large objects like config and params are store in the url hash params while the rest are in the search params
unless config is a string in which case it is stored in searchParams
## Defined in
[index.ts:387](https://github.com/live-codes/livecodes/blob/4163d1dd4a3ae8a76a1ba3597745e1bceaf59adc/src/sdk/index.ts#L387)