# Fix VS Code Conflicting Formatters Prettier and ESLint on Save

Every time you save a file in VS Code, the code gets reformatted differently. One formatter changes double quotes to single quotes, another changes them back. Prettier and ESLint fight over the formatting, and the file oscillates between two styles with each save.

Understanding the Conflict

VS Code can have multiple formatters registered for the same language. When you save with editor.formatOnSave enabled, VS Code runs the configured default formatter. If both Prettier and ESLint are installed and both try to format on save, they conflict.

Check which formatters are registered:

json
// In settings.json
{
    "editor.formatOnSave": true,
    "[javascript]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "[typescript]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    }
}

Step 1: Choose One Default Formatter

Pick either Prettier or ESLint as your default formatter for each language:

json
{
    "[javascript]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "[typescript]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "[json]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "[html]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    },
    "[css]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    }
}

Remove any conflicting formatter settings:

json
// REMOVE these if present:
// "[javascript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" }

Step 2: Configure ESLint to Not Format

ESLint can both lint and format. To avoid conflicts with Prettier, configure ESLint to only lint (not format):

json
{
    "eslint.format.enable": false,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": "explicit"
    }
}

With this configuration: - Prettier handles formatting (via formatOnSave) - ESLint handles linting fixes (via codeActionsOnSave) - They do not conflict because they handle different concerns

Step 3: Use eslint-config-prettier

The eslint-config-prettier package disables all ESLint formatting rules that conflict with Prettier:

bash
npm install --save-dev eslint-config-prettier

Then in your ESLint configuration:

javascript
// .eslintrc.js
module.exports = {
    extends: [
        'eslint:recommended',
        'plugin:@typescript-eslint/recommended',
        'prettier',  // Must be LAST to override formatting rules
    ],
};

The prettier config must be the last entry in extends so it can override any conflicting rules from previous configs.

Step 4: Use eslint-plugin-prettier

For the tightest integration, run Prettier AS an ESLint rule:

bash
npm install --save-dev eslint-plugin-prettier
javascript
// .eslintrc.js
module.exports = {
    extends: [
        'eslint:recommended',
        'plugin:@typescript-eslint/recommended',
        'plugin:prettier/recommended',
    ],
};

Then in VS Code:

json
{
    "editor.formatOnSave": false,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": "explicit"
    }
}

With this setup, ESLint runs Prettier as a rule, so there is only ONE formatter (ESLint) and no conflicts.

Step 5: Prettier Configuration

Ensure Prettier is configured correctly for your project:

json
// .prettierrc
{
    "singleQuote": true,
    "semi": true,
    "trailingComma": "all",
    "printWidth": 100,
    "tabWidth": 2,
    "useTabs": false,
    "endOfLine": "lf"
}

And tell Prettier which files to process:

bash
// .prettierignore
node_modules/
dist/
build/
*.min.js

Step 6: Detecting the Active Formatter

To verify which formatter is running:

json
{
    "editor.formatOnSave": true
}

Save a file and check the Output panel:

bash
View > Output > Select "Prettier" or "ESLint" from dropdown

Only the active formatter should show output. If both show output, you have a conflict.

Common Conflict Scenarios

Scenario: Prettier changes quotes, ESLint changes them back

```json { // Prettier wants single quotes "prettier.singleQuote": true,

// ESLint wants double quotes (from 'quotes' rule) // Fix: eslint-config-prettier disables this } ```

Scenario: Different indentation

```json { // Prettier uses 2 spaces "prettier.tabWidth": 2,

// VS Code default uses 4 spaces "editor.tabSize": 4,

// Fix: align them "editor.tabSize": 2 } ```

Scenario: Format on Paste Also Conflicts

json
{
    "editor.formatOnPaste": false
}

Disable format on paste to avoid conflicts when pasting code snippets.