JavaScript Playground

You want to know whether a reduce chain returns what you think, or in which order two promises settle. Opening DevTools on a production tab to test that is a bad idea. Write the snippet here instead, press Run, and read the rendered result and the console side by side.

Saved in this browser

Result

Sandboxed frame, rebuilt on every run

Anything your code writes to the page shows up here.

Console

Your code runs in a frame of its own, not in this page

Every run builds a fresh sandboxed iframe, drops your HTML and CSS into it, then injects the JavaScript as a script element. The frame has no access to this page, no cookies, and no same-origin privileges. That separation is what makes it safe to paste code you half trust and press Run.

1. The frame is rebuilt

The previous frame is discarded first, so leftover intervals, listeners and globals from your last run are gone. Each run starts on clean state.

2. Console methods are wrapped

Before your script loads, the frame replaces the console methods with versions that serialize their arguments and post them out to the panel on the right.

3. Your script is appended

The code goes in as your-code.js, so thrown errors report a line number that matches what you typed rather than an offset into a wrapper.

The result panel and the console are two views of the same run. DOM writes land on the left, printed values on the right, and the status bar under the console reports how long the synchronous pass took.

Console methods the panel mirrors

Output is not piped through JSON.stringify, which drops functions and chokes on circular references. Objects are walked with a depth limit and printed in a shape closer to what a browser console shows.

MethodWhat appears in the panelDifference from DevTools
log, info, debugEach argument serialized and joined by a spaceObjects print expanded to four levels, not click-to-expand
warn, errorTinted rows that the filter chips count separatelySame behaviour
tableA monospace text table with aligned columnsText output rather than a sortable grid
time, timeEndElapsed milliseconds against the label you passedSame behaviour
count, assertRunning tally, or a failed assertion as an error rowSame behaviour
group, groupEndIndented rows under the group labelFlat indentation, no collapse control
dirThe value printed as an object even when it is a nodeNo interactive property tree
clearWipes the panel and resets the countersSame behaviour

Uncaught errors and rejected promises print without a console call. A rejection that nothing handles shows as unhandled rejection with the reason attached, which is the failure most people miss when they test async code by eye.

Reading async order instead of guessing it

The ordering question comes up constantly in interviews and in real bugs. Paste this, run it, and the answer stops being theory.

Code
console.log("A");setTimeout(() => console.log("D"), 0);Promise.resolve().then(() => console.log("C"));console.log("B");
Console panel
> A
> B
> C +0ms
> D +1ms

The timestamp on the right of each row counts from the moment the run started. Synchronous lines share the same figure, microtasks land before timers, and a value that appears 400ms later is doing real waiting rather than blocking. Watching those offsets is faster than reasoning about the event loop from memory.

When a run stops responding

A loop with no exit freezes the frame, not this page. After four seconds without a finish signal, a warning strip appears above the console with a Stop button. Stopping destroys the frame, which is the only reliable way to end a spinning loop in a browser.

  1. Check the loop condition first.while (i < n) with no i++ inside accounts for most hangs.
  2. Look for a recursive call with no base case. Those usually throw a stack overflow instead, which prints as an error row.
  3. Watch out for an interval you never clear. It keeps logging until you run again, since the next run replaces the frame.
  4. Cap the iterations while testing. Swap a million-row loop for a hundred rows until the logic reads correctly.

What this sandbox refuses to do

The isolation that makes the page safe also removes capabilities. Know these before you decide a snippet is broken.

Rule of thumb: this page is for a function, an algorithm, or a piece of DOM behaviour you hold in your head. Once the snippet needs a build step or a real server, it has outgrown a playground and belongs in your editor.

What people actually paste in here

Checking an array chain before it goes in a component
A filter into map into reduce reads fine and returns the wrong shape. Logging the intermediate arrays here takes twenty seconds and saves a round trip through a build.
Teaching or learning the event loop
Timestamps beside each row turn microtask and macrotask ordering into something you watch instead of something you memorise. The timing sample in the picker is built for that.
Reproducing a bug from a stack trace
Copy the failing function out of your codebase, stub the inputs, and run it alone. If it fails here too, the bug lives in the function rather than in the surrounding state.
Sketching DOM behaviour
Put markup in the HTML tab, a rule or two in the CSS tab, then wire a listener in JavaScript. Clicks inside the frame log to the console like they would on a page.
Verifying obfuscated or minified output
Run a transformed file next to the original and compare the console output line for line. Renaming breaks code that reads function names at runtime, and this is where that shows.

Nothing you type is uploaded

The editor, the sandbox and the console all live in this tab. No request carries your snippet to a server, which matters when the code holds an internal endpoint or a piece of unreleased logic. Your three tabs are kept in this browser's local storage so a reload does not wipe your work, and Reset clears them back to the sample. On a shared machine, hit Reset before you walk away.

Questions about running JavaScript here

Execution model, console behaviour, and the limits worth knowing before you blame your code.

Is my code sent to a server?

No. Execution happens inside a sandboxed iframe in your own browser and the console output is passed back through a postMessage call. The page makes no network request with your code in it.

Why does localStorage throw an error in my snippet?

The sandbox runs without same-origin access, so the browser blocks storage APIs and returns a security error. Keep test state in a variable, or move that part of the code to your own project.

Can I fetch data from an API?

Rarely. Requests leave with a null origin and almost every API rejects that in its CORS policy. Mock the response with a resolved promise to test the code around the request instead.

Does an infinite loop crash the page?

It freezes the preview frame only. After four seconds with no finish signal a Stop button appears, and pressing it destroys the frame and returns control. This page itself keeps responding throughout.

Are async results captured?

Yes. Timers, promise callbacks and interval ticks keep printing after the synchronous pass reports its duration, each row stamped with how many milliseconds after the start it fired.

Which JavaScript features are supported?

Whatever your browser supports natively, including classes, private fields, async and await, optional chaining and top level arrow functions. Import and export statements fail because the code loads as a classic script.

Why is the line number in an error slightly off?

The script is injected with a sourceURL of your-code.js so line numbers match your editor in Chrome and Edge. Firefox reports the same numbers for thrown errors, though a syntax error in the first line sometimes reports as line zero.

Can I keep several snippets?

One set of three tabs is stored in this browser. Use the Save .js button to keep a copy of a snippet you want back later, since loading a sample overwrites all three tabs.