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.
$schema
is a field you can add to any.json
file 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 thetsconfig
is contained in. This is crucial to sharing the configuration between projects. For example,outDir
will always be relative to the user’stsconfig
instead of relative to the location of your package innode_modules
after 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!