
Security News
Meet Socket at Black Hat Europe and BSides London 2025
Socket is heading to London! Stop by our booth or schedule a meeting to see what we've been working on.
eslint-plugin-harlanzw
Advanced tools
Harlan's ESLint rules for Vue projects with focus on link hygiene, Nuxt best practices, and Vue reactivity patterns.
|
Made possible by my Sponsor Program 💖 Follow me @harlan_zw 🐦 |
Try the rules in action with a Nuxt ESLint interactive playground:
Note: These rules are experimental and may change. They will be submitted to the official Vue ESLint plugin for consideration.
The rules are organized into the following categories:
| Rule | Description |
|---|---|
link-ascii-only | ensure link URLs contain only ASCII characters |
link-lowercase | ensure link URLs do not contain uppercase characters |
link-no-double-slashes | ensure link URLs do not contain consecutive slashes |
link-no-whitespace | ensure link URLs do not contain whitespace characters |
nuxt-await-navigate-to | enforce awaiting navigateTo() calls |
nuxt-no-redundant-import-meta | disallow redundant import.meta.server or import.meta.client checks in scoped components |
nuxt-no-side-effects-in-async-data-handler | disallow side effects in async data handlers |
nuxt-no-side-effects-in-setup | disallow side effects in setup functions |
nuxt-prefer-navigate-to-over-router-push-replace | prefer navigateTo() over router.push() or router.replace() |
nuxt-prefer-nuxt-link-over-router-link | prefer NuxtLink over RouterLink |
vue-no-faux-composables | stop fake composables that don't use Vue reactivity |
vue-no-nested-reactivity | don't mix ref() and reactive() together |
vue-no-passing-refs-as-props | don't pass refs as props - unwrap them first |
vue-no-reactive-destructuring | avoid destructuring reactive objects |
vue-no-ref-access-in-templates | don't use .value in Vue templates |
vue-no-torefs-on-props | don't use toRefs() on the props object |
Install the plugin:
pnpm add -D eslint-plugin-harlanzw
// eslint.config.js
import antfu from '@antfu/eslint-config'
import harlanzw from 'eslint-plugin-harlanzw'
export default antfu(
{
vue: true,
},
{
plugins: {
harlanzw
},
rules: {
'harlanzw/link-ascii-only': 'error',
'harlanzw/link-lowercase': 'error',
'harlanzw/link-no-double-slashes': 'error',
'harlanzw/link-no-whitespace': 'error',
'harlanzw/nuxt-await-navigate-to': 'error',
'harlanzw/nuxt-no-redundant-import-meta': 'error',
'harlanzw/nuxt-no-side-effects-in-async-data-handler': 'error',
'harlanzw/nuxt-no-side-effects-in-setup': 'error',
'harlanzw/nuxt-prefer-navigate-to-over-router-push-replace': 'error',
'harlanzw/nuxt-prefer-nuxt-link-over-router-link': 'error',
'harlanzw/vue-no-faux-composables': 'error',
'harlanzw/vue-no-nested-reactivity': 'error',
'harlanzw/vue-no-passing-refs-as-props': 'error',
'harlanzw/vue-no-reactive-destructuring': 'error',
'harlanzw/vue-no-ref-access-in-templates': 'error',
'harlanzw/vue-no-torefs-on-props': 'error'
}
}
)
// eslint.config.mjs
import harlanzw from 'eslint-plugin-harlanzw'
import withNuxt from './.nuxt/eslint.config.mjs'
export default withNuxt([{
plugins: {
harlanzw
},
rules: {
'harlanzw/link-ascii-only': 'error',
'harlanzw/link-lowercase': 'error',
'harlanzw/link-no-double-slashes': 'error',
'harlanzw/link-no-whitespace': 'error',
'harlanzw/nuxt-await-navigate-to': 'error',
'harlanzw/nuxt-no-redundant-import-meta': 'error',
'harlanzw/nuxt-no-side-effects-in-async-data-handler': 'error',
'harlanzw/nuxt-no-side-effects-in-setup': 'error',
'harlanzw/nuxt-prefer-navigate-to-over-router-push-replace': 'error',
'harlanzw/nuxt-prefer-nuxt-link-over-router-link': 'error',
'harlanzw/vue-no-faux-composables': 'error',
'harlanzw/vue-no-nested-reactivity': 'error',
'harlanzw/vue-no-passing-refs-as-props': 'error',
'harlanzw/vue-no-reactive-destructuring': 'error',
'harlanzw/vue-no-ref-access-in-templates': 'error',
'harlanzw/vue-no-torefs-on-props': 'error'
}
}])
Add the plugin to your ESLint configuration:
// eslint.config.js
import harlanzw from 'eslint-plugin-harlanzw'
import vueParser from 'vue-eslint-parser'
export default [
{
files: ['**/*.vue'],
languageOptions: {
parser: vueParser
},
plugins: {
harlanzw
},
rules: {
'harlanzw/link-ascii-only': 'error',
'harlanzw/link-lowercase': 'error',
'harlanzw/link-no-double-slashes': 'error',
'harlanzw/link-no-whitespace': 'error',
'harlanzw/nuxt-await-navigate-to': 'error',
'harlanzw/nuxt-no-redundant-import-meta': 'error',
'harlanzw/nuxt-no-side-effects-in-async-data-handler': 'error',
'harlanzw/nuxt-no-side-effects-in-setup': 'error',
'harlanzw/nuxt-prefer-navigate-to-over-router-push-replace': 'error',
'harlanzw/nuxt-prefer-nuxt-link-over-router-link': 'error',
'harlanzw/vue-no-faux-composables': 'error',
'harlanzw/vue-no-nested-reactivity': 'error',
'harlanzw/vue-no-passing-refs-as-props': 'error',
'harlanzw/vue-no-reactive-destructuring': 'error',
'harlanzw/vue-no-ref-access-in-templates': 'error',
'harlanzw/vue-no-torefs-on-props': 'error'
}
}
]
This plugin is based on eslint-plugin-antfu by Anthony Fu.
Licensed under the MIT license.
FAQs
Harlan's opinionated ESLint rules
The npm package eslint-plugin-harlanzw receives a total of 75 weekly downloads. As such, eslint-plugin-harlanzw popularity was classified as not popular.
We found that eslint-plugin-harlanzw demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket is heading to London! Stop by our booth or schedule a meeting to see what we've been working on.

Security News
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.