expressjs/express · error · Error

Module "' + mod + '" does not provide a view engine.

Error message

Module "' + mod + '" does not provide a view engine.

What it means

When no engine is registered for a view's extension, Express auto-loads one by require()-ing the extension name and reading its __express export (lib/view.js:75-85). If the module loads but exports no __express function, Express throws because it has no (path, options, callback) render entry point to call.

Source

Thrown at lib/view.js:84

  if (!this.ext) {
    // get extension from default engine name
    this.ext = this.defaultEngine[0] !== '.'
      ? '.' + this.defaultEngine
      : this.defaultEngine;

    fileName += this.ext;
  }

  if (!opts.engines[this.ext]) {
    // load engine
    var mod = this.ext.slice(1)
    debug('require "%s"', mod)

    // default engine export
    var fn = require(mod).__express

    if (typeof fn !== 'function') {
      throw new Error('Module "' + mod + '" does not provide a view engine.')
    }

    opts.engines[this.ext] = fn
  }

  // store loaded engine
  this.engine = opts.engines[this.ext];

  // lookup path
  this.path = this.lookup(fileName);
}

/**
 * Lookup view by the given `name`
 *
 * @param {string} name
 * @private
 */

View on GitHub ↗ (pinned to a3714473fe)

Solutions

  1. Register the engine explicitly for that extension: app.engine('html', require('ejs').renderFile).
  2. Use consolidate.js for engines without __express: app.engine('mustache', require('consolidate').mustache).
  3. If you only want to send static HTML files, skip the view system: use express.static() or res.sendFile().
  4. Pin/downgrade the engine to a version that still exports __express, or check its docs for the new Express integration API.

Example fix

// before
app.set('view engine', 'html'); // require('html') has no __express
// after
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
Defensive patterns

Strategy: validation

Validate before calling

const engine = require('pug');
if (typeof engine.__express !== 'function') {
  throw new Error("Module 'pug' does not export __express; register it explicitly with app.engine()");
}

Type guard

function providesViewEngine(mod) {
  return mod && typeof mod.__express === 'function';
}

Try / catch

try {
  res.render('index');
} catch (err) {
  if (/does not provide a view engine/.test(err.message)) {
    // register manually: app.engine('hbs', require('hbs').__express) or the engine's documented adapter
  }
  next(err);
}

Prevention

When it happens

Trigger: Rendering a .html (or other) view whose extension maps to a package that isn't an Express-compatible engine — e.g. app.set('view engine', 'html') causes require('html'), or rendering 'page.mustache' when the mustache package (which lacks __express) is installed; any engine package that dropped or never had the __express convention.

Common situations: Setting 'view engine' to a file extension like 'html' hoping to serve static HTML (use express.static or app.engine('html', ...) instead); using mustache/swig/other engines that need consolidate.js; an engine major-version upgrade that removed __express; ESM-only engine versions whose CJS require() no longer exposes the export.

Related errors


AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31). Data as JSON: /data/errors/f514352f90f32643.json. Report an issue: GitHub ↗.