A collection of shell functions that make TypeScript type-checking faster, observable, and easier to debug.
Stop waiting on npx tsc --noEmit. Start forging.
- ⚡ tsforge
Every TypeScript developer runs the same command hundreds of times a day:
npx tsc --noEmitAnd every time, it feels slower than it should. The reasons are well-documented but rarely addressed in one place:
| Problem | Impact | tsforge Solution |
|---|---|---|
npx overhead |
Adds 50–100ms per invocation just resolving the binary | Uses local node_modules/.bin/tsc directly via walk-up discovery |
| No incremental caching | tsc restarts from zero on every run |
tsc-optimize detects missing incremental: true |
node_modules type-checking |
tsc processes thousands of .d.ts files unnecessarily |
tsc-optimize detects missing skipLibCheck: true |
| No visibility into bottlenecks | "It's slow" — but where? Parse? Bind? Check? | tsc-diagx shows per-phase and per-file timings |
| Wrong tsconfig active | extends and paths resolution can be confusing |
tsc-config shows the fully resolved config |
| TypeScript 7 (native Go) | 8–12x faster, but hard to adopt incrementally | tsgo-fast works alongside tsc with zero config changes |
tsforge wraps tsc and tsgo in ergonomic shell functions so you get speed, visibility, and consistency — from any project directory.
- 🔍 Auto-discovery — Walks up from
$PWDto findnode_modules/.bin/tscortsgo. Works from any subdirectory of any project. - ⚡ TypeScript 7 ready — First-class support for
tsgo, the native Go compiler (8–12x speedup on real codebases). - 📊 Rich diagnostics —
--diagnostics,--extendedDiagnostics,--generateTrace(Chrome/Perfetto),--explainFiles, and--showConfig. - 🏗️ Monorepo support —
tsc-buildandtsc-build-forcefor project references with--verbose. - 🩺 Health checks —
tsc-optimizeaudits yourtsconfig.jsonforincremental,skipLibCheck,isolatedDeclarations, andcomposite. - 🧹 Cache management —
tsc-cleanremoves stale.tsbuildinfowhen results feel wrong. - 🔒 npm v12 aware —
npm-audit-scriptslists dependencies that requestpreinstall/install/postinstallscripts (blocked by default in npm v12). - 🎨 TTY-aware colors — Auto-disables colors when output is piped, safe for CI logs.
- 🛡️ Double-source guard — Sourcing the script twice does not redefine functions.
- 📦 Zero dependencies — Pure Bash +
grep+time. Nothing to install.
See it in action (generate the GIF locally):
git clone https://github.com/setuju/tsforge.git
cd tsforge
make demo # requires vhs, ttyd, ffmpegWhat the demo shows:
| Scene | Command | What you see |
|---|---|---|
| 1 | time npx tsc --noEmit |
The slow baseline — the problem tsforge solves |
| 2 | source ~/tsforge.sh + tsforge-help |
Loading the toolkit and listing commands |
| 3 | tsc-where |
Which tsc / tsgo / tsconfig is active |
| 4 | tsc-optimize |
Auditing tsconfig.json for missing perf flags |
| 5 | tsc-fast |
Fast type-check with timing |
| 6 | tsc-diagx | head -30 |
Per-file diagnostics — where time goes |
| 7 | tsgo-fast |
Native Go compiler — up to 10x faster |
| 8 | — | Outro with project URL |
💡 Tip: The GIF is generated from
demo.tapeusing VHS. Every commit totsforge.shordemo.taperegenerates it automatically via thedemo.ymlworkflow.
tsforge/
├── tsforge.sh # Main script
├── package.json # npm metadata (for tooling & CI)
├── README.md # Primary documentation
├── LICENSE.md # MIT License
├── CONTRIBUTING.md # Contribution guide
├── CODE_OF_CONDUCT.md # Community standards
├── CHANGELOG.md # Version history
├── SECURITY.md # Security policy
├── CODEOWNERS # Auto-review assignment
├── Makefile # Convenience commands
├── shell.nix # Nix reproducible shell
├── flake.nix # Nix flake (modern)
├── Dockerfile # Multi-stage container
├── .dockerignore
├── demo.tape # VHS demo script
├── .gitignore
├── .editorconfig
├── .shellcheckrc
├── docs/
│ ├── ARCHITECTURE.md # How it works internally
│ ├── COMMANDS.md # Extended command reference
│ ├── TSconfig.md # tsconfig optimization guide
│ └── TROUBLESHOOTING.md # Common issues & fixes
└── .github/
├── FUNDING.yml
├── dependabot.yml
├── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ ├── feature_request.md
│ └── config.yml
├── PULL_REQUEST_TEMPLATE.md
└── workflows/
├── shellcheck.yml # Lint on every push
├── test.yml # Smoke tests (Bash + Docker + Nix)
├── demo.yml # Auto-regenerate demo.gif
└── release.yml # Tag → GitHub Release
curl -fsSL https://raw.githubusercontent.com/setuju/tsforge/main/tsforge.sh -o ~/tsforge.sh
chmod +x ~/tsforge.sh# For Bash
echo '[ -f "$HOME/tsforge.sh" ] && source "$HOME/tsforge.sh"' >> ~/.bashrc
# For Zsh
echo '[ -f "$HOME/tsforge.sh" ] && source "$HOME/tsforge.sh"' >> ~/.zshrcsource ~/.bashrc # or source ~/.zshrc
tsforge-help # or just: tsc-helpcd /path/to/any/typescript/project
tsc-where # confirm environment
tsc-optimize # audit tsconfig
tsc-fast # type-check with timing| Command | What it does | When to use |
|---|---|---|
tsc-fast |
tsc --noEmit with time |
Daily driver — the fastest path to "is my code valid?" |
tsc-watch |
tsc --noEmit --watch |
During active development |
tsgo-fast |
tsgo --noEmit with time |
When you need 8–12x faster type-checking |
tsc-fast # type-check current project
tsc-fast --pretty false # extra flags pass through to tsc
tsgo-fast # native Go compiler (if installed)| Command | What it does | When to use |
|---|---|---|
tsc-files |
tsc --noEmit --listFiles |
Find accidentally-included files |
tsc-diag |
Summary timing (parse/bind/check/emit) | Quick performance overview |
tsc-diagx |
Per-file type-checking times | When tsc-diag shows a bottleneck |
tsc-trace |
tsc --noEmit --generateTrace <dir> |
Deep profiling in Perfetto |
tsc-why |
tsc --noEmit --explainFiles > file |
Track down unwanted file inclusions |
tsc-config |
tsc --showConfig |
See the fully resolved config after extends/paths |
tsc-diagx # deep timing report
tsc-why tsc-explain.txt # write explanation to file
tsc-trace tsc-trace-dir # then open Perfetto| Command | What it does | When to use |
|---|---|---|
tsc-build |
tsc --build --verbose |
Rebuild only stale referenced projects |
tsc-build-force |
tsc --build --force |
Full rebuild when --build skips something it shouldn't |
tsc-build # incremental monorepo build
tsc-build-force # nuclear option| Command | What it does | When to use |
|---|---|---|
tsc-where |
Shows which tsc/tsgo/tsconfig is active |
Before debugging "why is it using the wrong config?" |
tsc-optimize |
Audits tsconfig.json for performance flags |
After cloning a new repo |
tsc-clean |
Removes .tsbuildinfo cache files |
When results feel stale after config changes |
tsc-where # environment dump
tsc-optimize # tsconfig health check
tsc-clean # clear incremental cache| Command | What it does | When to use |
|---|---|---|
npm-audit-scripts |
Lists deps requesting install scripts | Before upgrading to npm v12 (July 2026) |
npm-audit-scripts # build your allowlist| Command | What it does |
|---|---|
tsc-help / tsforge-help |
Show all commands |
tsforge is driven entirely by your existing tsconfig.json. The tsc-optimize command checks for these performance-critical flags:
Run tsc-optimize to see which flags are missing in your project.
tsforge is a set of pure Bash functions. There is no binary, no build step, and no runtime.
- Binary discovery —
_ts_find_local_binwalks upward from$PWDuntil it findsnode_modules/.bin/tsc(ortsgo). This means it works fromsrc/components/just as well as from the project root. - tsconfig discovery —
_ts_find_tsconfigdoes the same fortsconfig.json. - Command dispatch — Each public function (
tsc-fast,tsc-diagx, etc.) is a thin wrapper that adds_ts_header, passes through all extra arguments, and optionally wraps intime. - Color management — Colors are only emitted when
[ -t 1 ]is true. Piped output stays clean.
There is no magic. Read the script — it is heavily commented.
| Requirement | Notes |
|---|---|
| Bash 4.0+ or Zsh 5.0+ | Uses local, printf, $'\033' escape syntax |
grep |
Used by tsc-optimize |
time (Bash builtin) |
Used by tsc-fast and tsgo-fast |
| TypeScript | npm install --save-dev typescript |
tsgo (optional) |
npm install --save-dev @typescript/native-preview for 8–12x speedup |
| npm 11.16.0+ (optional) | Required for npm-audit-scripts |
No macOS/Linux-specific binaries are used. Windows users can run tsforge under WSL, Git Bash, or MSYS2.
MIT — see LICENSE.md.
Jack
- GitHub: @setuju
- Website: saturumah.net
If tsforge saves you time, consider giving it a ⭐ on GitHub.
tsforge — TypeScript, faster.
Made with ☕ by Jack · saturumah.net
{ "compilerOptions": { // 50–90% faster rebuilds "incremental": true, // Skip .d.ts checking from node_modules "skipLibCheck": true, // Parallel .d.ts emit (TypeScript 5.5+) "isolatedDeclarations": true, // Required for project references "composite": true, // Keep build info inside node_modules (auto-ignored) "tsBuildInfoFile": "./node_modules/.cache/tsconfig.tsbuildinfo" } }