Common causes
1. Unbalanced braces or brackets
An extra } after a function, or a missing ) in a callback, leaves a closing token with nothing to close. Formatting the code makes the mismatch visible.
function total(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}}function total(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}2. Unexpected token '<': the script URL returns HTML
When a <script src> points to a missing file, many servers and single-page-app fallbacks return index.html, and the browser tries to run <!DOCTYPE html> as JavaScript. Fix the path, or the base URL your bundler writes into the page.
<script src="static/js/app.js"></script><script src="/static/js/app.js"></script>3. Unexpected token 'export' or 'import': ES modules run as CommonJS
Node.js treats .js files as CommonJS unless package.json says otherwise, and browsers need type="module" on the script tag. Mark the package as a module (or rename files to .mjs).
{
"name": "invoice-tool",
"main": "index.js"
}{
"name": "invoice-tool",
"type": "module",
"main": "index.js"
}4. Unexpected token ':': an object literal read as a block
An arrow function body that starts with { is a block, not an object, so { x: x, y: y } is parsed as a label followed by an error. Wrap the object in parentheses.
const toPoint = (x, y) => { x: x, y: y };const toPoint = (x, y) => ({ x: x, y: y });5. TypeScript or JSX in a plain .js file
Type annotations and JSX are not JavaScript. Without a compiler step (tsc, Babel, esbuild), const port: number fails at the colon. Remove the annotation, or rename the file and compile it.
const port: number = 3000;const port = 3000;Frequently asked questions
What is the difference between Unexpected token and Unexpected identifier?
Unexpected identifier means a name appeared where it cannot, often because a comma, operator or semicolon is missing before it. Unexpected token is reported for punctuation and keywords.
Why does the error point at the end of the file?
If a brace or bracket is never closed, the parser only fails when the code runs out, and some engines report “Unexpected end of input” instead. Look for the opening token that has no partner.
How do I see what was served for a script that fails with '<'?
Open the script URL directly in the browser, or check the Network tab: if the response starts with <!DOCTYPE html> or has a text/html content type, the path is wrong or the server is returning an error page.