Skip to content
Happy Programming Guide
Start learning
JavaScript

Fixing “TypeError: x is not a constructor”

You used new on something that cannot be constructed: an arrow function, an object, an undefined import, or a module instead of its class. The causes and the import mistake behind most of them.

A home office desk with a computer

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#

JavaScript
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#

JavaScript
// 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:

JavaScript
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#

JavaScript
// 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
JavaScript
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#

JavaScript
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:

JavaScript
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#

JavaScript
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#

JavaScript
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#

Fixing 'require is not defined': ESM vs CommonJSRead next

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *