eslint-plugin-dprint

GitHub npm version Downloads/month
node-current npm peer dependency version (scoped) npm bundle size
Build Status codecov Quality Gate Status Quality Gate Quality Gate

This is an updated fork of mysticatea/eslint-plugin-dprint. Some things are still being adjusted.

The plugin that runs dprint to format code in ESLint.

đź’ż Installation

Use npm or a compatible tool.

$ npm install -D eslint @ben_12/eslint-plugin-dprint

Then install dprint plugin for the language to format.

$ npm install -D @dprint/dockerfile
$ npm install -D @dprint/json
$ npm install -D @dprint/markdown
$ npm install -D @dprint/toml
$ npm install -D @dprint/typescript
$ npm install -D dprint-plugin-malva
$ npm install -D dprint-plugin-markup
$ npm install -D dprint-plugin-yaml
$ npm install -D dprint-plugin-graphql

npm peer dependency version (scoped) npm peer dependency version (scoped) npm peer dependency version (scoped) npm peer dependency version (scoped) npm peer dependency version (scoped) npm peer dependency version (scoped) npm peer dependency version (scoped) npm peer dependency version (scoped) npm peer dependency version (scoped)

đź“– Usage

Write your ESLint configuration. For example with typescript code:

import { defineConfig } from "eslint/config";
import tsPlugin from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
import dprint from "@ben_12/eslint-plugin-dprint";

module.exports = defineConfig([
  {
    files: ["**/*.ts", "**/*.js"],

    languageOptions: {
        parser: tsParser
    },

    plugins: {
        "@typescript-eslint": tsPlugin,
        "@ben_12/dprint": dprint,
    },

    rules: {
      ...tsPlugin.configs["eslint-recommended"].rules,
      ...tsPlugin.configs["recommended"].rules,
      ...tsPlugin.configs["strict"].rules,
      ...dprint.configs["typescript-recommended"].rules
      "@ben_12/dprint/typescript": [
        "error",
        {
          // Use dprint JSON configuration file (default: "dprint.json")
          // It may be created using `dprint init` command
          // See also https://dprint.dev/config/
          configFile: "dprint.json",
          config: {
            // The TypeScript configuration of dprint
            // See also https://dprint.dev/plugins/typescript/config/
          },
        },
      ],
    },
  },
]);

For legacy eslint (eslintrc configuration),

module.exports = {
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@ben_12/dprint/typescript-recommended",
  ],
  rules: {
    "@ben_12/dprint/typescript": [
      "error",
      {
        // Use dprint JSON configuration file (default: "dprint.json")
        // It may be created using `dprint init` command
        // See also https://dprint.dev/config/
        configFile: "dprint.json",
        config: {
          // The TypeScript configuration of dprint
          // See also https://dprint.dev/plugins/typescript/config/
        },
      },
    ],
  },
};

Then run ESLint with --fix!

Providing a pre-resolved formatter via settings

By default the plugin loads each dprint formatter at module-load time by doing a dynamic require() of the corresponding peer package (@dprint/typescript, dprint-plugin-yaml, …). That works for most setups, but it relies on the optional peer dependency being installed and discoverable by Node’s resolver. Some bundlers and bundled config packages (anything that does static module-graph analysis, e.g. Packtory) only follow real import statements, so the dprint plugins never end up in the bundle. In that case the plugin logs Plugin not found: … for every linted file and the rule silently becomes a no-op.

You can avoid this by passing a pre-resolved formatter through ESLint’s settings. Settings are not serialized or structuredCloned by ESLint, so they can carry runtime objects (modules, buffers, pre-built formatters). When a formatter is provided this way, the plugin uses it directly and skips the dynamic require() lookup (and the associated “Plugin not found” warning).

Accepted shapes for each formatter entry:

Example (flat config):

import { defineConfig } from "eslint/config";
import dprint from "@ben_12/eslint-plugin-dprint";
import typescriptFormatter from "@dprint/typescript";

export default defineConfig([
  {
    files: ["**/*.ts"],
    plugins: { "@ben_12/dprint": dprint },
    settings: {
      "@ben_12/dprint": {
        formatters: {
          typescript: typescriptFormatter,
        },
      },
    },
    rules: {
      "@ben_12/dprint/typescript": ["error", { config: { /* dprint config */ } }],
    },
  },
]);

