What is TypeScript, and why do product teams still adopt it?
The dashboard showed $0 revenue for a customer who had paid. Support had screenshots. Engineering had a green build. The bug was a renamed field: totalCents on the server, totalAmount still typed into three React components nobody had touched since the migration. Grep found two of them. TypeScript would have flagged the third at compile time.
That is the whole pitch, stripped of ideology. TypeScript is JavaScript with a type checker that runs before your code ships. It does not make your product smart. It makes shape mismatches expensive on Tuesday afternoon instead of expensive when renewal conversations start.
My default for a small product team building something that will change: adopt TypeScript, run strict mode in CI, and wire types from your schema outward. The exceptions are real. They are just narrower than Twitter would have you believe.
What you are actually buying
You write .ts files. A compiler strips the types and emits JavaScript that Node, Bun, or the browser already runs. Types describe shapes: what a Postgres row looks like, what an API returns, what props a component expects.
The checker proves your code agrees with the types you declared. Not that your business logic is correct. A perfectly typed refund function can still refund the wrong person. What you get is consistency at scale. When someone renames a column, the compiler surfaces every file still expecting the old name. Grep is a good start. Types finish the job when the codebase outgrows one person's memory.
Most teams adopt incrementally. Greenfield repos can start fully typed. Brownfield JavaScript repos enable allowJs and tighten one folder at a time. Boring on purpose. Small teams cannot pause shipping for a rewrite, and they should not pretend they can.
Where the investment pays
TypeScript earns its keep when change is frequent and users feel mistakes immediately.
Shared contracts across layers. When your schema, API, and client describe the same entities, types become documentation the compiler enforces. Tools like Drizzle infer query results from Postgres tables. That kills the failure mode where production data and local assumptions diverge for a week before anyone notices.
Refactors you can afford. Products pivot. Columns rename. Permissions split. Typed codebases absorb those moves with compiler errors instead of Sentry events. For a five person team with no dedicated QA, that trade is rational.
Onboarding after month one. New engineers read types to learn what functions expect. The first week feels slower because types force explicit decisions. Month two often feels faster because fewer pull requests end with "oh, that property is sometimes undefined."
Libraries that assume types. Modern packages ship TypeScript definitions. Fighting JavaScript in a typed ecosystem means maintaining your own .d.ts shims. That friction pushes lukewarm teams toward TypeScript whether they planned it or not.
Where I would skip it
TypeScript is not free. These are stop signs, not moral failures.
Tiny scripts and one off glue. A deployment script that runs twice a year does not need generics. JavaScript is the right tool for code you will delete.
Teams that will not run the checker in CI. Types you ignore at build time are theater. If pull requests merge with suppressed errors, you inherited syntax without benefit.
Heavy throwaway prototyping. Early discovery sometimes needs to mutate objects freely. Strict typing during sketch phase feels like writing specs for a napkin drawing. Prototype in JavaScript, harden in TypeScript once the shape stabilizes. But actually harden it.
Solo founders who know JavaScript cold. If learning type gymnastics mid sprint slows customer value, ship untyped until pain appears. Pain is a signal, not a verdict.
How it fits the stack
TypeScript is one layer, not the whole strategy. The through line is how types flow from the database to the client. Random any at the HTTP boundary defeats the point.
| Layer | TypeScript role |
|---|---|
| Database schema | Types generated or inferred from tables |
| Application API | Request and response shapes checked at boundaries |
| Client UI | Components receive props with known fields |
| CI | tsc fails builds on drift |
Runtime choice is marginal here. Bun versus Node affects startup and tooling, not whether types help. React adds client weight TypeScript does not remove, but it makes large component trees safer to change.
What I would tell a founder in the same spot
Ask three questions before mandating TypeScript repo wide.
How often does the data model change? Frequent schema and API churn favors types. A static marketing site with one form does not.
How many people touch the same modules? Solo founders get less collision benefit. Three engineers editing checkout get more.
What happens when a shape mismatch reaches production? Silent wrong numbers in a dashboard argue for types. A broken blog image argues less.
If two answers point toward structure: TypeScript, strict CI, schema aligned tooling. If two point toward speed on a small surface: stay in JavaScript until the dashboard shows $0 again.
Practical defaults that work:
- Turn on strict mode in new packages. Legacy folders can lag.
- Type the boundaries first: HTTP handlers, database queries, payment integrations.
- Prefer schema driven generation over hand written interfaces.
- One failing type check blocks merge. No exceptions for "just this once."
- Review nullable fields like product decisions. Optional chaining everywhere often means the model is fuzzy.
Lessons
The JavaScript ecosystem grew faster than any team could mentally track. Packages multiply. APIs sprawl. TypeScript is partly a reaction to that scale. It is also a reaction to SaaS expectations: users assume admin tools, integrations, and permissions behave consistently. Consistency is a type problem dressed as a UX problem.
Small teams adopt TypeScript because the alternative is becoming the person who remembers every implicit contract. That person takes vacation. The product keeps shipping. Types distribute memory into the repo where pull requests can see it.
TypeScript will not save an unclear product strategy. It will not replace tests. It will not make Postgres optional. It will make ordinary mistakes expensive at compile time instead of expensive at renewal time. For software that must evolve under real customers, that trade still looks rational in 2026.
Work with Kleto
I am James Cowan, founder of Kleto. We help small teams adopt TypeScript where it pays, skip it where it does not, and wire schema first workflows so types stay honest from Postgres to the UI. Contact Kleto if that matches your stack.