{"id":"f514352f90f32643","repo":"expressjs/express","slug":"module-mod-does-not-provide-a-view-engin","errorCode":null,"errorMessage":"Module \"' + mod + '\" does not provide a view engine.","messagePattern":"Module \"' \\+ mod \\+ '\" does not provide a view engine\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/view.js","lineNumber":84,"sourceCode":"  if (!this.ext) {\n    // get extension from default engine name\n    this.ext = this.defaultEngine[0] !== '.'\n      ? '.' + this.defaultEngine\n      : this.defaultEngine;\n\n    fileName += this.ext;\n  }\n\n  if (!opts.engines[this.ext]) {\n    // load engine\n    var mod = this.ext.slice(1)\n    debug('require \"%s\"', mod)\n\n    // default engine export\n    var fn = require(mod).__express\n\n    if (typeof fn !== 'function') {\n      throw new Error('Module \"' + mod + '\" does not provide a view engine.')\n    }\n\n    opts.engines[this.ext] = fn\n  }\n\n  // store loaded engine\n  this.engine = opts.engines[this.ext];\n\n  // lookup path\n  this.path = this.lookup(fileName);\n}\n\n/**\n * Lookup view by the given `name`\n *\n * @param {string} name\n * @private\n */","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/expressjs/express/blob/a3714473feb3d2908add734d340e7755fd85e0a3/lib/view.js#L66-L102","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Register the engine explicitly for that extension: app.engine('html', require('ejs').renderFile).","Use consolidate.js for engines without __express: app.engine('mustache', require('consolidate').mustache).","If you only want to send static HTML files, skip the view system: use express.static() or res.sendFile().","Pin/downgrade the engine to a version that still exports __express, or check its docs for the new Express integration API."],"exampleFix":"// before\napp.set('view engine', 'html'); // require('html') has no __express\n// after\napp.engine('html', require('ejs').renderFile);\napp.set('view engine', 'html');","handlingStrategy":"validation","validationCode":"const engine = require('pug');\nif (typeof engine.__express !== 'function') {\n  throw new Error(\"Module 'pug' does not export __express; register it explicitly with app.engine()\");\n}","typeGuard":"function providesViewEngine(mod) {\n  return mod && typeof mod.__express === 'function';\n}","tryCatchPattern":"try {\n  res.render('index');\n} catch (err) {\n  if (/does not provide a view engine/.test(err.message)) {\n    // register manually: app.engine('hbs', require('hbs').__express) or the engine's documented adapter\n  }\n  next(err);\n}","preventionTips":["Verify the template package is installed and listed in dependencies (not just present locally).","For engines without __express (e.g. handlebars, nunjucks), register an adapter explicitly via app.engine(ext, fn).","Match the extension in app.set('view engine', ...) to the module name Express will require.","Exercise one render at startup so a missing/incompatible engine fails on boot."],"tags":["express","view-engine","template-engine","module-resolution"],"analyzedSha":"a3714473feb3d2908add734d340e7755fd85e0a3","analyzedAt":"2026-07-31T18:55:36.968Z","schemaVersion":2}