TypeError: X is not a constructor means new X() was called and X is not a class or a constructor function. Usually X is undefined because of an import mismatch, or it is a module object when you wanted the class inside it, or it is an arrow function, which cannot be constructed by design. The name in the message is the expression you tried to construct; check what it actually holds.
Check what X is#
console.log(typeof Parser, Parser);
If it prints undefined, the import is wrong. If it prints object, you have a module or an instance rather than a class. If it prints function but construction still fails, it is an arrow function or a method. Each is below.
Cause 1: default vs named export#
// parser.js
export class Parser { ... } // a named export
// app.js
import Parser from './parser.js'; // default import: there is no default, so Parser is undefined
new Parser(); // TypeError: Parser is not a constructor
Match the export style:
import { Parser } from './parser.js'; // named import
The reverse mistake, import { Parser } from a module that does export default class Parser, produces the same error. Open the module and look at how it exports. Libraries are the usual source: some export a default, some export named members, and some changed between major versions.
Cause 2: CommonJS require gives the module#
// parser.js (CommonJS)
class Parser { ... }
module.exports = { Parser }; // exports an object containing the class
// app.js
const Parser = require('./parser'); // Parser is the object { Parser: [class] }
new Parser(); // TypeError: Parser is not a constructor
const { Parser } = require('./parser'); // destructure the class out
// or
const Parser = require('./parser').Parser;
Mixing ESM and CommonJS adds a variant: importing a CommonJS module from ESM gives you module.exports as the default import, so a library that does module.exports = SomeClass works with import SomeClass from 'lib', but one that exports an object needs import lib from 'lib'; new lib.SomeClass(). When in doubt, log the import.
Cause 3: arrow functions cannot be constructed#
const Point = (x, y) => { this.x = x; this.y = y; };
new Point(1, 2); // TypeError: Point is not a constructor
Arrow functions have no this of their own and no prototype, so new is meaningless for them. Use a class, or a regular function:
class Point {
constructor(x, y) { this.x = x; this.y = y; }
}
Object methods defined with the shorthand syntax, and async functions, and generator functions, are also not constructable.
Cause 4: it is an instance, not the class#
const db = new Database();
const another = new db(); // TypeError: db is not a constructor
You constructed from the instance rather than the class. Sometimes this is a library that exports a ready-made instance, a singleton, and you were expected to use it directly rather than construct it.
Cause 5: built-ins and globals#
new Math(); // TypeError: Math is not a constructor - it is a namespace object
new Symbol(); // TypeError: Symbol is not a constructor - call it without new
new Promise.resolve(); // parses as new (Promise.resolve)() - not a constructor
Some built-ins are objects, not classes; some are functions that refuse new; and operator precedence can make new apply to the wrong thing. Brackets fix the last one: new (Promise.resolve()) is still wrong, but it is at least clear what was meant.
Cause 6: circular imports#
Module A imports B, B imports A. Whichever loads second sees the other’s exports before they are assigned, so the class is temporarily undefined. The error appears only on some load orders, which makes it look random. Break the cycle by moving the shared class into a third module both can import.
Cause 7: minified or bundled code#
In a production bundle, class names are mangled, so the message says something like t is not a constructor. Enable source maps to see the original name, then apply the checks above. This error after a dependency upgrade almost always means the library changed its export shape between versions; read its changelog.
Questions people ask#
What is the difference from “is not a function”?
Same family. “Not a function” is a call without new; “not a constructor” is a call with it. The causes overlap almost entirely.
Can a class be called without new?
No; that throws “Class constructor cannot be invoked without new”. The two errors are mirror images.
Why does the library’s example work and mine does not?
Usually a different module system, or a different major version. Check that your import line matches the version you installed.
Does this happen in Node only?
No. It is the same in browsers; bundlers can add the mangled-name variant.
Where to go next#
- “x is not a function” — the companion error.
- “require is not defined” — the ESM vs CommonJS problem in full.
- Exporting functions in JavaScript — default vs named, decided properly.