Skip to content

Add multi-language code execution (Python, C/C++, Go, Ruby, Lua)#4

Merged
dreamteam-mobile merged 2 commits intomainfrom
feature/multi-language-wasm-execution
Feb 20, 2026
Merged

Add multi-language code execution (Python, C/C++, Go, Ruby, Lua)#4
dreamteam-mobile merged 2 commits intomainfrom
feature/multi-language-wasm-execution

Conversation

@dreamteam-mobile
Copy link
Collaborator

Summary

Expands in-browser code execution from JS/TS-only to 7 languages using a persistent Web Worker architecture with lazy-loaded runtimes. No WASM is downloaded until the user selects a language — runtimes load in the background while the user types.

New Language Runtimes

Language Runtime Download Size Startup How It Works
Python Pyodide ~5 MB (WASM) 2-5s CPython compiled to WebAssembly, loaded from jsDelivr CDN
C/C++ Compiler Explorer None Instant GCC 14.2 via Godbolt REST API (server-side compilation)
Go Go Playground None Instant Official Go Playground compile API (server-side)
Ruby ruby.wasm ~36 MB (WASM) 3-6s CRuby 3.3 compiled to WebAssembly via WASI, loaded from jsDelivr CDN
Lua Wasmoon ~300 KB (WASM) <100ms Lua 5.4 compiled to WebAssembly, bundled via npm

Architecture

  • Persistent workers — one Web Worker per language, loaded once and reused across executions (unlike JS/TS which uses fresh workers)
  • Lazy loading — WASM runtimes only download when the user first selects that language
  • Progress tracking — large downloads (Python, Ruby) show real-time byte-level progress via ReadableStream.getReader() fetch interception
  • Runtime store (Zustand) — tracks idle → loading → ready → error status per language, drives UI state

New Files

  • src/stores/runtimeStore.ts — Zustand store for runtime download/loading state
  • src/services/wasm-runtime-manager.ts — Central orchestrator managing persistent workers
  • src/services/runtimes/*.worker.ts — 5 worker files (one per new language runtime)

Modified Files

  • src/services/code-executor.ts — Routes WASM languages to runtime manager
  • src/hooks/useExecutionSync.ts — Preloads runtimes on language switch, handles loading states
  • src/components/TabBar.tsx — Progress ring on run button during download
  • src/components/CodeEditor/LanguageSelector.tsx — Triggers preload, marks executable languages
  • src/components/CodeEditor/OutputPanel.tsx — Shows download progress in output area
  • src/components/CodeEditor/CodeEditor.tsx — Added Prism Lua syntax highlighting
  • src/services/code-editor-logic.ts — Added Lua code template
  • src/styles.css — Progress ring animation styles
  • vite.config.tsoptimizeDeps.include for WASM runtime dependencies

UX

  • Run button shows a circular progress ring while runtime downloads (disabled)
  • Run button shows an error icon if runtime fails to load (click retries)
  • Output panel shows "Downloading {language} runtime... {progress}%"
  • All executable languages have a prefix in the dropdown
  • Switching back to an already-loaded language is instant (no re-download)

Test plan

  • All 1214 unit tests pass
  • TypeScript strict mode — no type errors
  • Python execution: print("Hello Python!") → output in 5ms
  • C++ execution: std::cout << "Hello C++!" << std::endl → output in ~2s
  • Go execution: fmt.Println("Hello Go!") → output in ~850ms
  • Ruby execution: puts "Hello Ruby!" → output in 1ms
  • Lua execution: print("Hello Lua!") → output in 4ms
  • JS/TS execution still works as before
  • Language switching does not cause page reload or name modal reappearing
  • Ctrl+Enter keyboard shortcut works for all languages

🤖 Generated with Claude Code

Expand in-browser code execution from JS/TS-only to 7 languages using
a persistent Web Worker architecture with lazy-loaded runtimes.

New language runtimes:
- Python: Pyodide (CPython compiled to WASM, ~5MB from jsDelivr CDN)
- C/C++: Compiler Explorer / Godbolt API (GCC 14.2, server-side compilation)
- Go: Go Playground API (play.golang.org/compile, server-side compilation)
- Ruby: ruby.wasm (@ruby/3.3-wasm-wasi, ~36MB WASM from jsDelivr CDN)
- Lua: Wasmoon (Lua 5.4 compiled to WASM, ~300KB)

Architecture:
- Persistent workers per language (loaded once, reused across executions)
- Lazy loading: no WASM downloaded until user selects a language
- Progress tracking for large downloads (Python, Ruby) via fetch interception
- Runtime status store (Zustand) drives UI state for run button and output panel

UI changes:
- Run button shows progress ring while runtime downloads, error icon on failure
- Output panel shows download progress percentage for WASM runtimes
- Language selector triggers background preload on switch
- All executable languages marked with ▶ prefix in dropdown
- Lua added as 16th language option with Prism syntax highlighting

Fixes:
- Vite optimizeDeps.include prevents page reload on first worker dep import
Vite's default worker format (iife) doesn't support code-splitting,
which is needed by our WASM runtime workers that use dynamic imports.
Setting worker.format to 'es' fixes the Rollup build error.
@dreamteam-mobile dreamteam-mobile merged commit 227ea83 into main Feb 20, 2026
2 checks passed
@dreamteam-mobile dreamteam-mobile deleted the feature/multi-language-wasm-execution branch February 20, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant