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.
| Method | What appears in the panel | Difference from DevTools |
|---|---|---|
| log, info, debug | Each argument serialized and joined by a space | Objects print expanded to four levels, not click-to-expand |
| warn, error | Tinted rows that the filter chips count separately | Same behaviour |
| table | A monospace text table with aligned columns | Text output rather than a sortable grid |
| time, timeEnd | Elapsed milliseconds against the label you passed | Same behaviour |
| count, assert | Running tally, or a failed assertion as an error row | Same behaviour |
| group, groupEnd | Indented rows under the group label | Flat indentation, no collapse control |
| dir | The value printed as an object even when it is a node | No interactive property tree |
| clear | Wipes the panel and resets the counters | Same 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.
console.log("A");setTimeout(() => console.log("D"), 0);Promise.resolve().then(() => console.log("C"));console.log("B");> A
> B
> C +0ms
> D +1msThe 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.
- Check the loop condition first.
while (i < n)with noi++inside accounts for most hangs. - Look for a recursive call with no base case. Those usually throw a stack overflow instead, which prints as an error row.
- Watch out for an interval you never clear. It keeps logging until you run again, since the next run replaces the frame.
- 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.
- No storage APIsThe frame runs on an opaque origin, so
localStorageandsessionStoragethrow a security error. Hold state in a variable while you test. - Most network calls failA
fetchto an outside API is refused unless that server allows a null origin, which almost none do. Test request code against your own backend. - No module importsCode goes in as a classic script, so
importat the top is a syntax error. Paste the dependency inline or load it through the HTML tab with a script tag. - No TypeScript, JSX or npm packagesOnly what the browser parses natively. Compile first, then bring the output here.
- Snapshots, not a test runnerThere is no assertion library and no pass or fail report. For a suite with expectations, run it in your project.
- Heavy loops are slow to printTen thousand log lines take time to serialize and render. The panel keeps the last 600 rows and drops older ones.
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
filterintomapintoreducereads 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.
