TypeScript Config File Parser
tsconfck is a robust utility designed to find and parse `tsconfig.json` or `jsconfig.json` files programmatically, abstracting away the complexities of TypeScript's native parsing mechanisms. It enables developers to work with TypeScript configuration files without requiring a direct dependency on the `typescript` package itself, offering a lightweight alternative. The current stable version is 3.1.6, with a release cadence that appears to be frequent patch releases addressing bug fixes and minor improvements, as seen in the recent changelog for 3.1.x. Key differentiators include its ability to resolve `extends` and `references` properties, optional caching for performance, a minimal bundle size (4.8KB gzip), and being completely asynchronous. It also offers `parseNative` for when the `typescript` peer dependency *is* present and desired for official API usage. It's notably used by popular tools like Vite and Astro for their configuration needs.
Common errors
-
ERR_REQUIRE_ESM
cause Attempting to `require()` tsconfck in a CommonJS module, but tsconfck is an ESM-only package.fixChange your import statement to `import { parse } from 'tsconfck';` and ensure your environment supports ES modules (e.g., `type: 'module'` in package.json or running with a modern Node.js version). -
TypeError: Cannot read properties of undefined (reading 'parseJsonConfigFileContent')
cause The `parseNative` function was called, but the `typescript` peer dependency is either not installed or not found.fixInstall `typescript` as a peer dependency: `npm install typescript@^5.0.0` or use the `parse` function instead, which does not require `typescript`. -
The tsconfig content did not seem to be a valid tsconfig (eg. comments outside of strings) or could not be parsed as json.
cause The `tsconfig.json` file contains invalid JSON syntax, such as trailing commas in strict JSON mode, or unquoted keys/values. While `tsconfig.json` tolerates comments, strict JSON parsing might fail.fixVerify your `tsconfig.json` for syntax errors. Use a JSON linter or validator to ensure it's valid JSON. If the error persists, it might indicate an issue with how `tsconfck` handles specific non-standard JSON constructs in older versions.
Warnings
- breaking tsconfck is an ESM-only package since its major version 3. This means it can only be imported using `import` statements and cannot be `require`d in CommonJS environments without specific workarounds like dynamic import or setting 'type': 'module' in your package.json.
- gotcha When using the `parseNative` function, a `typescript` peer dependency (version ^5.0.0) is required. If `typescript` is not installed or the version is incompatible, `parseNative` will not function as expected or may throw errors.
- gotcha The package provides caching capabilities via `TSCOnfckCache`, but cache invalidation is explicitly stated to be the user's responsibility. Failing to clear the cache when `tsconfig` files are added, removed, or changed will lead to stale configuration data being used.
- gotcha Prior to version 3.1.4, glob matching for `include`/`exclude` patterns might not have correctly handled paths without explicit extensions or wildcards (e.g., `src` incorrectly becoming `src/**/*`). This could lead to files not being included/excluded as expected.
- gotcha Early 3.x versions had issues resolving `${configDir}` in referenced tsconfig files and handling complex `extends` scenarios (e.g., `extends: '..'`). This could lead to incorrect configuration resolution in multi-package repositories or complex project setups.
Install
-
npm install tsconfck -
yarn add tsconfck -
pnpm add tsconfck
Imports
- parse
const { parse } = require('tsconfck');import { parse } from 'tsconfck'; - parseNative
const { parseNative } = require('tsconfck');import { parseNative } from 'tsconfck'; - find
const { find } = require('tsconfck');import { find } from 'tsconfck'; - TSCOnfckCache
import { TSCOnfckCache } from 'tsconfck';
Quickstart
import { parse } from 'tsconfck';
import * as path from 'path';
import * as fs from 'fs/promises';
// Create a dummy tsconfig.json for demonstration
const projectRoot = path.join(process.cwd(), 'temp_tsconfck_project');
const tsconfigFile = path.join(projectRoot, 'tsconfig.json');
async function setupProject() {
await fs.mkdir(projectRoot, { recursive: true });
await fs.writeFile(tsconfigFile, JSON.stringify({
"compilerOptions": {
"target": "es2020",
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": [
"src/**/*.ts"
]
}, null, 2));
await fs.mkdir(path.join(projectRoot, 'src'), { recursive: true });
await fs.writeFile(path.join(projectRoot, 'src', 'index.ts'), 'console.log("Hello");');
}
async function cleanupProject() {
await fs.rm(projectRoot, { recursive: true, force: true });
}
async function run() {
await setupProject();
try {
const { tsconfigFile, tsconfig, extended, solution, referenced } = await parse(path.join(projectRoot, 'src', 'index.ts'));
console.log('Found tsconfig file:', tsconfigFile);
console.log('Parsed tsconfig (merged):', tsconfig);
// console.log('Extended configs:', extended);
// console.log('Solution config:', solution);
// console.log('Referenced configs:', referenced);
} catch (error) {
console.error('Error parsing tsconfig:', error);
} finally {
await cleanupProject();
}
}
run();