Notes From Migrating a Large App to Vite
For a long time I treated bundle size as something to worry about later. Then a small change to our Vite setup turned into a week of debugging, and "later" arrived all at once.
Most of the complexity was accidental. Over the years we'd layered three different approaches to bundle size on top of each other, and each one made sense at the time.
The problem
We had good intentions. We even had a document describing how bundle size should work. The trouble was that the document and the code had quietly gone their separate ways.
The first symptom was subtle. Nothing failed outright, but bundle size kept drifting in the wrong direction, and every fix seemed to make the next one harder.
What we changed
We started by writing down the one rule we actually cared about, then deleted every bit of code that didn't serve it. It's not glamorous, but it works.
Here's a trimmed-down version of what we ended up with:
export function debounce<T extends (...args: any[]) => void>(fn: T, wait = 200) {
let timer: ReturnType<typeof setTimeout> | undefined;
return (...args: Parameters<T>) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), wait);
};
}
This alone let us delete a surprising amount of code elsewhere in the project.
A few things that helped along the way:
- Keep the old path around until the new one has survived a real incident.
- Measure before and after, even if it's just a rough number in a spreadsheet.
- Write the migration guide before writing the migration.
Caveats
None of this is free. The new approach is a bit more verbose, and newcomers occasionally ask why we don't just use TypeScript for everything. That's a fair question with a boring answer: we tried, and it made bundle size harder to reason about.
We still haven't solved accessibility. That's a post for another day, and honestly, I'm not sure we'll get it right the first time either.
Takeaways
If you take one thing away from this, let it be this: bundle size is a design decision, not a cleanup task. Make it early and make it on purpose.