Developer Lab
An editor, a sandboxed preview, and a shelf for the code worth keeping. What runs, what is only stored, and why.
What the lab does
- Three panes — HTML, CSS, JavaScript — with a byte counter on each
- A monospace editor that handles Tab, and says plainly that it does not colour your syntax
- Named workspaces that save, re-open and stay yours
- Run composes the three panes into one document and shows it beside your code
- console.log, warnings, errors and unhandled rejections arrive in a console pane
- Nothing rebuilds while you type. The frame only changes when you ask it to
- Save any pane as a snippet, in HTML, CSS, JavaScript or PHP
- Publish one and it gets a public page: escaped code, a copy button, an opt-in preview
- A history of your runs, and the number that remain today
Try it on our code
Three panes, one frame, and a console — the same arrangement the sandbox gives you, with the example already written.
This example is ours, not something a stranger published, and it still does nothing until you ask. Press run and the frame composes the three panes the way the sandbox composes yours.
The frame has no origin of its own, so the code in it cannot read this site’s cookies, storage, or page, and cannot call the server with your session. It can loop forever, which is what Stop is for. `alert()` does not open — the console says so instead, which is why the silence is not a bug.
Read the three panes
HTML (358 bytes)
<main class="note">
<h1>Three panes, one frame</h1>
<p>
This heading is the HTML pane. The card around it is the CSS pane. The
counter below is written by the JavaScript pane, and nothing on this page
came from your account.
</p>
<button type="button" id="poke">Count</button>
<p class="count" id="count" aria-live="polite"></p>
</main>
CSS (1,040 bytes)
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 1.5rem;
box-sizing: border-box;
background: #0b1120;
color: #e2e8f0;
font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
}
.note {
max-width: 30rem;
padding: 1.75rem;
border: 1px solid #1e293b;
border-radius: 16px;
background: #111827;
box-shadow: 0 18px 40px -24px rgba(2, 6, 23, 0.9);
}
h1 {
margin: 0 0 0.625rem;
font-size: 1.25rem;
font-weight: 600;
letter-spacing: -0.01em;
}
p {
margin: 0 0 1.25rem;
font-size: 0.875rem;
line-height: 1.65;
color: #94a3b8;
}
button {
font: inherit;
font-size: 0.875rem;
padding: 0.5rem 1.1rem;
border: 1px solid #134e4a;
border-radius: 999px;
background: #0f2e2b;
color: #5eead4;
cursor: pointer;
}
button:hover {
border-color: #2dd4bf;
}
button:active {
transform: translateY(1px);
}
.count {
margin: 1rem 0 0;
min-height: 1.2rem;
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 0.8rem;
color: #5eead4;
}
JavaScript (546 bytes)
var output = document.getElementById('count');
var clicks = 0;
console.log('Frame ready. Anything this script logs arrives in the panel beside it.');
document.getElementById('poke').addEventListener('click', function () {
clicks += 1;
output.textContent = clicks === 1
? 'One click, handled in the JavaScript pane.'
: clicks + ' clicks. The number is written into the HTML pane\'s element.';
console.log('click #' + clicks);
if (clicks === 5) {
console.warn('Five. A warning is coloured differently from a log.');
}
});
Each pane of a real workspace is capped at 30,000 bytes, and this example fits well inside all three.
A loop belongs to the frame, not to this site: Run again or Stop replaces the document and the tab stays yours. There is no CPU limit, because a browser does not hand the page one to enforce.
Nothing logged yet. console.log, console.warn and uncaught errors from the frame arrive here.
What the lab will not do
There is no server-side runner. Nothing this lab stores is executed by the application, which means no CPU quota, no container, and no PHP. The four limits that follow are the design, not oversights:
- A PHP snippet is text. It is listed, escaped on every page, and copyable. The Run button does not appear for it, and the action that records a run refuses the language on the server as well as in the interface, so the absence is not a hidden control.
- The preview has no origin. The frame is sandboxed without same-origin permission, so a page running in it cannot read this site's cookies, its storage, or the document around it, and cannot call back into the application with your session attached.
- An infinite loop hangs your tab. Run rebuilds the frame, so pressing Run again replaces a looping document with a fresh one, and the daily allowance limits how often the button may be pressed. There is no timeout, because a browser does not give the page one to enforce.
- `alert()`, `confirm()` and `prompt()` do not open. A modal from a sandboxed frame would be the frame speaking to your browser rather than to itself, so the console pane says what was called instead.
Specification: docs/lab.md