Accelerating CI: ~90% Faster Bundles with Vite and Knip

May 20, 2025 (12mo ago)

A real-world migration story on how switching from Webpack to Vite plus cleaning up unused code and dependencies with Knip cut our bundle times at Silence by ~90% and drastically improved development speed.

Build result after migrating to Vite and Knip

After the optimization, our build times now last ~2m.

The Pain: Slow Feedback, Wasted Time

Every time we deployed to any stage, dev, pre, or prod, the pipeline felt like a gamble. Sometimes it would take 20 minutes, sometimes 12, and occasionally our on-premises GitLab would crash due to the excessive build duration if there were other pipelines running.

At the core of our setup was react-scripts, which under the hood relies on Webpack. It is a powerful tool, but one that had grown into a bottleneck for us.

This situation did not just affect deployment times. It was slowing down our entire team.

We were losing time, burning compute resources, and increasing developer frustration, all without shipping value faster.

The Shift: Vite + Knip to the Rescue

Step 1: Analyse and Optimize with Knip

The first thing I tackled was identifying unused code, components, and dependencies in the project. To do this, I used Knip, a powerful tool that analyzes your codebase and flags anything that is not being used.

Getting started was simple:

npx knip

From there, I could see the list of unused files and dependencies in the project, then started deleting them after a double-check. In this case, Knip surfaced 55 unused files and 14 unused dependencies.

Knip output showing unused files

Knip output showing unused dependencies

Terminal output showing 55 unused files and 14 unused dependencies.

Step 2: Swapping Webpack for Vite

After cleaning up the codebase with Knip, it was time to replace react-scripts, which uses Webpack under the hood, with something leaner and faster.

Vite was the clear choice. It is modern, fast, and optimized for frontend frameworks like React.

To get started, I installed Vite and the official Vite React plugin:

npm install --save-dev vite @vitejs/plugin-react

Then I created a vite.config.js file to configure the basics:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
 
export default defineConfig(() => {
  return {
    plugins: [react()],
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./src"),
      },
    },
    server: {
      port: 3000,
    },
    build: {
      assetsDir: "static",
      outDir: "build",
    },
  };
});

Finally, I updated our package.json scripts to replace react-scripts with the vite command.

Package scripts after replacing react-scripts with Vite

That Was It: Simple Setup and No More Drama

From there, cold starts and HMR are now instant, and our pipelines currently take less than 2 minutes on average. It was also a huge win for developer experience.