Skip to content

About

A web playground for type checking, compiling, running, and inspecting Luau code.

Topics

Resources

Stars

28 stars

Watchers

1 watching

Forks

Repository files navigation

Luau Playground

A browser-based Luau code playground with execution and IDE features.

Luau Playground

Features

  • Code Execution: Run Luau code directly in the browser via WebAssembly
  • Type Checking: Type check Luau code directly in the browser via WebAssembly
  • Syntax Highlighting: Full Luau syntax support with light/dark themes
  • IDE Features:
    • Real-time diagnostics (type errors, lint warnings)
    • Autocomplete with type information
    • Hover tooltips for type inspection
  • Multi-file Support: Create and manage multiple files with tabs
  • Sharing: Compress and share playground state via URL
  • Mobile Friendly: Responsive design that works on phones and tablets
  • Bytecode View: View the bytecode of the compiled code

Stack

  • Frontend: Svelte 5 + Vite
  • Editor: CodeMirror 6 with custom Luau language mode
  • Runtime: Luau compiled to WebAssembly

Getting Started

Prerequisites

  • Node.js 18+
  • npm or pnpm

Development

# Install dependencies
npm install

# Start dev server
npm run dev

# Build for production
npm run build

# Preview production build
npm run preview

Building the WASM Module

The Luau WASM module needs to be built separately using Emscripten:

cd wasm

# Install Emscripten if not already installed
# See: https://emscripten.org/docs/getting_started/downloads.html

# Activate Emscripten
source ~/emsdk/emsdk_env.sh  # Adjust path as needed

# Build
./build.sh release

The built WASM file will be copied to public/wasm/.

API

URL Parameters

Share State (Hash)

Share playground state via URL hash:

https://play.luau.org/#<compressed-state>

The state is LZ-String compressed and versioned JSON:

v2:

  • c: Optional single file code contents, mutually exclusive with f
  • f: Optional object mapping filenames to content, mutually exclusive with c
  • a: Currently active filename, optional if only one file exists
  • v: 2: Version number for compatibility
  • s: Optional and partial (all properties are optional) compiler/type-checking settings
    • mode: "strict" | "nonstrict" | "nocheck"
    • solver: "new" | "old"
    • optimizationLevel: 0 | 1 | 2
    • debugLevel: 0 | 1 | 2
    • compilerRemarks: boolean
  • b: Optional boolean to show bytecode panel, default false

v1:

  • files: Object mapping filenames to content
  • active: Currently active filename
  • v: 1: Version number for compatibility
  • settings: Optional compiler/type-checking settings
    • mode: "strict" | "nonstrict" | "nocheck"
    • solver: "new" | "old"
    • optimizationLevel: 0 | 1 | 2
    • debugLevel: 0 | 1 | 2
    • compilerRemarks: boolean
  • showBytecode: Optional boolean to show bytecode panel

Embed Mode (Query Parameters)

Embed the playground in an iframe with a minimal UI:

https://play.luau.org/?embed=true#<compressed-state>

Query parameters:

  • embed=true: Enables embed mode (hides settings, bytecode toggle, share button)
  • theme=light|dark: Force a specific theme (defaults to auto which follows system preference)
  • controls=icons: Use icon labels instead of text (defaults to text)
  • expandId: Id of the host checkbox that grows the frame. Present only when the code is taller than the collapsed height (set by generated snippets)

Embeds always include a copy button for the active file. When the embed contains a single file there is no tab bar — the controls float over the editor instead.

Expandable embeds

An iframe cannot resize itself, so the frame's height belongs to the host page. When the code does not fit the requested height, the generated snippet brings a checkbox and a stylesheet that grow the frame. The expand button is inside the frame, first in the action row (expand, copy, open, check, then play), and posts a message that checks the box:

<div class="luau-embed" style="--luau-collapsed: 400px; --luau-expanded: 828px;">
  <input class="luau-embed-toggle" id="luau-embed-k3f9qa" type="checkbox">
  <iframe src="https://play.luau.org/?embed=true&expandId=luau-embed-k3f9qa#<state>"></iframe>
  <script>/* sets the checkbox when the frame posts luau-embed-expand */</script>
</div>

The expanded height is measured from the code when the snippet is generated — line count against the editor's line height, plus the tab bar for multi-file embeds — and capped at 80vh. Code that already fits gets a plain iframe with no toggle. Editing the code inside an embed does not change these heights; regenerate the snippet to update them.

About

A web playground for type checking, compiling, running, and inspecting Luau code.

Topics

Resources

Stars

28 stars

Watchers

1 watching

Forks

Contributors

Languages