# @total-typescript/tsconfig: twelve tsconfig files instead of one argument

> The @total-typescript/tsconfig package removes the guesswork from tsconfig.json by shipping a small matrix of ready-made configurations, split on two questions: whether tsc emits your JavaScript or an external bundler does, and whether the code runs in the DOM. It is a preset library with an opinionated author rather than a neutral defaults collection, and the README says so directly.

**total-typescript/tsconfig** — The simplest way to set up your tsconfig.json

- Repository: https://github.com/total-typescript/tsconfig
- Website: https://www.totaltypescript.com/tsconfig-cheat-sheet
- Stars: 1,179 · Forks: 29
- Language: Unknown
- License: not declared
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/total-typescript-tsconfig

## Two questions decide twelve files

The README frames the problem well: tsconfig.json can seem extremely scary, but really, it's only 2 or 3 decisions you need to make.

The package's job is to make those decisions for you, based on Matt Pocock's TSConfig Cheat Sheet.

The mechanism is a decision tree, and the first question is the one that actually changes the compiler's behaviour. Are you using tsc to turn your .ts files into .js files?

If yes, tsc is your bundler, or at least your transpiler, and the output directory and module settings matter. If no, you are probably using an external bundler, and the README names Vite, Remix, Astro and Nuxt as the kind of frameworks that fall into this category.

The second question is whether the code runs in the DOM. If it does, the lib settings are DOM libraries and the types have to include the browser globals. If it does not, for instance in Node.js, they are not.

The third dimension is what you are building: an app, a library, or a library in a monorepo. A library needs different output settings from an app, because a library's .d.ts files are consumed by other projects.

So two questions and three kinds of project give the twelve configurations, and the naming scheme in the package exports map mirrors the tree exactly: tsc or bundler, then dom or no-dom, then app, library or library-monorepo.

## The extends line, and the comment that tells you which to pick

The setup is three steps. Install the package, choose the tsconfig you need, and add it to your tsconfig.json with extends.

```jsonc
{
  // I'm building an app that runs in the DOM with an external bundler
  "extends": "@total-typescript/tsconfig/bundler/dom/app"
}
```

The comment above the extends line is not decoration. Each of the twelve snippets in the README carries a comment saying what it is for, so the choice is made by reading the line rather than by inferring it from a path.

```jsonc
{
  // My code runs in the DOM:
  "extends": "@total-typescript/tsconfig/tsc/dom/app", // For an app
  "extends": "@total-typescript/tsconfig/tsc/dom/library", // For a library
  "extends": "@total-typescript/tsconfig/tsc/dom/library-monorepo", // For a library in a monorepo

  // My code _doesn't_ run in the DOM (for instance, in Node.js):
  "extends": "@total-typescript/tsconfig/tsc/no-dom/app", // For an app
  "extends": "@total-typescript/tsconfig/tsc/no-dom/library", // For a library
  "extends": "@total-typescript/tsconfig/tsc/no-dom/library-monorepo" // For a library in a monorepo
}
```

The exports map in package.json is what makes those paths resolve, and it is worth reading because it shows something about the design. Several paths are aliases of the same file. ./tsc points at tsc/dom/app.json, as do ./tsc/dom and ./tsc/dom/app, and the same pattern repeats for the no-dom variants and for the bundler family, where ./bundler/dom and ./bundler/dom/app both resolve to bundler/dom.json.

So the aliasing is not a duplicate set of files, it is the same configuration reachable under several names, so that a project can pick the name that reads best in its own tsconfig.json. The two family roots, ./tsc and ./bundler, exist so that a project can switch families without rewriting the rest of the path, and the bare family root resolves to the app variant, which is the most common case.

## What the presets deliberately leave to you

The README has a section titled Options Not Covered, and it is short.

The jsx option is the first, because it depends on the JSX runtime in use. If your app has JSX you set it yourself.

```json
{
  "extends": "@total-typescript/tsconfig/bundler/dom/app",
  "compilerOptions": {
    "jsx": "react-jsx"
  }
}
```

The outDir option is next, described as mostly relevant for when you are transpiling with tsc, and the example extends the no-dom library config with an outDir of dist.

The third entry is a statement of scope rather than an option: framework-specific options like vite, next and remix are not covered yet, and with enough persuasion the author might add them in the future.

That last point is the honest boundary of the package, and it is the one worth remembering. A tsconfig preset is a starting point, and the parts of the configuration that vary with your framework are exactly the parts a general preset cannot get right for you.

The structure of the override is the standard TypeScript one. The preset supplies compilerOptions, and your own file adds to it through the compilerOptions key, which merges over the inherited settings rather than replacing them. The extends mechanism is what makes this work, and the reason the package can ship twelve files rather than one is that it never has to describe your whole project.

## Why not the tsconfig bases package

The README has a section explaining what this package is not, and it is the most opinionated content in the document.

The @tsconfig/bases package is described as a great resource for TypeScript configurations. However, the author disagrees with the idea that there is a single recommended configuration that works for everyone.

That is the argument for the whole design, and it is a disagreement with the premise of the other package rather than with its quality. @tsconfig/bases is a set of baselines, and the premise of a baseline is that the compiler options have a broadly correct value. The author of this package holds that they do not, because the meaningful differences are the two in the decision tree, and a single recommended config necessarily has to pick a side on both.

