You might not need `lib` in `tsconfig.json`
TypeScript has one of the most complex configuration schemas in the JavaScript ecosystem, beaten only by bundlers like Webpack. At the time of writing, there are 105 separate options in the TypeScript config schema!
Given this size and complexity, it is not surprising that people make mistakes in their tsconfig.json
. It helps that the file allows comments in the JSON – when building your own tsconfig.json
, I highly recommend documenting your choices with comments. Also, when copying a boilerplate tsconfig.json
, I recommend taking a few minutes to find the docs for each preconfigured option and make sure you understand what it’s doing and whether you actually need or want it. Understanding what your code is actually doing is the first step in building maintainable software.
lib
and target
One of the most common mistakes I see is with the target
and lib
options. It is extremely common to find lib
declared in tsconfig.json
, but it is very rarely needed, especially for browser-based projects. As the docs themselves explain:
Changing
target
also changes the default value oflib
. You may “mix and match”target
andlib
settings as desired, but you could just settarget
for convenience.
The problem
If you’ve ever seen a tsconfig.json
with something like the following in it, then you’ll know why it causes confusion and uncertainty:
{ "target": "es5", "lib": ["dom", "es2016", "es2017.object"] }
This is from a real tsconfig.json
I found in use in a large company. Why is it targetting es5
, but then including the es2016
library? What is es2017.object
? Does anyone really know?
The transpiling step for this project used Babel, and @babel/preset-env
, so there was absolutely no reason to limit the TS target to es5
. In fact, it should have targetted es2020
, because that matched the version of Node being used and the latest version of Babel can handle everything in es2020
.
The solution
So how do you choose what options to set? A good set of principles to follow are:
You probably don’t need
lib
at all. If you’re writing a pure Node project, you may want to remove thedom
library by setting lib to match yourtarget
, e.g.:"lib": ["es2020"]
, but otherwise, just leave it out until you find you actually need to control this.Choosing your
target
is actually quite simple, although it requires answering a question that we might not already know the answer to: What ES version are you using in your development environment? In most cases, this will match the Node version you are using, and you can find the ES version that matches your Node version by checking this table: node.green. Find your Node version along the top, then scroll down until red boxes start appearing in that column. The last section that has all green boxes, is your ES version.
Every line of code is tech debt, so by removing config you don’t actually need (and might even be doing you harm), you’re reducing tech debt and making you project easier to maintain.