Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to configure lint-staged in Vue

Running linters on every file in your Vue project before each commit can slow down your development workflow significantly, especially in large codebases. With 10 years of experience in Vue.js development since 2014 and as the creator of CoreUI, I’ve optimized countless development workflows to balance code quality with developer productivity. From my expertise, the most efficient solution is to use lint-staged to run ESLint and Prettier only on staged files, ensuring fast commits while maintaining code quality. This approach integrates seamlessly with Git hooks and reduces pre-commit time from seconds to milliseconds.

Use lint-staged to run linters only on staged Git files for faster commits.

npm install --save-dev lint-staged

Basic Configuration

Configure lint-staged in your package.json to run ESLint and Prettier on staged Vue files:

{
  "lint-staged": {
    "*.{js,jsx,vue}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,scss,vue}": [
      "prettier --write"
    ]
  }
}

This configuration runs ESLint with auto-fix and Prettier formatting on all staged JavaScript and Vue files. The --fix flag automatically corrects linting errors that can be fixed programmatically. For style files, only Prettier runs to ensure consistent formatting.

Installing Required Dependencies

Install ESLint and Prettier along with their Vue plugins:

npm install --save-dev eslint prettier eslint-plugin-vue
npm install --save-dev @vue/eslint-config-prettier

Create an .eslintrc.js file in your project root:

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    'plugin:vue/vue3-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'
  }
}

Advanced Configuration with File Patterns

Configure different linters for different file types with more specific patterns:

{
  "lint-staged": {
    "*.vue": [
      "eslint --fix",
      "prettier --write",
      "git add"
    ],
    "*.{js,jsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,scss,less}": [
      "prettier --write"
    ],
    "*.{json,md}": [
      "prettier --write"
    ]
  }
}

This configuration separates Vue files from JavaScript files, allowing you to apply different rules. The git add command at the end ensures that the fixed files are added back to the staging area.

Integrating with Husky

Combine lint-staged with Husky to automatically run linters on pre-commit:

npm install --save-dev husky
npx husky-init && npm install

Update the .husky/pre-commit file:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

Now lint-staged runs automatically before each commit, preventing badly formatted or linting-error code from being committed.

Using Separate Config File

For complex configurations, create a dedicated .lintstagedrc.js file:

module.exports = {
  '*.{js,jsx,vue}': [
    'eslint --fix --max-warnings 0',
    'prettier --write'
  ],
  '*.{css,scss,vue}': [
    'stylelint --fix',
    'prettier --write'
  ],
  '*.{json,md,yml,yaml}': [
    'prettier --write'
  ]
}

This JavaScript configuration file allows you to add comments, use variables, and apply more complex logic. The --max-warnings 0 flag ensures that commits fail if there are any ESLint warnings.

Excluding Files

Add patterns to exclude specific files or directories:

module.exports = {
  '*.{js,vue}': [
    'eslint --fix --ignore-path .gitignore',
    'prettier --write'
  ],
  '!(*test).{js,vue}': [
    'eslint --fix'
  ]
}

The --ignore-path .gitignore flag tells ESLint to respect your .gitignore file. The negation pattern !(*test).{js,vue} excludes test files from certain linters.

Running Type Checking

Add Vue TypeScript type checking to your lint-staged configuration:

{
  "lint-staged": {
    "*.{ts,tsx,vue}": [
      "vue-tsc --noEmit",
      "eslint --fix",
      "prettier --write"
    ]
  }
}

This runs Vue’s TypeScript compiler in no-emit mode to check for type errors before committing. Type checking catches errors early in the development process.

Performance Optimization

For large projects, optimize lint-staged performance with concurrent execution:

{
  "lint-staged": {
    "*.{js,vue}": [
      "eslint --fix --cache"
    ],
    "*.{css,scss}": [
      "prettier --write"
    ]
  }
}

The --cache flag makes ESLint cache its results, significantly speeding up subsequent runs. ESLint only processes files that have changed since the last run.

Testing the Configuration

Test your lint-staged configuration without making a commit:

npx lint-staged --debug

This command shows exactly which commands will run for your staged files. Use this to debug configuration issues or verify that your setup works correctly.

Running lint-staged Manually

Run lint-staged on specific files without a Git hook:

# Run on all staged files
npx lint-staged

# Run on specific files
npx lint-staged --files src/components/Button.vue

# Dry run to see what would happen
npx lint-staged --dry-run

The --files flag allows testing your configuration on specific files. The --dry-run flag shows which commands would run without executing them.

Handling Warnings vs Errors

Configure ESLint to treat warnings differently than errors:

module.exports = {
  '*.{js,vue}': [
    'eslint --fix --max-warnings 0'
  ]
}

The --max-warnings 0 flag causes the linting to fail if there are any warnings, ensuring your codebase stays completely clean. Remove this flag if you want to allow warnings.

Adding Stylelint for CSS

Include CSS/SCSS linting with Stylelint:

npm install --save-dev stylelint stylelint-config-standard

Create a .stylelintrc.js file:

module.exports = {
  extends: ['stylelint-config-standard'],
  rules: {
    'selector-class-pattern': null
  }
}

Update your lint-staged configuration:

{
  "lint-staged": {
    "*.{js,vue}": [
      "eslint --fix"
    ],
    "*.{css,scss,vue}": [
      "stylelint --fix",
      "prettier --write"
    ]
  }
}

This runs Stylelint on CSS and SCSS files as well as the style blocks in Vue components.

Common Configuration for Vue 3 Projects

Here’s a complete production-ready configuration for Vue 3 projects:

// .lintstagedrc.js
module.exports = {
  '*.{js,jsx,ts,tsx,vue}': [
    'eslint --fix --cache --max-warnings 0',
    'prettier --write'
  ],
  '*.{css,scss,vue}': [
    'stylelint --fix',
    'prettier --write'
  ],
  '*.{json,md,yml,yaml,html}': [
    'prettier --write'
  ]
}

With corresponding package.json scripts:

{
  "scripts": {
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "lint:fix": "eslint --ext .js,.vue --ignore-path .gitignore --fix .",
    "format": "prettier --write 'src/**/*.{js,vue,css,scss,json}'",
    "prepare": "husky install"
  }
}

Best Practice Note

At CoreUI, we use lint-staged across all our Vue projects to maintain consistent code quality without slowing down our development workflow. This configuration works particularly well with our Vue admin templates where maintaining clean code across large component libraries is essential. If you’re building a Vue application with complex Git workflows, consider setting up Husky with Vue to integrate lint-staged with other pre-commit checks. For optimal results, combine lint-staged with continuous integration to catch any issues that might slip through local checks.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.

Answers by CoreUI Core Team