How to set up Typescript and ESLINT for UXP development in VSCode

After reading this post, I’ve decided to install Typescript and ESLINT.

So I’ve installed node and ESLINT:

I ran npm install eslint in the workspace folder.

I then run node_modules\.bin>eslint --init but it’s asking me this:

How would you like to use ESLint? · problems
What type of modules does your project use?
> JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

I think CommonJS is the correct choice, but I’m not entirely sure. Can someone give me a definitive answer on what to select here? I’ve read through this:

And it says this:

Node.js, however, supports the CommonJS module format by default. CommonJS modules load using require(), and variables and functions export from a CommonJS module with module.exports.

Since I see require statements in UXP JS files, my best guess is CommonJS. But I’m new to JavaScript and could be completely wrong.

Any help on what to choose would be extremely appreciated!


1 Like

If you’re new to JavaScript then using TypeScript might be a case of trying to run before walking.
For me personally, TS didn’t make much sense until I understood the underlying JS.
That said, I know people who’ve just learnt TS, but generally they came with prior experience of other strongly typed languages.

As for ESLint, if you’re using VSCode it’s easier to just install the ESLint extension

I also use ESLint extension for VSCode in Alchemist plugin. It is easier that way. alchemist/.eslintrc.js at master · jardicc/alchemist · GitHub


This is a great question, but it’ll require a bit of explanation. I’ll try to keep it as short as possible.

First off, let me say that it’s definitely not wrong to use CommonJS. The full answer, especially if you want to use TypeScript, is a bit more complicated, though.


TypeScript code gets translated into JavaScript code. This process is called transpiling. The TypeScript compiler (tsc) can do this for you. It can also do a lot more, like type checking, but that’s not important for this discussion.

Here’s the catch: the tsc compiler can output JavaScript code in two different formats: CommonJS and ES modules no matter what style is used in the input file. The format is determined by the module compiler option (specified in a tsconfig.json).

This means that you can write TypeScript code that uses ES modules, but the output will still be CommonJS. This is what the module option does: it tells the compiler what format to use for the output.


Let’s say you have a TypeScript file called index.ts that looks like this:

import { storage } from 'uxp';

console.log(storage) // for demo purposes

Let’s say TypeScript is configured like this:

  "compilerOptions": {
    "module": "esnext"

When you run tsc index.ts, the compiler will output a file called index.js that looks like this:

import { storage } from 'uxp';
console.log(storage); // for demo purposes

Notice that the output is still using ES modules, even though the input is TypeScript. This is because the module option tells the compiler to use ES modules for the output.

This won’t work since UXP modules need to be imported using the CommonJS require function!

If you change the module option to commonjs, the output will look like this:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const uxp_1 = require("uxp");
console.log(; // for demo purposes

As you can see, even though our input file used the ES module syntax (import), the output is using the CommonJS syntax (require). This is because the module option tells the compiler to use CommonJS for the output.


Since ESLint is a linter, it doesn’t care about the output format. It only cares about the input format. Its job is to check your code for errors and style issues. It doesn’t care about the output format, because it doesn’t care about the output at all.


For ESLint, you should specify the input format. If you’re using JavaScript, you should use CommonJS (to be able to import UXP modules). If you’re using TypeScript, you can write your code as either CommonJS or ES modules. It doesn’t matter, because the output will be “conformed” by the transpiler. Just make sure that you configure the transpiler to output to CommonJS modules.

I hope this helps! If not all of it makes sense to you, don’t worry. It takes a bit of time to get used to all of this. But it’s worth it (at least in my opinion)!

Happy coding!