Live code playgrounds like CodePen, JSFiddle, and StackBlitz feel like magic. You type code—JavaScript, React with JSX, or TypeScript—and instantly see the result in a preview pane. Have you ever wondered how to build one yourself? The thought of managing server-side transpilation, bundling, dependency resolution, and performance can be daunting.
What if you could offload all that heavy lifting to a simple, blazing-fast API?
Enter esbuild.do, an "esbuild as a service" agent that puts the extreme speed of the esbuild bundler behind a clean, scalable API. In this guide, we'll show you how to build a functional, real-time JavaScript and TypeScript code playground in just a few minutes using the esbuild.do agent.
esbuild.do is a powerful agent on the do-business agentic workflow platform. It provides esbuild's bundling, minification, and transpilation capabilities as a robust API. Instead of installing and managing Node.js, npm packages, and esbuild binaries in your environment, you can simply make an API call.
This approach is perfect for:
The core benefit is simplicity without sacrificing speed. You get all the power of esbuild without the maintenance overhead.
We'll create a simple web page with two main components:
The logic is straightforward: every time you type in the text area, we'll send the code to the esbuild.do API, receive the browser-ready JavaScript bundle, and inject it into the iframe for execution.
First, let's create our index.html file. This is the skeleton of our application.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>esbuild.do Playground</title>
<style>
body { font-family: sans-serif; display: flex; height: 100vh; margin: 0; }
#editor, #preview { flex: 1; height: 100%; border: none; }
#editor { font-size: 16px; padding: 1rem; resize: none; border-right: 1px solid #ccc; }
#preview-container { flex: 1; }
</style>
</head>
<body>
<textarea id="editor" placeholder="Write your TypeScript code here..."></textarea>
<div id="preview-container">
<iframe id="preview" title="Code Preview"></iframe>
</div>
<!-- We'll use the SDK from a CDN for this demo -->
<script type="module" src="https://cdn.jsdelivr.net/npm/@do-business/sdk/dist/index.browser.js"></script>
<script type="module" src="app.js"></script>
</body>
</html>
Now for the brains of the operation. Create a file named app.js. This script will use the @do-business/sdk to communicate with the esbuild.do agent.
First, we'll initialize the agent and get references to our HTML elements. Then, we'll create a function to handle the bundling and update the preview.
// app.js
// The SDK is globally available from the script tag in our HTML
const { Agent } = window.DO;
// 1. Initialize the esbuild.do agent
const esbuild = new Agent('esbuild.do');
// 2. Get references to our DOM elements
const editor = document.getElementById('editor');
const preview = document.getElementById('preview');
const initialCode = `
// Welcome to the esbuild.do playground!
// Type some TypeScript below.
interface User {
name: string;
id: number;
}
const user: User = {
name: 'World',
id: 1,
};
function greet(u: User): void {
const el = document.createElement('h1');
el.textContent = \`Hello, \${u.name}!\`;
document.body.append(el);
}
greet(user);
`.trim();
editor.value = initialCode;
// 3. The function that bundles the code and updates the preview
async function updatePreview() {
const userInput = editor.value;
try {
// 4. Call the esbuild.do agent to bundle the code
const { code } = await esbuild.bundle({
entryPoints: ['index.ts'],
sources: {
// We create a virtual file named 'index.ts'
'index.ts': userInput
},
bundle: true, // Bundle all code into one file
minify: true, // Make it compact
platform: 'browser', // Target the browser environment
target: 'es2020'
});
// 5. Inject the bundled code into the iframe
preview.srcdoc = `
<html>
<body>
<script>${code}</script>
</body>
</html>
`;
} catch (error) {
// Display errors in the preview as well
console.error("Bundling failed:", error);
preview.srcdoc = `
<pre style="color: red;">${error.message}</pre>
`;
}
}
// 6. Listen for input and trigger the update (with debouncing)
let timeout;
editor.addEventListener('input', () => {
clearTimeout(timeout);
timeout = setTimeout(updatePreview, 300); // Debounce for 300ms
});
// Initial load
updatePreview();
That's it! Open your index.html file in a browser. You'll see a working code playground. The TypeScript code is sent to the esbuild.do API, which instantly bundles it into browser-compatible JavaScript and sends it back. Our script then runs it inside the iframe.
Our current playground is great for vanilla JS and TypeScript, but what about frameworks like React? The process is very similar; we just need to adjust our strategy slightly.
The key is that esbuild.do only transpiles source code you provide it. To support React, we need to:
Here’s how you would modify updatePreview to support JSX:
// A modified updatePreview function for React/JSX
async function updatePreviewWithReact() {
const userInput = editor.value; // Assume this is JSX code now
try {
// Use the 'transform' method for simple transpilation
const { code } = await esbuild.transform(
userInput,
{
loader: 'jsx', // Tell esbuild this is JSX
target: 'es2020'
}
);
// Inject the transpiled JS into an iframe that already has React loaded
preview.srcdoc = `
<html>
<head>
<!-- 1. Load React and ReactDOM from a CDN -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
// This script block will now contain the transpiled JS
${code}
</script>
</body>
</html>
`;
} catch (error) {
console.error("JSX Transform failed:", error);
// ... error handling ...
}
}
Note: The esbuild.do agent also supports a more powerful bundle method which can resolve JSX without pre-loading from a CDN by creating a virtual file system. The transform method shown here is a simple and effective alternative for this use case.
Building our playground highlights the core advantages of using esbuild as a service:
By leveraging esbuild.do, you can focus on building your application's features, not the underlying build infrastructure.
Ready to integrate a high-speed build step into your own applications? Explore esbuild.do and start bundling in minutes.
Q: What is esbuild.do?
A: esbuild.do provides esbuild's powerful bundling, transpilation, and minification capabilities as a simple and robust API. It allows you to integrate a high-speed build step into any application or workflow without installing or configuring local build tools.
Q: Why use an API for esbuild instead of the CLI?
A: Using esbuild.do abstracts away the complexity of managing binary dependencies, versions, and build environments. It's perfect for serverless functions, CI/CD pipelines, online playgrounds, and any environment where installing Node.js and npm packages is inconvenient.
Q: What languages and formats does esbuild.do support?
A: Just like the underlying tool, our agent supports JavaScript (JS, JSX) and TypeScript (TS, TSX). It can also bundle CSS, load JSON files, and handle various output formats like IIFE, CommonJS (CJS), and ES Modules (ESM).
Q: How does source data work with the bundle method?
A: You provide an object where keys are filenames and values are the file content as strings. Our agent creates a virtual file system to process these, resolves imports between them, and returns the final bundled code.