
Vue.js with ESLint and Prettier Setup Guide
Setting up Vue.js with ESLint and Prettier is like having a stern code reviewer and a perfectionist formatter working together to keep your codebase clean and consistent. ESLint catches potential bugs and enforces coding standards, while Prettier handles the formatting automatically, eliminating those endless debates about semicolons and indentation. This guide walks you through the complete setup process, from initial configuration to advanced customization, plus troubleshooting the inevitable conflicts that arise when these tools don’t play nice together.
How ESLint and Prettier Work Together
ESLint is a static analysis tool that identifies problematic patterns in JavaScript code, while Prettier is an opinionated code formatter that enforces consistent style. The challenge is that they sometimes step on each other’s toes – ESLint might complain about formatting that Prettier automatically applies.
The solution involves three key packages:
- eslint-config-prettier – Disables ESLint rules that conflict with Prettier
- eslint-plugin-prettier – Runs Prettier as an ESLint rule
- @vue/eslint-config-prettier – Vue-specific integration
This setup lets you run eslint --fix
and get both linting and formatting in one command, which is particularly useful for CI/CD pipelines and pre-commit hooks.
Step-by-Step Setup Guide
Starting with a fresh Vue.js project gives you the cleanest setup. If you’re working with an existing project, you might need to resolve some conflicts along the way.
Creating a New Vue Project with ESLint
Use Vue CLI to scaffold a project with ESLint pre-configured:
npm install -g @vue/cli
vue create my-vue-app
# Select the following options:
# - Manually select features
# - Choose Vue version: 3.x
# - Linter / Formatter: ESLint + Prettier
# - ESLint config: ESLint + Prettier
# - Lint on save: Yes
If you prefer Vite over Vue CLI:
npm create vue@latest my-vue-app
cd my-vue-app
npm install
Manual Installation for Existing Projects
For existing Vue projects, install the necessary packages:
npm install --save-dev eslint prettier
npm install --save-dev eslint-plugin-vue
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
npm install --save-dev @vue/eslint-config-prettier
Create an .eslintrc.js
file in your project root:
module.exports = {
root: true,
env: {
node: true,
'vue/setup-compiler-macros': true
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/prettier'
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'vue/multi-word-component-names': 'off'
}
}
Create a .prettierrc
file for Prettier configuration:
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"printWidth": 80,
"bracketSpacing": true,
"arrowParens": "avoid"
}
Add a .prettierignore
file to exclude certain files:
dist/
node_modules/
*.min.js
*.map
package-lock.json
yarn.lock
Package.json Scripts
Add these useful scripts to your package.json
:
{
"scripts": {
"lint": "eslint --ext .js,.vue --ignore-path .eslintignore .",
"lint:fix": "eslint --ext .js,.vue --ignore-path .eslintignore . --fix",
"format": "prettier --write \"src/**/*.{js,vue,css,scss,html}\"",
"format:check": "prettier --check \"src/**/*.{js,vue,css,scss,html}\""
}
}
Configuration Options and Customization
The default setup works well, but you’ll likely want to customize rules based on your team’s preferences. Here are some common configurations:
Stricter Vue.js Rules
For more comprehensive Vue.js linting, use the recommended or strongly-recommended rule sets:
module.exports = {
extends: [
'plugin:vue/vue3-strongly-recommended', // or vue3-recommended
'eslint:recommended',
'@vue/prettier'
],
rules: {
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
'vue/require-default-prop': 'error',
'vue/require-prop-types': 'error',
'vue/no-unused-properties': 'warn'
}
}
TypeScript Support
If you’re using TypeScript, install additional packages:
npm install --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser
npm install --save-dev @vue/eslint-config-typescript
Update your ESLint configuration:
module.exports = {
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/typescript/recommended',
'@vue/prettier',
'@vue/prettier/@typescript-eslint'
],
parserOptions: {
ecmaVersion: 2020
}
}
IDE Integration and Workflow
Getting your editor to work seamlessly with ESLint and Prettier saves tons of time. Here’s how to set up the most popular editors:
VS Code Setup
Install these extensions:
- ESLint by Microsoft
- Prettier – Code formatter by Prettier
- Vetur or Volar for Vue.js support
Create a .vscode/settings.json
file:
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": [
"javascript",
"javascriptreact",
"vue"
],
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
Pre-commit Hooks with Husky
Enforce code quality before commits hit your repository:
npm install --save-dev husky lint-staged
# Initialize husky
npx husky install
npm pkg set scripts.prepare="husky install"
# Add pre-commit hook
npx husky add .husky/pre-commit "npx lint-staged"
Add this to your package.json
:
{
"lint-staged": {
"*.{js,vue}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,html,json,md}": [
"prettier --write"
]
}
}
Common Issues and Troubleshooting
Here are the most frequent problems you’ll encounter and their solutions:
Conflicting Rules
If ESLint and Prettier are fighting over formatting, you’ll see errors like:
Expected 1 space after 'if' keyword eslint(keyword-spacing)
Delete ';' prettier/prettier
The fix is ensuring @vue/prettier
comes last in your extends array:
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/prettier' // Must be last
]
Import/Export Issues
If you see “Parsing error: Unexpected token import”, your parser isn’t configured for ES6 modules:
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module'
}
Vue 3 Composition API
For Vue 3 with <script setup>
, add this to your ESLint config:
env: {
'vue/setup-compiler-macros': true
}
Performance Issues
Large codebases might experience slow linting. Create an .eslintignore
file:
node_modules/
dist/
*.min.js
coverage/
.nuxt/
Comparison with Alternative Setups
Setup | Pros | Cons | Best For |
---|---|---|---|
ESLint + Prettier | Comprehensive, configurable, great IDE support | Complex configuration, potential conflicts | Team projects, strict standards |
ESLint only | Simple setup, fewer dependencies | Limited formatting capabilities | Solo projects, minimal setup |
Prettier only | Zero config formatting | No code quality checks | Pure formatting needs |
Standard.js | No configuration needed | Opinionated, less flexible | Quick prototypes, standard adherence |
Real-World Use Cases and Examples
Here’s a practical example of how this setup improves code quality in a Vue.js component:
Before ESLint/Prettier
<template>
<div class="user-card">
<h2>{{user.name}}</h2>
<p v-if="user.email">{{ user.email }}</p>
<button @click="deleteUser">Delete</button>
</div>
</template>
<script>
export default{
name:'UserCard',
props:{
user:Object
},
methods:{
deleteUser(){
console.log('Deleting user...')
this.$emit('delete',this.user.id)
}
}
}
</script>
After ESLint/Prettier
<template>
<div class="user-card">
<h2>{{ user.name }}</h2>
<p v-if="user.email">{{ user.email }}</p>
<button @click="deleteUser">Delete</button>
</div>
</template>
<script>
export default {
name: 'UserCard',
props: {
user: {
type: Object,
required: true
}
},
emits: ['delete'],
methods: {
deleteUser() {
this.$emit('delete', this.user.id)
}
}
}
</script>
The automated fixes include proper indentation, spacing, prop validation, and explicit emits declaration – all crucial for maintainable Vue.js applications.
Best Practices and Advanced Configuration
Once you have the basic setup running, consider these advanced practices:
Environment-Specific Rules
Different rules for development and production:
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
'vue/no-unused-vars': process.env.NODE_ENV === 'production' ? 'error' : 'warn'
}
Custom Rule Configuration
Tailor rules to your team’s needs:
rules: {
'vue/max-attributes-per-line': ['error', {
'singleline': 3,
'multiline': 1
}],
'vue/html-self-closing': ['error', {
'html': {
'void': 'always',
'normal': 'never',
'component': 'always'
}
}]
}
CI/CD Integration
Add linting to your CI pipeline:
# GitHub Actions example
name: Code Quality
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm ci
- run: npm run lint
- run: npm run format:check
This setup creates a robust development environment where code quality is maintained automatically. The initial configuration might seem complex, but it pays dividends in reduced bugs, consistent formatting, and smoother code reviews. For comprehensive documentation, check the official Vue ESLint plugin docs and Prettier’s configuration guide.
Remember that tools should serve your team, not the other way around. Start with the recommended configuration and adjust rules based on your actual development experience and team preferences.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.