Package Your TSConfig
- npm
- package
- tsconfig
- typescript
Directory structure
Your project will need to contain at minimum a package.json and another .json file containing your shared TSConfig. I have one TSConfig that I use in library development with tsc and another in app development when using a bundler. I have also included a README.md and a LICENSE.md.
.
├── bundler.json
├── LICENSE.md
├── package.json
├── README.md
└── tsc.json
Preparing to share your TSConfig
Here are a couple of helpful fields that make it easier to share your TSConfig between projects.
$schemais a field you can add to any.jsonfile to provide types for the file in editors like VSCode, regardless of the filename. When you are building a package, you might have multiple configuration files with different names thantsconfig. This field ensures you get auto-complete when creating the configuration files.${configDir}is a new configuration as of TypeScript 5.5 you can use to reference the directory that thetsconfigis contained in. This is crucial to sharing the configuration between projects. For example,outDirwill always be relative to the user’stsconfiginstead of relative to the location of your package innode_modulesafter being installed.
For more information on each of these options check out Matt Pocock’s TSConfig Cheat Sheet. See this repository for the latest version of my TSConfig files.
// tsc.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"outDir": "${configDir}/dist"
// ...
},
"include": ["${configDir}/src", "${configDir}/**/*.test.*"],
"exclude": [
"${configDir}/**/*.test.*",
"${configDir}/node_modules",
"${configDir}/dist"
]
}
Package configuration
A TSConfig package can be published with minimal configuration. Specify the following fields in your package.json.
Replace @robino/tsconfig with the name of your package you will publish to npm. Replace the MIT license if you wish to use a different license.
I’ve specified that this TSConfig needs to use TypeScript 5.5 or later because I’m using the configDir feature.
Any dependencies specified will be installed alongside your package when it is installed. I find it helpful to install the types for Node.js since I use Node APIs in most of my projects. This will make it so you have types when importing modules like "node:fs" by just installing your package, and you will manage the version in a central location.
// package.json
{
"name": "@robino/tsconfig",
"description": "Shared TypeScript configurations.",
"license": "MIT",
"version": "0.0.1",
"files": ["tsc.json", "bundler.json", "README.md", "LICENSE.md"],
"peerDependencies": { "typescript": ">=5.5.0" },
"dependencies": { "@types/node": "^22.0.0" }
}
There is no need to specify the main, or exports fields, TypeScript will find the files referenced by the entire path.
When you are ready, publish your package to npm using the npm publish command or your preferred method.
Extending and overriding
Once you have published your package, you can use your configurations in another project by installing them as a development dependency. For example, to install my package:
npm i -D @robino/tsconfig
Any TSConfig can extend another configuration by using the extends option. Any fields provided in addition to the extends options will override the extended configuration.
// tsconfig.json
{
"extends": "@robino/tsconfig/tsc.json",
"compilerOptions": {
// overrides the "target" of @robino/tsconfig/tsc.json
"target": "ES2020"
}
}
Thanks for reading!