JavaScript

TypeScript is now our default for new frontend projects

JS

Last year we ran TypeScript on an internal tool as an experiment. This year, after seeing how many bugs it caught before they ever reached a browser, we flipped our default: new client-facing frontend projects now start in TypeScript unless the client's own team specifically prefers plain JavaScript.

The learning curve for developers new to it is real but shorter than we expected, especially with the improved inference in recent TypeScript releases meaning we write far fewer explicit type annotations than the language's early reputation suggests. Editor support has also matured enough that the immediate, inline feedback on a wrong prop type or an undefined property access has genuinely changed how quickly we can move through a refactor without fear of a change silently breaking something several files away that nobody happens to be looking at during the change itself.

How we handled the rollout across the team

Rather than mandating the switch for every existing project simultaneously, we made TypeScript the default for new projects only, leaving existing JavaScript projects to migrate opportunistically or not at all depending on each project's specific circumstances. This avoided a disruptive, all-at-once migration effort and let the team build real comfort with TypeScript on lower-stakes new work before any pressure to apply it retroactively to an established, already-working codebase.

We still keep plain JavaScript on the table for very small scripts and one-off tools where the setup overhead is not worth it, but for anything a client will be maintaining for years, TypeScript is now the safer default. A few developers newer to the team have asked whether this makes onboarding harder, and our honest answer is that it adds a genuine but modest ramp-up cost, more than offset by how much faster a new developer can safely make changes to an unfamiliar codebase once the type system is actively telling them what a function expects rather than leaving that knowledge implicit in code comments or, worse, nowhere at all.

Migrating type definitions for third-party libraries that ship without them

Not every npm package we depend on ships its own TypeScript types, and the DefinitelyTyped community project fills that gap for most of the popular ones, but a handful of smaller or more obscure packages we rely on have no types available anywhere. For those, we write a minimal local declaration file covering just the functions and props we actually call rather than attempting a full, exhaustive type definition for a library we do not maintain, which keeps the type-safety benefit where it matters most without turning every new dependency into its own small research project.

What tooling we standardized on alongside the language switch

Adopting TypeScript also meant settling a few tooling questions as a team rather than leaving each project to decide independently: ESLint's TypeScript plugin for linting, a shared `tsconfig.json` base that every new project extends rather than configuring compiler options from scratch each time, and Prettier for formatting so code style discussions do not compete with the type-safety discussion for a reviewer's attention during code review. Having these settled once, centrally, has mattered nearly as much for onboarding speed as the type system itself, since a new project no longer starts with a round of tooling bikeshedding before any actual feature work begins.

Where we still make exceptions

A client occasionally comes to us with an existing plain JavaScript codebase and a firm preference to keep it that way, usually because their own in-house team is more comfortable maintaining it without TypeScript after we hand it off. We respect that preference rather than pushing our own default onto a team that will be the one living with the codebase long after our engagement ends, though we do still recommend at least JSDoc-based type hints as a lighter-weight middle ground in those specific cases.

← Back to the journal

Have a project in mind?
Let’s talk.

Tell us where you are and where you want to go. We'll map the fastest route between the two.

Currently accepting new clients