There is a second reason given, and it is the more honest one. The author wanted a set of tsconfig.json files that he controlled so he could use them to keep his Total TypeScript course repos up to date.

That second reason is worth stating plainly because it tells you what kind of artefact this is. It is a teaching artefact that happens to be useful in production, maintained by the person who teaches TypeScript. That is not a criticism, and the course link at the end of the section is a fair piece of context, but it does explain the design decisions. The configs are opinionated because the author wanted them to be, and the question of whether an opinion matches your project is the question you have to answer.

## The package shape, and what the repository actually contains

The repository is small in the way a preset repository should be. There are two directories at the root, bundler/ and tsc/, plus a package.json, a pnpm-lock.yaml, a.changeset/ directory, an.npmignore and a.gitignore.

The two directories map to the two families in the decision tree. The tsc family has a separate file for app, library and library-monorepo under dom and no-dom, while every bundler path resolves to bundler/dom.json or bundler/no-dom.json.

The.changeset/ directory is the release mechanism. Changesets is the tool that keeps a monorepo's packages versioned together and generates the changelog and the version bump from a markdown file describing the change. The devDependency is @changesets/cli at 2.27.1.

The package itself has no runtime dependencies, which is the norm for a configuration package. The version is 1.0.4, the author is Matt Pocock, and the licence is MIT. The homepage is set to the TSConfig cheat sheet page, which is a nice touch, since the package's real documentation is that cheat sheet rather than the readme.

The pnpm-lock.yaml is worth noticing, because a package that ships only JSON files does not need a lockfile for its own build. The lockfile is there for the repository's own development, and pnpm is also a reasonable default for a project that will be consumed by pnpm users.

The last push was on 2026-05-21, and the repository has no GitHub releases, so the version history lives in the npm registry and in the changesets.

## Where this fits against the alternatives

There are three practical alternatives, and they differ in kind rather than in detail.

The first is writing tsconfig.json by hand, using the compiler options reference. That gives complete control and costs time, and for a project with unusual requirements it is the right answer.

The second is @tsconfig/bases, which offers a set of baseline configurations maintained under the tsconfig organisation. The difference from this package is the philosophy: baselines assume there is a broadly correct set of options, and the author of this package says he disagrees with that premise.

The third is a framework's own configuration. The README names vite, next and remix as framework-specific options it does not cover yet, and that is exactly the category this package declines to cover.

So the honest summary is that @total-typescript/tsconfig sits in the space between the hand-rolled file and the framework default, and it wins on a narrow, well-defined question: which of the four combinations of tsc versus bundler and DOM versus no-DOM applies to you, and should the output be an app, a library or a monorepo library.

If that question has an easy answer for your project, this package removes a decision that has no single right answer in the general case. If it does not, the package is not for you, and the cheat sheet it points to will teach you the options faster than any preset can.

## Conclusion

The @total-typescript/tsconfig package suits a TypeScript developer who wants a defensible starting configuration without reading the compiler options reference, because the two questions it asks are the two that actually change the settings, and the twelve presets are combinations of those answers. It is the wrong tool if you want a neutral reference set, because the README states the author disagrees with the idea of a single recommended configuration and says these files exist because he controlled them. Before you adopt it, read the config it extends rather than the name, because the library and the monorepo variants differ in ways the name does not spell out, and check the version, since the published package is at 1.0.4 and the last push was on 2026-05-21.

## FAQ

### How do I install and use @total-typescript/tsconfig?

Run npm install --save-dev @total-typescript/tsconfig, pick the configuration you need from the list in the README, and add it to your tsconfig.json with an extends entry such as "extends": "@total-typescript/tsconfig/bundler/dom/app".

### What is the difference between the tsc and bundler configs in @total-typescript/tsconfig?

The question is whether you use tsc to turn your .ts files into .js files. If you do, use the tsc family; if not, and you are using an external bundler such as Vite, Remix, Astro or Nuxt, use the bundler family.

### What is the difference between the app, library and library-monorepo configs?

They cover what you are building rather than how it runs. The app configs are for applications, the library configs for libraries, and the library-monorepo configs for libraries that live in a monorepo, where the output settings differ.

### Does @total-typescript/tsconfig set the jsx option for me?

No. The README lists jsx among the options not covered, so you set it yourself in compilerOptions, for example "jsx": "react-jsx" alongside an extends entry pointing at the bundler/dom/app config.

### How does @total-typescript/tsconfig differ from @tsconfig/bases?

The README calls @tsconfig/bases a great resource but says the author disagrees with the idea that there is a single recommended configuration that works for everyone, and that he wanted a set of tsconfig files he controlled so he could keep his course repositories up to date.

## Sources

- [Issues](https://github.com/total-typescript/tsconfig/issues)
- [Project website](https://www.totaltypescript.com/tsconfig-cheat-sheet)
- [README](https://github.com/total-typescript/tsconfig/blob/main/README.md)
- [total-typescript/tsconfig on GitHub](https://github.com/total-typescript/tsconfig)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/total-typescript-tsconfig
