Checking JavaScript syntax without running it
A JavaScript syntax checker parses your code and reports the first grammar error, such as an unclosed bracket, a stray comma or a misplaced keyword, without executing any of it. This one hands your code to the JavaScript engine already built into your browser, so the rules it applies are exactly the ones your browser uses, and it tells you the line and column of the problem.
Under the hood the code is loaded as a classic <script> inside a hidden, sandboxed iframe that's created for the check and removed straight after. A line that throws is placed in front of your code. The engine has to parse the whole script against the grammar in ECMA-262 before running anything, so a syntax error is reported with its position, and valid code stops at that first throw. In Chrome and Edge the engine is V8; in Firefox it's SpiderMonkey, which phrases errors differently.
Script, module or function body?
Your code is checked as a normal, non-strict browser script, the same way a <script> tag would load it:
| Code | Result here (script) | As a module |
|---|---|---|
import fs from 'fs'; |
Error | Valid |
export const x = 1; |
Error | Valid |
const r = await fetch('/x'); |
Error | Valid (top-level await) |
return 5; |
Error | Error |
var let = 1; |
Valid | Error (modules are strict) |
So a pass here is a strong signal for classic scripts and a weaker one for ES modules. To check module code, strip the import/export lines and top-level await first. Code you'll paste into a function body is checked fine too, as long as it doesn't use return outside a function.
One browser rule surprises people: let, const and class can't redeclare the page's built-in globals that are locked, such as document, window, location and top. let document = 1; fails here exactly as it would on a real page.
Messages from real mistakes
The same input produces different wording in different browsers. Both columns below are actual output (each message is followed by its line and column):
| Mistake | Chrome / Edge | Firefox |
|---|---|---|
function greet(name { |
Unexpected token '{' | missing ) after formal parameters |
if (x) { never closed |
Unexpected end of input | missing } in compound statement |
let x declared twice |
Identifier 'x' has already been declared | redeclaration of let x |
const a; |
Missing initializer in const declaration | missing = in const declaration |
let s = "abc; |
Invalid or unexpected token | literal not terminated before end of script |
import fs from 'fs'; |
Cannot use import statement outside a module | import declarations may only appear at top level of a module |
return 5; at the top level |
Illegal return statement | return not in function |
For an unclosed brace, the position points at the end of the code, since that's where the parser discovers the block never ended. Look upwards from there for the {, ( or [ that lost its partner.
Using it well
- Paste the code and click Validate.
- If you get an error, go to the line and column it names and look at that spot and the line before it.
- For a hard-to-find error, paste half the code, validate, and keep halving the half that fails. It finds a single bad character in a few hundred lines in a handful of runs.
- When you see "Valid JavaScript syntax", move on to linting or running tests; a valid parse says nothing about whether the code works.
A syntax check is not a linter
Syntax is the narrowest kind of correctness. These all pass, because they're grammatical:
- calling a function that doesn't exist, or misspelling a method (
arr.lenght); - using
=where you meant===inside anif; - unreachable code after a
returninside a function; - trailing commas in calls (
f(a, b,)), which are valid in modern JavaScript.
Catching those is ESLint's job, or TypeScript's if you add types. What this tool is good for is the quick question in the middle of an edit: "did I break the brackets?" Pasting a snippet here is faster than reloading a page and reading the console.
For a longer session with syntax highlighting, the online JavaScript editor shows errors as you type. If the code is minified or badly indented, the code beautifier makes bracket mismatches easier to see. The JavaScript cheat sheet and the JavaScript lessons cover the syntax rules behind the messages above.
Last updated