{"id":20004,"library":"eslint-template-visitor","title":"eslint-template-visitor","description":"Simplify ESLint rule creation by visiting AST node templates instead of manually inspecting ESTree nodes. v2.3.2 supports ESLint >=7 and uses @babel/eslint-parser behind the scenes for template parsing. It offers a declarative API with template literals, variables, spread variables, and variable declaration variables. Maintained by futpib, with regular releases and active development. Differentiates from other template-based tools by integrating directly with ESLint's visitor pattern.","status":"active","version":"2.3.2","language":"javascript","source_language":"en","source_url":"https://github.com/futpib/eslint-template-visitor","tags":["javascript"],"install":[{"cmd":"npm install eslint-template-visitor","lang":"bash","label":"npm"},{"cmd":"yarn add eslint-template-visitor","lang":"bash","label":"yarn"},{"cmd":"pnpm add eslint-template-visitor","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for ESLint rule creation and AST parsing context.","package":"eslint","optional":false}],"imports":[{"note":"Default export is the factory function. Named import is incorrect.","wrong":"const { eslintTemplateVisitor } = require('eslint-template-visitor');","symbol":"default","correct":"import eslintTemplateVisitor from 'eslint-template-visitor';"},{"note":"CommonJS require returns the default export directly.","wrong":"const { template } = require('eslint-template-visitor');","symbol":"default (require)","correct":"const eslintTemplateVisitor = require('eslint-template-visitor');"},{"note":"template is a method on the object returned by the factory function, not a named export of the module.","wrong":"const { template } = eslintTemplateVisitor();","symbol":"template (after calling factory)","correct":"const templates = eslintTemplateVisitor(); const { template } = templates;"}],"quickstart":{"code":"const eslintTemplateVisitor = require('eslint-template-visitor');\nconst templates = eslintTemplateVisitor();\n\nconst objVar = templates.variable();\nconst argVar = templates.spreadVariable();\nconst substrCallTemplate = templates.template`${objVar}.substr(${argVar})`;\n\nmodule.exports = {\n  meta: {\n    type: 'suggestion',\n    docs: {\n      description: 'Prefer String#slice() over String#substr()',\n    },\n    fixable: 'code',\n  },\n  create(context) {\n    return templates.visitor({\n      [substrCallTemplate](node) {\n        const objectNode = substrCallTemplate.context.getMatch(objVar);\n        const argumentNodes = substrCallTemplate.context.getMatch(argVar);\n        const problem = {\n          node,\n          message: 'Prefer `String#slice()` over `String#substr()`.',\n        };\n        if (argumentNodes.length === 0) {\n          problem.fix = fixer => fixer.replaceText(node, context.getSourceCode().getText(objectNode) + '.slice()');\n        }\n        context.report(problem);\n      },\n    });\n  },\n};","lang":"javascript","description":"ESLint rule using template visitor to detect and optionally fix .substr() calls."},"warnings":[{"fix":"Update parser options if needed, ensure @babel/eslint-parser is installed as a direct dependency.","message":"Upgraded parser from babel-eslint to @babel/eslint-parser in v2.3.0. Existing templates that relied on babel-eslint-specific behavior may break.","severity":"breaking","affected_versions":">=2.3.0"},{"fix":"Upgrade to v2.3.0 or later to avoid deprecated babel-eslint.","message":"The old babel-eslint parser is deprecated; v2.3.0 switched to @babel/eslint-parser.","severity":"deprecated","affected_versions":"<2.3.0"},{"fix":"Ensure template string contains exactly one top-level AST node.","message":"Template cannot have more than one top-level node. Throws an error in v2.1.0+.","severity":"gotcha","affected_versions":">=2.1.0"},{"fix":"Use ${variableDeclarationVariable} x = y; instead of ${variableDeclarationVariable} x = y; with wrong placement.","message":"Variable declaration variable (variableDeclarationVariable) must be used in place of the declaration keyword (const/let/var), not the entire declaration node.","severity":"gotcha","affected_versions":">=2.1.0"},{"fix":"Use templates.variable() for a single node match, templates.spreadVariable() for an array.","message":"Spread variable matches an array of nodes, not a single node. Mistaking it for a regular variable leads to incorrect type errors.","severity":"gotcha","affected_versions":"all"},{"fix":"Upgrade ESLint to version 7 or later.","message":"Removal of support for ESLint <7.0.0. Peer dependency requires eslint >=7.","severity":"breaking","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Call eslintTemplateVisitor() to get the templates object, then use templates.template.","cause":"Calling template on the default export directly without calling eslintTemplateVisitor first.","error":"TypeError: templates.template is not a function"},{"fix":"Wrap the template in a block or ensure only one top-level node.","cause":"Template string contains multiple top-level statements or expressions.","error":"Error: Template must have exactly one top-level node"},{"fix":"Install @babel/eslint-parser: npm install --save-dev @babel/eslint-parser","cause":"@babel/eslint-parser is required as a dependency since v2.3.0 but not installed.","error":"Cannot find module '@babel/eslint-parser'"},{"fix":"Use substrCallTemplate.context.getMatch(objVar) not context.getMatch.","cause":"Accessing getMatch incorrectly (e.g., on context instead of template context).","error":"TypeError: context.getMatch is not a function"},{"fix":"Add const eslintTemplateVisitor = require('eslint-template-visitor'); or import statement.","cause":"Forgetting to import/require the module.","error":"ReferenceError: eslintTemplateVisitor is not defined"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}