The settings key is the plugin namespace (@ben_12/dprint). Inside formatters, the key is the rule name (typescript, json, markdown, toml, dockerfile, malva, markup, yaml, graphql).

g-plane plugins (yaml, malva, markup, graphql)

The @dprint/* packages can be imported and passed straight through, as in the example above. The g-plane packages (dprint-plugin-yaml, dprint-plugin-malva, dprint-plugin-markup, dprint-plugin-graphql) have no JS entrypoint and ship only plugin.wasm, so callers have to resolve and read the wasm file themselves and pass the result through createFromBuffer (or as a raw BufferSource). Example for dprint-plugin-graphql:

import { defineConfig } from "eslint/config";
import dprint from "@ben_12/eslint-plugin-dprint";
import { createFromBuffer } from "@dprint/formatter";
import fs from "node:fs";

const graphqlFormatter = createFromBuffer(
  fs.readFileSync(new URL(import.meta.resolve("dprint-plugin-graphql/plugin.wasm"))),
);

export default defineConfig([
  {
    files: ["**/*.graphql"],
    plugins: { "@ben_12/dprint": dprint },
    settings: {
      "@ben_12/dprint": {
        formatters: { graphql: graphqlFormatter },
      },
    },
    rules: {
      "@ben_12/dprint/graphql": ["error", { config: { /* dprint config */ } }],
    },
  },
]);

The same pattern (with the matching package and rule name) applies to yaml, malva, and markup.

For unparsed eslint file like markdown or dockerfile, you can use @ben_12/eslint-simple-parser as parser.

import { defineConfig } from "eslint/config";
import dprint from "@ben_12/eslint-plugin-dprint";
import simpleParser from "@ben_12/eslint-simple-parser";

export default defineConfig([
  {
    files: ["**/*.md"],
    plugins: {
        "@ben_12/dprint": dprint,
    },
    languageOptions: {
        parser: simpleParser,
    },
    rules: dprint.configs["markdown-recommended"].rules,
  },
]);

Available Rules

Rule Description
@ben_12/dprint/dockerfile Format dockerfile code with @dprint/dockerfile.
@ben_12/dprint/json Format json code with @dprint/json.
@ben_12/dprint/markdown Format markdown code with @dprint/markdown.
@ben_12/dprint/toml Format toml code with @dprint/toml.
@ben_12/dprint/typescript Format typescript code with @dprint/typescript.
@ben_12/dprint/malva Format css/scss/less/sass code with malva.
@ben_12/dprint/markup Format HTML/Vue/Svelte/… code with markup_fmt.
@ben_12/dprint/yaml Format YAML code with pretty_yaml.
@ben_12/dprint/graphql Format GraphQL code with pretty_graphql.

Available Configs

Config Description
plugin:@ben_12/dprint/disable-typescript-conflict-rules Disable rules where are conflicted with the @ben_12/dprint/typescript rule.
plugin:@ben_12/dprint/dockerfile-recommended Enable the @ben_12/dprint/dockerfile rule.
plugin:@ben_12/dprint/json-recommended Enable the @ben_12/dprint/json rule.
plugin:@ben_12/dprint/markdown-recommended Enable the @ben_12/dprint/markdown rule.
plugin:@ben_12/dprint/toml-recommended Enable the @ben_12/dprint/toml rule.
plugin:@ben_12/dprint/typescript-recommended Enable the @ben_12/dprint/typescript rule along with the plugin:@ben_12/dprint/disable-typescript-conflict-rules preset.
plugin:@ben_12/dprint/malva-recommended Enable the @ben_12/dprint/malva rule.
plugin:@ben_12/dprint/markup-recommended Enable the @ben_12/dprint/markup rule.
plugin:@ben_12/dprint/yaml-recommended Enable the @ben_12/dprint/yaml rule.
plugin:@ben_12/dprint/graphql-recommended Enable the @ben_12/dprint/graphql rule.

đź“° Changelog

See GitHub Releases.

❤️ Contributing

Welcome contributing!

Please use GitHub’s Issues/PRs.

Development Tools