Strict mode in TypeScript isn't one setting — it's a bundle of flags including strictNullChecks, noImplicitAny, and strictFunctionTypes, among others. We inherited a 40,000-line client codebase running with strict mode off and spent three weeks turning it on. Here's what that actually cost us, and what it bought us.
What broke immediately
strictNullChecks was, by far, the most disruptive single flag. It surfaced over 600 places where the code assumed a value existed when TypeScript couldn't actually guarantee that — optional API response fields accessed without a check, array .find() results used without confirming they weren't undefined, and DOM queries assumed to always succeed.
// Before strict mode — compiles fine, crashes at runtime
const user = users.find(u => u.id === targetId);
console.log(user.name); // user could be undefined
// After — TypeScript forces you to handle it
const user = users.find(u => u.id === targetId);
if (user) {
console.log(user.name);
}
The bugs it caught were real
Of those 600+ null-check errors, we estimate roughly 40 represented genuine latent bugs — code paths that would crash in production under specific, rare conditions nobody had hit yet in testing. That number alone justified the migration for us. These weren't hypothetical type-safety improvements; they were incidents that hadn't happened yet.
What we'd do differently
- Migrate flag by flag, not all at once. We turned on every strict flag simultaneously and got buried under thousands of errors with no clear priority order. Enabling
noImplicitAnyfirst, fixing that fully, then moving tostrictNullCheckswould have kept the error count manageable at every stage. - Use
// @ts-expect-erroras a tracked escape hatch. For genuinely low-risk spots, we marked them explicitly instead of writing defensive code that added no real safety, and tracked those markers in a spreadsheet to revisit later. - Don't do it during a feature crunch. The migration touched files across the entire codebase, which meant merge conflicts with every feature branch in flight. We'd schedule it in a quiet sprint next time.
Key takeaway
Strict mode is worth it for any codebase with a lifespan longer than a few months, but treat the migration as a real project with its own timeline and priority order — not a config flag you flip on a Friday afternoon.
Three weeks of focused work, on a 40k-line codebase, for roughly 40 real bugs caught before production and a measurably lower rate of null-reference errors since. For us, the math clearly favored making the switch — and every new project since starts with strict mode on from day one.