
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
The changes introduced by ESLint aren’t drastic, but one key update is the shift in file convention from .json to .js or .mjs. Specifically, you’ll notice a file like eslint.config.mjs in your generated Next.js app.
So, what’s .mjs? It stands for "Module JavaScript" and is used to explicitly indicate that the file is using ES Modules (ESM), a modern module system in JavaScript. This format ensures compatibility with ESM features like import and export.
With this new file format, ESLint has also updated how rules and configurations are defined. Instead of a static .json file, you now get the flexibility of JavaScript, enabling dynamic configurations, custom logic, or importing/exporting within your ESLint setup.
A good starting point would be to watch this video, which provides an overview of ESLint and Prettier, explains their importance, and highlights the tools you should pair them with to write clean, maintainable code. After that, you can move on to the NEW video to learn how to migrate from the older convention to the new one.
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.addMissingImports": "explicit"
},
"prettier.tabWidth": 2,
"prettier.useTabs": false,
"prettier.semi": true,
"prettier.singleQuote": false,
"prettier.jsxSingleQuote": false,
"prettier.trailingComma": "es5",
"prettier.arrowParens": "always",
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"typescript.tsdk": "node_modules/typescript/lib"
}
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
export default [
...compat.extends(
"next/core-web-vitals",
"next/typescript",
"standard",
"plugin:tailwindcss/recommended",
"prettier"
),
{
rules: {
"no-undef": "off",
},
},
];
If you’ve been using the .json convention and want to migrate to the new .eslint.config.mjs format, you can follow this video for a step-by-step guide.
That’s all. Just a single command and you’re all set.
Complete source code available till this point of lesson is available at
00:00:02 As of recently, eslint has changed its file convention.
00:00:05 Up to this point, the typical naming was .eslint.json, but now it has been modified to eslint.config.mjs.
00:00:15 So just to make sure that we are up to date even with our linting tools, let me show you how we can migrate it.
00:00:20 And this is something that happens often.
00:00:22 Whenever tools or libraries get updated, many of them provide you with a quick migration command that you can run, and it'll do everything for you.
00:00:30 So let me show you how we can do that together.
00:00:32 I'll copy this command, go back to my terminal, and paste it.
00:00:36 That is mpx at eslint forward slash migrate-config.eslintrc.json, which is the name of your current eslint configuration file.
00:00:47 Press enter, and it'll say migrating.eslintrc.json to a new place.eslint.config.mjs.
00:00:56 And you can see it right here.
00:00:58 It essentially moved all of our current configuration into this new format.
00:01:01 And now we can remove the previous .eslintrc.json.
00:01:06 And I forgot to mention, if you started watching this course a bit later down the line, after it was recorded, you might already have this proper file
00:01:14 naming right here as it became the new norm.
00:01:16 In any case, head into that file, and below this lesson, I'll provide a final config file just in case something went wrong with the migration.
00:01:24 So, you can copy it from below and override everything we have here.
00:01:28 After that, you'll need to install the following packages to use the new config.
00:01:33 add-eslint-compat, add-eslint-js, and add-eslint-eslint-rc.
00:01:38 So, let's simply copy this command that they provided to us nicely, paste it, npm install add-eslint, and then those three packages,
00:01:46 dash d, which stands for development, And let's install them.
00:01:50 There we go, it got installed successfully.
00:01:53 And you might wonder, what is this file extension name, .mgs?
00:01:57 I was also a bit weirded out by that.
00:01:59 Is it JavaScript or is it something else?
00:02:01 It feels like JavaScript, right?
00:02:03 Well, it's easy to find out.
00:02:05 A quick Google search led me to this Stack Overflow question, where the first answer says that it indicates it is an ES6 module file.
00:02:14 Node.js' original module system is CommonJS, which uses Requires, but in MJS, you can use Imports and Exports, which is becoming the new standard.
00:02:23 So, if you write CJS, that can be treated as Common JavaScript, and if you use MJS, that's going to be treated as the new ES6 Plus JavaScript.
00:02:32 Doesn't matter too much in day-to-day use, but it's useful to know when setting up these linters and libraries.
00:02:37 With that in mind, if you now go into any file and make a change, everything should still work as before.
00:02:43 So let's go ahead and push this.
00:02:44 I'll simply say migrate eslint to v9.
00:02:51 Commit and sync.
00:02:53 And with that, we are ready to move on to the next lesson.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:00 Let's set up linting so we can ensure to have a clean code base throughout the entire project.
00:00:06 As with source control, you want to set up linting early on and not later.
00:00:11 ESLint is one of the most popular linters out there.
00:00:15 The one that statically analyzes your code to quickly find problems.
00:00:19 It is also built into most of the text editors so you can run it as part of your continuous integration pipeline.
00:00:26 Basically, what it does is you hover over something and it quickly finds problems for you.
00:00:30 If you check out your file explorer, you'll see that there's already an eslint.config.mgs file right here, and it already extends some core configurations,
00:00:41 such as the Next.js Core Web Vitals and Next Tabscript.
00:00:45 Leave these two in, as they'll warn you about writing code that affects the core web vitals, as well as your general consistency and type safety.
00:00:53 But these are just the defaults, so I'll show you how you can add another ESLint configuration for consistent code styling,
00:01:01 as the default next configuration doesn't do much to help you improve the quality of your codebase.
00:01:06 So let's install the standard configuration.
00:01:09 So we'll add this JavaScript standard style that applies consistent indentation for all of your files, uses one type of quotes,
00:01:18 in this case, single quote, so that your entire code is consistent.
00:01:22 It warns you if you initialize some variables, but they're unused.
00:01:26 It adds a space after every keyword.
00:01:28 It adds space before function declarations.
00:01:31 It makes you always use strict equality instead of double equals to make sure that the code is super safe.
00:01:38 And it does so much more stuff that when combined, significantly improves the quality of your code base.
00:01:46 Understanding these rules not only makes your code base cleaner, but also makes you a better developer.
00:01:51 So to install it, open up your terminal.
00:01:54 I'll actually open up a new one so we can run additional commands right here.
00:01:58 And I'll type npm install.
00:02:01 eslint-config-standard.
00:02:05 Don't worry if you see a big fat error message right here.
00:02:09 This is actually expected.
00:02:10 That's because eslint has been upgraded to a newer version, but some packages that are required to run Next.js are still using old versions of eslint.
00:02:20 And Next.js is using the latest, so there's a mismatch.
00:02:23 So let's just do what it says.
00:02:25 You can retry the same command by adding the legacy peer depths command at the end.
00:02:29 So just type npm install eslinconfig standard and add dash dash legacy dash peer dash depths at the end of it.
00:02:37 And that's it.
00:02:37 It got installed within seconds.
00:02:39 So now that we have installed this additional ESLint standard, head over to eslinconfig.mjs and add it right here at the end where we extend different
00:02:49 types of configurations by just calling it standard.
00:02:52 Now that we've added ESLint to our configuration, let's actually run it by opening our terminal and running npm run lint.
00:03:01 When you do that, you'll see that we get another error saying that the plugin N is required for the standard configuration.
00:03:08 So what we have to do is install it.
00:03:11 So just say npm install eslint plugin.
00:03:17 and also add the ESLint plugin promise, which are needed for the standard configuration.
00:03:24 You can also add the dash dash legacy dash peer dash depths and press enter.
00:03:31 Once these two additional packages get installed, you can rerun the npm run lint command.
00:03:37 And now you'll see a bunch of errors.
00:03:39 Just what we needed, right?
00:03:40 But yeah, technically it is, right?
00:03:42 That's exactly what we're using the linter for.
00:03:45 For example, the standard code style wants us to use single quotes rather than double quotes for strings.
00:03:51 Now, you might be asking why, and you might be questioning every single one of these rules.
00:03:55 I'll give you a short answer and a quick tip.
00:03:59 And that is, don't.
00:04:00 Don't question it.
00:04:02 I used it to the same thing when I was starting to learn to code, but then I learned that these rules are there for a reason.
00:04:09 And it could take you about a year or two years to fully see that reason, but once you see it, you'll see, oh, now I understand why it's there.
00:04:17 So sure, you can question it from the start and find out the reason why it's there, or just trust it and immediately improve your code base.
00:04:24 Now, we'll focus on fixing these errors later on.
00:04:27 As a matter of fact, I'll show you how your IDE or text editor can fix them automatically on its own, so you don't have to go ahead and change every single line.
00:04:36 But before we do that, let's further improve our ESLing configuration to truly make our code bases production-ready.
00:04:44 We'll add a Tailwind CSS ESLing configuration.
00:04:48 It'll allow us to have our class names organized logically in Tailwind CSS, making our code easier to read and review.
00:04:56 So let's actually install it by running mpm install eslint plugin Tailwind CSS.
00:05:06 And just to be safe, I'll add that legacy peer depths at the end and press enter.
00:05:12 It'll quickly get installed, so I can simply add it at the end of this extents part.
00:05:17 Now that we have multiple configurations, I'll actually spread it in multiple lines.
00:05:23 And at the end, I'll add a plugin, Tailwind, CSS, Recommended.
00:05:29 Now, alongside our linter called ESLint, there's also Prettier.
00:05:34 And devs often confuse those two.
00:05:36 See, ESLint is a linter, but Prettier is an opinionated code formatter.
00:05:42 And it actually works in tandem with ESLint.
00:05:45 Each one serves its purpose.
00:05:47 Prettier will auto format your code and save.
00:05:50 No need to discuss style and code reviews, and it saves you time and energy.
00:05:54 So, let's set it up.
00:05:56 And not only do we have to set it up, but we have to make it work seamlessly with ESLint, because the two often run into conflicts.
00:06:04 So, let's first install the ESLint config prettier, "-legacy-peer-deps".
00:06:11 Head back over into your config and add it at the end.
00:06:15 just Prettier.
00:06:17 This package will remove all ESLint rules that could conflict with Prettier ones.
00:06:22 Now we have to install Prettier by running npm install prettier, legacy peer depths.
00:06:28 And now that everything is set up command line wise, it's time to integrate ESLint and Prettier with your text editor.
00:06:35 In this case, I'll be using VS Code.
00:06:38 In this case, I'll be using VS Code, so I'll show you how to set up the configuration for it.
00:06:42 But if you're using an IDE like WebStorm, that's also totally okay, but you might need to set it up in a bit of a different way.
00:06:49 So you can search for a tutorial that shows you how to do ESLint and Prettier within Next.js applications within WebStorm.
00:06:56 For VS Code, you can press Command-Shift-B or Control-Shift-B on Windows and search for Open Settings JSON.
00:07:05 You can go for Workspace Settings, for example.
00:07:07 Here you have an empty object which will automatically be added to your file explorer if you decide to unhide it like I did.
00:07:15 But you can always get to it by simply saying open workspace settings and you'll open it right here.
00:07:21 Another way to create it is just to manually create a new folder called .vscode but you can see in this case it already exists in this location.
00:07:30 And then below this lesson I'll give you the configuration that you can copy and paste right here.
00:07:35 This is a configuration that I have built over the years working on large Next.js projects, and I grew to love it.
00:07:43 It has some default information for ESLint and Prettier to work well together.
00:07:48 It auto-formats on save.
00:07:49 This is very important.
00:07:51 And it fixes everything that it can on save.
00:07:54 We have a specific tab width, semicolons, single quotes, and so on.
00:07:59 Just some rules that make it all work well.
00:08:02 So copy and paste it right here.
00:08:04 This will set up ESLint and Prettier to work well within VS Code.
00:08:09 Now, every time you hit save, both Prettier and ESLint will run.
00:08:13 But to test it in action, there's one final thing we have to do.
00:08:17 And that is to install ESLint and Prettier from the Extensions Marketplace.
00:08:23 Search for ESLint and install it.
00:08:27 Also install the Prettier ESLint as well as Prettier itself.
00:08:34 This one right here.
00:08:36 So you need those three packages.
00:08:38 Once they are installed, you'll have to restart your Visual Studio Code.
00:08:42 You can do that using the command line by pressing Command-Shift-P and then saying, reload window, or just close and then open it again.
00:08:50 You should see that both of them are now working.
00:08:52 Now, to test it all in action, let's go to a file that previously had many errors.
00:08:56 For example, the layout.dsx.
00:08:58 You'll notice that now every single line ending has a semicolon.
00:09:03 Every single string is wrapped in double-quoted strings.
00:09:06 You have no additional spacings or enters.
00:09:09 You don't have any extra spacing that you don't need.
00:09:12 Everything is nicely structured.
00:09:14 And if you try to mess with some parts of the config, like removing the last comma, you'll see that it'll get added automatically.
00:09:21 Same thing for the semicolons and more.
00:09:23 We can also check out the page.
00:09:26 And see, if you save the file, it'll automatically restructure it, because Prettier doesn't like to have super long lines,
00:09:33 so actually it spaces it out in multiple lines.
00:09:36 If you head back over to Layout, you'll see that we have different types of imports.
00:09:40 And later on within our applications, we'll have dozens of imports on every single file.
00:09:45 So if you have the local import at first, then you have another one, they can be messed up, they can be separated.
00:09:52 This also decreases the legibility of the code base.
00:09:55 You always want to have your imports nicely structured.
00:09:59 So to do that, there's another package that helps us with imports.
00:10:02 So head over to your terminal and run mpmi eslint plugin import dash dash save dash dev and dash dash legacy dash beer dash depths.
00:10:15 This will save it as a dev dependency and then head back over to your ESLint config.mjs and then at the bottom, we'll have to provide additional rules
00:10:24 on how to set up our import order.
00:10:26 This one is a bit longer, so instead of typing it out by hand, simply go ahead and copy the .mjs file from below this lesson.
00:10:34 And then override everything you have right here with that new configuration.
00:10:38 You'll see that we're still keeping the same things right here that we had before, but also we're adding some rules for the import order.
00:10:46 Now, if you head back to one of the files and run npm run lint and press enter, you'll see that Tailwind CSS doesn't quite work with ESLint.
00:10:56 at least it doesn't automatically reorder the class names.
00:11:00 This is because the ESLint Tailwind CSS plugin doesn't support the latest version of Tailwind CSS yet, the one that we'll be using.
00:11:08 So for the time being, you can just comment this config out, and then later on, as they implement it, you'll be able to uncomment it,
00:11:16 and it'll work.
00:11:17 but for now let me just rerun npm run lint and you can see that now since we have prettier installed the number of errors automatically decreased and we
00:11:27 only get the ones that we have to manually change such as it's saying that we should use camel case instead of underscores and it's also saying that the
00:11:35 next import should occur before the import of next google and this is the import order plugin doing its thing So if you try to mess with the imports a bit,
00:11:43 such as separating them or doing some weird stuff, it'll say, please don't do that, keep them as they should be.
00:11:49 So if we do it like this, we're good.
00:11:51 And now when it comes to this font name, that's its actual name.
00:11:55 So there's not much we can do about it, besides maybe renaming it to use camel case.
00:12:00 In that case, we should be good right here as well.
00:12:04 Perfect.
00:12:05 And now our application is error free.
00:12:07 And in the future, ESLint and Prettier will work well together to fix out all of the empty spaces, all the inconsistencies,
00:12:14 maybe some weird indentation.
00:12:17 Whatever you do, it'll auto fix it in one click.
00:12:20 So let me go ahead and commit this by saying implement ESLint and Prettier.
00:12:25 And keep in mind that if anything changes with these configurations, I'll always keep this lesson updated.
00:12:31 So below this lesson, there might be some new configurations that work out with the latest versions of all of these tools that we're using.
00:12:37 Perfect.
00:12:38 Great job.
00:12:39 And I just want to let you know that if something didn't work for you, don't worry about it.
00:12:43 Setting up linters and formatters can be a real pain in the ass.
00:12:47 So we can always tweak it a bit on the go.