Skip to main content

Using ESLint to automatically sort JS/TS imports

“import/order”: [
  “error”,
  {
    “alphabetize”: { “order”: “asc”, “caseInsensitive”: true },
    // See: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md#groups-array
    “groups”: [[“builtin”, “external”], “internal”, “parent”, “sibling”, “index”, “object”],
    “newlines-between”: “always”,
    “warnOnUnassignedImports”: true
  }
],

Ah, imports. Gotta have ‘em. But managing them isn’t fun.

Should they be arranged in a consistent order? Yeah, that’s kind of nice because it means you can scan the top of any file and quickly find what you’re looking for.

But do you want to have to remember what that order should be? Do you want to manually rearrange rows of imports every day? Do you want to ask your teammates to do that too?

No. No, I don’t think you do.

It’s nice for your project’s imports to always be in a consistent order so you can quickly scan them and find what you’re looking for. But remembering that order should be and manually maintaining it is a chore that takes time. And worse, asking your teammates to follow those rules can feel like nitpicking.

Automation to the rescue! Letting your editor manage your import sorting for you will give you and your team all the benefits of consistently sorted imports with none of the drawbacks.

A lovely library called https://github.com/import-js/eslint-plugin-import will automate this problem away once and for all so we can forget all about import sorting and focus on writing code.

Install library

To begin, we need to install the import plugin:

npm i -D eslint-plugin-import

Add import to your ESLint plugins list

# .eslintrc.js
 
plugins: ['import']

Add the import/order to your ESLint rules

See all the options for the order rule here.

Here’s my favourite way to order imports:

// .eslintrc.js
 
rules: {
	'import/order': [
	  process.env.NODE_ENV === 'production' ? 'error' : 'warn',
	  {
	    alphabetize: { order: 'asc', caseInsensitive: true },
	    groups: [['builtin', 'external'], 'internal', 'parent', 'sibling', 'index', 'object'],
	    'newlines-between': 'always',
	    warnOnUnassignedImports: true
	  }
	]
}

TODO: show an example of how it would rearrange some imports

Add other import/* rules you may like

You can find the full list of import/* rules and their explanations here.

Here are some that I find helpful:

// .eslintrc.js
 
// Automatically sorts imports on --fix (or save if "editor.codeActionsOnSave": { "source.fixAll.eslint": true })
rules: {
	'import/newline-after-import': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
	'import/no-anonymous-default-export': 0,
	'import/no-duplicates': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
	'import/no-nodejs-modules': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
	'import/no-self-import': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
	'import/no-unresolved': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
	'import/no-useless-path-segments': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
}

Add path mapping setting

If you use the import/no-unresolved rule and have absolute imports set up in your project with a base URL other than your project root (e.g. allowing you to import directly from components/ from anywhere instead of using a relative path like ../../components), the import plugin won’t understand how to resolve those absolute imports unless you help it out.

Here’s how you do that (assuming your base URL is ./src):

// .eslintrc.js
 
settings: {
  // This helps the "import/no-unresolved" rule resolve absolute import paths like "components/A" and "utils/B"
  'import/resolver': {
     node: {
       // See: https://stackoverflow.com/a/58323590/8802485
       moduleDirectory: ['node_modules', 'src']
     }
   }
}

Enable automatic linter error fixing in your editor

This is the fun part!

By default, the rules above will just show up as errors in your editor. The errors won’t automatically fix themselves unless actually get fixed unless you manually read and fix each error one by one (please don’t do that!) or run npx eslint . --fix.

But don’t! That’s a huge waste of time. Your editors can reorder your imports for you.

In VS Code:

// settings.json
 
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
},

Further reading

Inbox