Inside Tango’s Sandbox: Leveraging CodeSandbox for Fast Low‑Code Development
This article explains how the open‑source Tango low‑code engine uses a CodeSandbox‑based sandbox architecture—including dependency initialization, transpilation, and cross‑origin communication—to enable real‑time source‑code execution and visual drag‑and‑drop building within a secure iframe environment.
Overview
Tango is an open‑source low‑code design framework that generates source code from visual operations. It drives the low‑code workflow by editing source files directly, enabling seamless integration with existing development pipelines. Because Tango executes arbitrary JavaScript in the browser and must load third‑party components without contaminating the designer’s global scope, an isolated sandbox runtime is required.
Sandbox Architecture
The sandbox builds on the CodeSandbox platform and consists of three layers:
Frontend sandbox component – a ready‑to‑use React component that renders an iframe and forwards source files and configuration to the sandbox.
Online packager – a browser‑based bundler (similar to a lightweight webpack) that resolves dependencies from package.json, fetches the required npm packages, and produces a minimal set of files for execution.
Backend service – a serverless dependency‑packager that runs yarn install, builds the full dependency tree, and returns only the runtime files, excluding devDependencies, @types, test files, and other non‑essential assets.
Sandbox Workflow
Code preparation – The host platform sends the source code to the sandbox via postMessage.
Dependency initialization – The sandbox reads package.json, extracts the dependencies field, and invokes the packager service to fetch those packages. Missing files are retrieved from CDN providers such as unpkg or jsDelivr with Service Worker caching.
Transpilation – Each module is passed through a Babel‑based transpiler that converts modern ESM syntax to CommonJS. The transpilation is driven by a template (preset) that defines which Transpiler handles each file type.
Execution – The sandbox creates a CommonJS environment exposing require, module, exports, global, etc., wraps the entry module in an IIFE and evaluates it.
Lifecycle events – The sandbox emits events (e.g., compilation success, runtime error) so the host can react accordingly.
Dependency Initialization Details
The serverless dependency‑packager receives a request containing the package name and version, runs yarn install on the server, and walks the dependency graph to collect only the files that are actually imported. Files that are not needed at runtime—such as type definitions ( .d.ts) and test files—are omitted, reducing network payload. If a required asset is not present in the packager response, the sandbox falls back to fetching it from a CDN (unpkg/jsDelivr). Service Worker caching is employed to avoid repeated network requests for the same assets.
Transpilation & Build Process
When compilation starts, the sandbox calls compile(). The supplied template (preset) acts like a webpack configuration: it declares which loaders (Transpilers) to apply to JavaScript, CSS, Less, etc. A Manager instance orchestrates the lifecycle, rebuilding only when the dependency set changes.
const allGlobals = { require, module, exports, process, global, ...globals };
const allGlobalKeys = Object.keys(allGlobals);
const globalsCode = allGlobalKeys.length ? allGlobalKeys.join(', ') : '';
const globalsValues = allGlobalKeys.map(k => allGlobals[k]);
const wrapped = `(function $csb$eval(${globalsCode}){${code}
})`;
// @ts-ignore
(0, eval)(wrapped).apply(allGlobals.global, globalsValues);
return module.exports;The wrapper creates an IIFE that receives the CommonJS helpers as parameters, then evaluates the user code with eval(). Subsequent require() calls resolve additional modules recursively using the same environment.
Performance Optimizations for Tango
Because Tango projects are full‑featured applications rather than isolated snippets, the sandbox must start quickly and run smoothly. Optimizations include:
Excluding devDependencies and type definition files from the packager output.
Caching fetched assets via Service Workers to eliminate redundant network traffic.
Trimming unnecessary files (e.g., documentation, test suites) during the server‑side bundling step.
Integration with Tango
Cross‑origin communication is achieved by setting the same document.domain for both the host page and the sandbox iframe, and by adding the HTTP header Origin-Agent-Cluster: ?0 to bypass Chrome’s isolation policies.
The React package @music163/tango-sandbox encapsulates three core modules: IFrameProtocol – Listens for message events from the iframe and sends commands via postMessage to control the sandbox lifecycle. PreviewManager – Manages rendering; when source files change it sends a compile message to the sandbox to trigger rebuilding and preview update. Sandbox – The React component that mounts the iframe, passes the files prop (a map of file paths to content), and registers eventHandler callbacks to capture drag‑and‑drop interactions inside the sandbox.
Private npm registries can be supported by deploying a custom packager service that mimics the behavior of the public dependency‑packager, but the article does not detail that process.
References
Source code repository: https://github.com/NetEase/tango
Documentation site: https://netease.github.io/tango-site/
Discussion forum: https://github.com/NetEase/tango/discussions
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
