Skip to main content

Rollup vs Vite in 2026: When You Need a Dedicated Bundler

·PkgPulse Team

TL;DR

Vite for apps, Rollup for libraries — and Vite uses Rollup internally anyway. Vite (~18M weekly downloads) is the default for web applications in 2026. Rollup (~15M downloads) remains the best choice for building JavaScript/TypeScript libraries that will be published to npm. The distinction: Vite adds development server, HMR, and framework plugins that you don't need when building a library.

Key Takeaways

  • Vite uses Rollup for production builds — they share the same output quality
  • Rollup produces the cleanest library bundles — best tree-shaking in the ecosystem
  • Vite is better for applications — dev server, HMR, plugin ecosystem for frameworks
  • tsup wraps Rollup (via esbuild) for library builds — the modern choice
  • Rollup plugin ecosystem is available in Vite (backward compatible)

The Relationship Between Rollup and Vite

Vite architecture:
  ┌─────────────────────────────────────┐
  │ Vite                                │
  │  ├── Dev server (native ESM)        │
  │  ├── esbuild (transpile + dep prep) │
  │  └── Rollup (production builds) ←──┼── This IS Rollup
  └─────────────────────────────────────┘

When you run vite build, you're running Rollup with Vite's plugin transform layer on top. The output quality is identical to running Rollup directly.


When to Use Rollup Directly

Library bundling is Rollup's stronghold:

// rollup.config.js — for a npm library
import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { dts } from 'rollup-plugin-dts';

export default [
  // Build the JavaScript
  {
    input: 'src/index.ts',
    output: [
      {
        file: 'dist/index.cjs',
        format: 'cjs',          // CommonJS for Node.js
        exports: 'named',
      },
      {
        file: 'dist/index.js',
        format: 'esm',          // ES modules for modern bundlers
        exports: 'named',
      },
    ],
    plugins: [
      resolve(),
      commonjs(),
      typescript({ tsconfig: './tsconfig.build.json' }),
    ],
    external: ['react', 'react-dom'], // Don't bundle peer deps
  },
  // Build the type definitions
  {
    input: 'src/index.ts',
    output: { file: 'dist/index.d.ts', format: 'esm' },
    plugins: [dts()],
  },
];

This produces:

  • dist/index.js — ES module for Vite/webpack tree-shaking
  • dist/index.cjs — CommonJS for older Node.js
  • dist/index.d.ts — TypeScript types
  • Proper package.json exports field support

When to Use Vite

// vite.config.ts — for an application
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  // HMR, dev server, framework plugins
  // Production build = Rollup with these plugins applied
});

Vite adds:

  • Fast dev server with HMR
  • Framework-specific transforms (JSX, Vue SFC, Svelte)
  • CSS Modules, PostCSS, Sass support
  • Asset optimization (images, fonts)
  • Built-in manifest for cache busting

None of these are needed when publishing a library to npm.


tsup: The Modern Library Build Tool

For most library authors in 2026, tsup is the preferred tool:

// tsup.config.ts — replaces custom Rollup config
import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs', 'esm'],       // Both output formats
  dts: true,                     // Generate .d.ts files
  splitting: false,
  sourcemap: true,
  clean: true,
  minify: false,                 // Libraries usually don't minify
  external: ['react'],           // Peer dependencies
  treeshake: true,
});

tsup uses esbuild (not Rollup) internally and produces identical output in most cases. The advantage: zero config for the 90% case.


Tree-Shaking Quality

Rollup's tree-shaking is considered the gold standard:

// Your library
export function add(a: number, b: number) { return a + b; }
export function multiply(a: number, b: number) { return a * b; }
export const CONSTANT = 'unused';

// Consumer imports only add
import { add } from 'your-library';

// Rollup output — CONSTANT and multiply are completely removed
// webpack output — may include them depending on settings
// esbuild output — similar quality to Rollup

For libraries where bundle size matters to consumers, Rollup's tree-shaking is worth using directly (or through tsup).


Configuration Complexity

TaskRollupVitetsup
Single output formatMediumLowMinimal
ESM + CJS + typesHighMediumMinimal
Framework appNot idealLowNot needed
Library with pluginsHighN/ALow

When to Choose Each

Use Vite when:

  • Building a web application (React, Vue, Svelte, vanilla)
  • You need a dev server with HMR
  • You want framework-specific plugins

Use Rollup directly when:

  • Building a library with unusual output requirements
  • You need precise control over the bundle output
  • You're building a library that other bundlers will consume

Use tsup when:

  • Building a TypeScript npm library (the modern default)
  • You want Rollup/esbuild quality without configuration overhead

Compare Rollup and Vite package health on PkgPulse.

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.