← Blog
DevelopmentApril 29, 20259 min

JavaScript Sandbox: Running Code Safely in the Browser

How browser-based JS runners isolate and execute code, what they protect against, and practical use cases for running JavaScript without a backend.

Why Run JavaScript in the Browser?

A browser-based JavaScript runner lets you execute code snippets instantly — no Node.js installation, no terminal, no project setup. For quick tests, algorithm checks, and debugging, it is the fastest path from idea to result. All execution happens locally, so there is no code sent to any server.

The Security Challenge

Executing arbitrary JavaScript in a browser is inherently risky if it can access the host page. A malicious script could read your cookies, make authenticated requests on your behalf, or exfiltrate data. The sandbox must isolate the executed code from both the tool's DOM and the user's browser session.

Sandboxed iframe: The Core Mechanism

The standard approach is to run user code inside a sandbox iframe:

<iframe
  sandbox="allow-scripts"
  srcdoc="..."
  title="JS Runner"
/>

With only allow-scripts, the iframe:

  • Cannot access document.cookie from the parent domain
  • Cannot call window.parent methods
  • Cannot submit forms or navigate the top-level window
  • Runs in an opaque (null) origin — no same-origin access to the parent

Capturing console.log Output

One of the trickiest parts of a JS runner is capturing console.log output and displaying it in the UI. Since the code runs in an iframe, you can intercept via postMessage:

Injected into the iframe's srcdoc

const _log = console.log;
console.log = (...args) => {
  window.parent.postMessage({
    type: 'log',
    data: args.map(String)
  }, '*');
  _log(...args);
};

Host page listener

window.addEventListener('message', (e) => {
  if (e.data?.type === 'log') {
    appendToOutput(e.data.data.join(' '));
  }
});

Error Handling

Uncaught errors in the iframe can be captured via the onerror handler or by wrapping user code in a try-catch:

try {
  // user code
  USER_CODE
} catch (err) {
  window.parent.postMessage({
    type: 'error',
    message: err.message,
    stack: err.stack
  }, '*');
}

Infinite Loop Protection

A common pitfall is user code with an infinite loop that freezes the iframe. Since the iframe is a separate browsing context, it will freeze without freezing the host page — but the only recovery is to destroy and recreate the iframe.

Some advanced runners use Web Workers instead of iframes — workers can be terminated programmatically after a timeout:

const worker = new Worker(blobUrl);
const timeout = setTimeout(() => worker.terminate(), 5000);
worker.onmessage = (e) => {
  clearTimeout(timeout);
  displayResult(e.data);
};

Practical Use Cases

  • Algorithm testing: Paste a sorting function and test it with sample inputs without setting up a project
  • Regex debugging: Test a regex pattern against sample strings and see matches highlighted
  • JSON transformation: Write a quick Array.map() to reshape API response data
  • Date arithmetic: Calculate date differences, format timestamps, test Intl APIs
  • Interview prep: Practice coding problems in the browser with instant feedback
  • Demo snippets: Share a self-contained code example without a full CodeSandbox setup

Limitations of Browser Sandboxes

  • No file system access (unless File API is used)
  • No Node.js built-ins (fs, path, http) — browser APIs only
  • No require() or import from npm without a bundler
  • Performance constrained by browser JS engine (V8/SpiderMonkey) — not suitable for heavy computation

Try it yourself

Run JavaScript snippets in a secure browser sandbox — no DevTools or Node.js needed.

Open JS Runner →