This page used to run your paste. That was a mistake.
An earlier build wrapped the snippet in new Function and then called the result. A syntax pass became a live interpreter sitting on a public page. fetch ran. Cookies were readable. A tight loop froze the tab. People pasted production helpers, forgot a debug call was still in the body, and watched the helper fire against whichever host still held a session.
The invoke is gone. new Function(source) still compiles source as the body of an anonymous function. A SyntaxError still throws when the grammar fails. The body never runs. console.log stays quiet. No request leaves the machine on account of the paste.
Green means the grammar parsed under that wrapper. Green does not mean the snippet is safe. Green does not mean merge it.
Four labels people mix up in a stand-up
A ticket that says "JS is broken" is usually one of four different failures. Mixing them wastes a morning.
- Syntax
- The engine refused to parse the source. A missing
), an unterminated string,importinside a function body, areturnin a classic script. This page answers this one. - Runtime
- The file parsed. Then a name was missing, a method ran on
null, or the DOM node was absent. None of that is visible here, because nothing executes. - Lint
- The file parsed and ran. A linter still has opinions:
==, an unused binding, a missing radix. Take that class of complaint to the JavaScript Validator, which runs JSHint. - Types
- TypeScript and JSDoc.
const n: number = 1is legal fortscand illegal fornew Function. There is no TypeScript mode on this page. Strip the types, or compile, before you paste.
The wrapper is a function body. Your file often is not.
People paste an ES module, watch the receipt go red, and argue with the banner. The failure is the wrapper.
new Function(source) compiles source as the body of an anonymous function. Function bodies allow return. Function bodies reject import and export. Node loading file.mjs, Vite bundling a component, and a classic <script src> each disagree with this wrapper in a different direction.
| Paste | This page (Function) | Classic <script src> | ES module / Vite / node file.mjs |
|---|---|---|---|
Missing } | Fails | Fails | Fails |
import / export | Fails | Fails | Succeeds |
Top-level return | Succeeds | Fails (Illegal return statement) | Fails |
host: string (TypeScript) | Fails | Fails | Fails until tsc or a strip plugin runs |
return then a newline then { ok: true } | Succeeds (returns undefined at runtime) | Parses. Same runtime surprise. | Parses. Same runtime surprise. |
Load the ES module trap above if you want to see the import case without typing. Load Stray return to see the opposite lie: a green receipt for a snippet a classic script tag would reject.
If a real paste starts with import, leave. Run the file under Node, or take mixed languages to the Code Syntax Validator. Debating the banner on this page wastes a stand-up.
Paste the forty lines the stack named. A webpack bundle is the wrong input. The receipt reports the first parse failure, not a review of three thousand generated lines.
Back to the editor if the paste is still sitting in the clipboard.
A line break after return is legal. The object you wrote is gone.
Automatic semicolon insertion is the part of JavaScript people swear they understand until a return sits on its own line.
function status() {return
{ok: true}}The grammar is fine. The Function constructor compiles it. At runtime the function returns undefined. The engine inserts a semicolon after return, then treats the braces as a block with a label ok. The object literal you thought you wrote never exists.
This page stays quiet. The JavaScript Playground, or the function running in the app, is where the surprise shows up. If the question is "why is my payload empty", a syntax checker is the wrong desk.
Load the Return ASI trap if you want the receipt in front of you while you read the next sentence. The receipt says compiled. The function still hands back nothing.
Four pastes. Four different machines.
Same forty seconds of typing. Four answers. The machine you run the file on is the one that matters, not the color of a banner in a tab.
Missing brace
Fails herefunction ping(host) {if (!host) {return 'missing host';}
return host.toLowerCase();Every engine fails. The reported line is often the next token the parser refused to reconcile, which sits below the brace you deleted. Read upward from the receipt, not downward.
ES module
Fails hereimport { ping } from './net.js'
export function check(host) {return ping(host)}Vite succeeds. node --check check.mjs succeeds. This page fails, because a function body is not a module. The file is not broken. The wrapper is the wrong shape.
Stray return
Passes hereconst n = 3
return n * 2This page succeeds. Load the same bytes with <script src="app.js"> and the browser throws Illegal return statement. A green receipt on a stray return is a warning label, not a blessing.
TypeScript
Fails herefunction ping(host: string): string {return host.toLowerCase()}tsc succeeds. A bundler with a strip plugin succeeds. new Function sees a colon in a parameter list and throws. Strip, or compile, then paste the JavaScript the engine will run.
Walk off this page when the question is not grammar
node --check file.js compiles as a script, not as a function body. Use it on a file you intend to ship as a classic script. Use node --check file.mjs for a module.
The JavaScript Validator runs JSHint. Unused bindings, ==, and a missing radix show up there. They will never show up here, because they are not parse errors.
After the receipt is green and you still cannot read the file, the JavaScript Beautifier reindents the paste. Indent first when the reported line sits far below the brace you deleted.
Need a return value, a log line, or a thrown TypeError? That is execution. Open the JavaScript Playground. Do not ask this page to grow an interpreter again.
Markup and stylesheets are different grammars. An unclosed <div> belongs on the HTML Syntax Validator. A missing brace in a rule block belongs on the CSS Syntax Validator.
The ceiling, named
- The engine is the JavaScript engine in this browser. Chrome, Firefox, and Safari disagree on a handful of newer productions. A pass in one tab is not a pass in every engine you ship to.
- JSX is not JavaScript.
<Panel />fails here the same way it fails in a raw<script>tag. Run the file through the JSX transform first. - Past roughly two hundred kilobytes the textarea starts to drag. Split the file. Paste the function the stack named.
- A balanced-looking snippet still hides a string that never closed, or a template literal that ate the rest of the file. The receipt names the first token the parser refused to swallow, which is often the last line.
- Nothing here knows your
tsconfig, Babel plugins, or the bundler's define replacements. Those rewrite the source before the engine sees it. Paste the rewrite, or paste after the build.
The snippet never leaves the tab. Compile, the file picker, and the findings copy all run in local JavaScript. Cut the network after the page has loaded and every button still works, which is the point when the paste holds a staging URL or an access token someone left in a comment.
