eslint-plugin-vue is the official ESLint plugin for Vue.js, and while it is a code-quality and correctness tool rather than a security scanner, configuring it well eliminates several patterns that commonly become security bugs in Vue applications. If you write Vue single-file components, this plugin is what lets ESLint understand .vue files at all — the <template>, <script>, and <style> blocks that a plain JavaScript parser cannot read.
Setting up Vue ESLint correctly is worth a few minutes because the alternative is silent gaps: without the plugin, ESLint simply skips your template markup, and the template is exactly where cross-site scripting sneaks into a Vue app.
What eslint-plugin-vue is and is not
The plugin ships rule sets that catch template syntax errors, deprecated APIs, reactivity mistakes, and style inconsistencies. It parses SFCs using vue-eslint-parser so rules can reason about directives like v-if, v-for, and v-html.
What it is not: a taint-analysis engine. It does not trace user input from a network response into the DOM. So calling it a "security tool" oversells it. Its security value is indirect but real — it flags the constructs most likely to cause trouble and enforces consistency that makes review easier.
The rule that matters most for security: v-html
The single most dangerous directive in Vue is v-html, because it renders raw HTML into the DOM without escaping. Any user-controlled string passed to it is a stored or reflected XSS waiting to happen.
eslint-plugin-vue ships vue/no-v-html, which flags every use so nothing slips in unreviewed:
// eslint.config.js (flat config)
import pluginVue from 'eslint-plugin-vue';
export default [
...pluginVue.configs['flat/recommended'],
{
rules: {
'vue/no-v-html': 'error',
},
},
];
Turning this to error does not mean you can never render HTML — it means every exception is deliberate. When you genuinely need to render markup (say, sanitized rich text), you sanitize with a library like DOMPurify first and add an inline disable comment that documents why. That comment becomes a searchable audit trail of every raw-HTML sink in your codebase.
Enabling the recommended config
Most teams under-configure the plugin, using only the base rules. The flat/recommended (or plugin:vue/vue3-recommended in the legacy config format) tier catches far more. It enforces attribute ordering, flags unused directives, and warns on patterns that break reactivity — the kind of subtle bug that leads to stale, incorrect UI state, which in an auth-gated view can mean showing content that should be hidden.
Pair it with @typescript-eslint if you use TypeScript, and with a security-focused plugin such as eslint-plugin-security for the JavaScript logic itself. eslint-plugin-vue handles the Vue-specific surface; it does not replace general JavaScript linting.
Keeping the toolchain itself trustworthy
eslint-plugin-vue is a dev dependency, which means it runs on your developers' machines and in CI with full filesystem access. A compromised release of any dev dependency is a supply-chain risk regardless of how benign the package's purpose is. Linters and formatters are attractive targets precisely because everyone installs them and few people read their source.
Sensible hygiene:
- Commit your lockfile and pin the plugin version so CI is reproducible.
- Review the changelog before bumping across major versions; ESLint plugins occasionally change rule defaults in ways that mask real issues.
- Run dependency scanning across your
devDependencies, not just runtime deps. An SCA tool will map installed versions to advisories including in the ESLint plugin tree, and a tool such as Safeguard can flag a risky transitive dependency you never installed on purpose.
I am not aware of a critical exploited CVE in eslint-plugin-vue itself, and its role as a build-time linter limits the blast radius. But dev dependencies deserve the same monitoring as production ones; the 2018 event-stream incident showed that a popular, unglamorous package is a fine place to hide malicious code.
A practical secure baseline
For a new Vue 3 project, a reasonable starting configuration is:
- Extend
flat/recommended. - Set
vue/no-v-htmltoerror. - Add
eslint-plugin-securityfor the script logic. - Wire ESLint into a pre-commit hook and CI so no unlinted code merges.
- Scan dependencies (including dev) in the same pipeline.
That combination will not stop every bug, but it removes the cheap, avoidable ones and forces a human decision on the dangerous constructs. For how static linting complements dynamic testing of the running app, see our DAST overview.
FAQ
Does eslint-plugin-vue prevent XSS?
Not by itself. It flags the risky v-html directive via vue/no-v-html, which forces you to review every raw-HTML render, but it does not sanitize input or trace tainted data. You still need to sanitize user content before rendering it as HTML.
Should I use the recommended config or just the base rules?
Use the recommended tier. The base rules catch only essential parsing errors; the recommended set enforces the correctness and reactivity rules that prevent the subtle state bugs which can leak gated content.
Is eslint-plugin-vue safe to install?
As a widely used official plugin it is generally trustworthy, but treat it like any dev dependency: pin the version, review major upgrades, and include it in dependency scanning. Its build-time role limits, but does not eliminate, supply-chain risk.
Can it replace a security scanner?
No. eslint-plugin-vue is a linter for Vue code quality and correctness. Combine it with general JavaScript security linting, dependency scanning, and dynamic testing for real coverage.