How to Use Brace Expansion Patterns in the TSSLint CLI to Lint Multiple Projects at Once

Use brace expansion patterns like {tsconfig.json,packages/*/tsconfig.json} with the --project flag to lint multiple TypeScript projects in a single TSSLint command.

TSSLint, the TypeScript linter from the johnsoncodehk/tsslint repository, supports linting across multiple projects simultaneously by leveraging standard shell brace expansion. This allows you to target several tsconfig files without invoking the CLI multiple times, streamlining CI pipelines and monorepo workflows.

How Brace Expansion Works in TSSLint

TSSLint does not implement custom brace expansion logic. Instead, it relies on your shell to expand patterns like {a,b,c} into separate arguments before the Node.js process receives them. In packages/cli/index.ts, the CLI scans process.argv for project flags (lines 70-96) and treats every subsequent token as a glob pattern to resolve via fs.globSync (lines 101-110).

When you execute:

npx tsslint --project {tsconfig.json,packages/*/tsconfig.json}

Your shell expands the braces into two arguments—tsconfig.json and packages/*/tsconfig.json—before TSSLint processes them. The CLI then resolves each glob to matching configuration files and queues them for the linting worker defined in packages/cli/lib/worker.ts.

Linting Multiple Projects with Brace Expansion

Basic Syntax for Root and Package Projects

The most common use case in monorepos involves linting the root project alongside all packages. The README (lines 152-154) documents the recommended pattern:

npx tsslint --project {tsconfig.json,packages/*/tsconfig.json}

This single command lints both the root tsconfig.json and every tsconfig.json found in immediate subdirectories of packages/.

Combining Framework-Specific Flags

TSSLint supports framework-specific project flags such as --vue-project, --mdx-project, and --astro-project. Each accepts brace expansion independently:

npx tsslint --vue-project {apps/*/tsconfig.json,libs/*/tsconfig.json}

This targets Vue projects in both apps/ and libs/ directories without affecting standard TypeScript projects.

Linting Heterogeneous Projects

You can combine multiple project flags in one invocation to lint disparate project types simultaneously:

npx tsslint \
  --project {tsconfig.json,extensions/*/tsconfig.json} \
  --vue-project apps/vue/**/tsconfig.json \
  --mdx-project docs/mdx/**/tsconfig.json

The CLI resolves each flag’s arguments separately, aggregating all discovered configurations into a single linting run.

Implementation Details

The argument resolution logic resides in packages/cli/index.ts. After identifying project flags (lines 70-96), the code iterates over remaining arguments and passes them directly to fs.globSync (lines 101-110). This design means:

  • No internal brace parsing: TSSLint receives already-expanded paths from the shell.
  • Standard glob support: Patterns like **/tsconfig.json or packages/*/tsconfig.json work natively.
  • Cross-platform compatibility: While brace expansion is a POSIX shell feature, Windows users can achieve similar results using Git Bash, WSL, or by passing multiple explicit arguments.

Summary

  • Brace expansion allows you to specify multiple tsconfig paths in a single --project argument by leveraging shell syntax like {a,b,c}.
  • TSSLint receives expanded arguments and resolves each via fs.globSync in packages/cli/index.ts (lines 101-110).
  • You can combine brace expansion with framework-specific flags (--vue-project, --mdx-project, etc.) to lint heterogeneous monorepos in one command.
  • The README officially documents the pattern {tsconfig.json,packages/*/tsconfig.json} as the standard approach for multi-project linting.

Frequently Asked Questions

Does TSSLint support brace expansion on Windows?

TSSLint itself processes whatever arguments the shell provides. Windows Command Prompt does not perform brace expansion, but you can use Git Bash, WSL, or PowerShell with explicit arrays to achieve the same result. Alternatively, pass multiple --project arguments explicitly: npx tsslint --project tsconfig.json --project packages/*/tsconfig.json.

Can I use brace expansion with npm scripts?

Yes, but you must quote the pattern to prevent premature expansion. In your package.json, wrap the brace expression in double quotes so the shell expands it at execution time rather than when parsing the script:

{
  "scripts": {
    "lint:all": "tsslint --project \"{tsconfig.json,packages/*/tsconfig.json}\""
  }
}

What other project flags support brace expansion?

All framework-specific project flags support the same glob and brace expansion logic as --project. This includes --vue-project, --mdx-project, --astro-project, --svelte-project, and any future framework integrations added to TSSLint. Each flag is processed independently in packages/cli/index.ts.

How does TSSLint handle glob patterns versus brace expansion?

TSSLint treats every argument after a project flag as a glob pattern to be resolved by fs.globSync. Brace expansion happens before TSSLint sees the arguments, performed by your shell. Therefore, {a,b}/*.json first becomes a/*.json b/*.json, and then each glob is resolved separately. This two-phase process allows complex combinations like {packages,apps}/*/tsconfig.json to work seamlessly.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →