Component libraries and SDKs need different output than apps.
An app build produces an HTML entry and hashed assets. A library needs stable file names, ESM (and sometimes CommonJS) output, and must not bundle its dependencies. Vite's library mode handles this:
build.lib.entry: one or more entry files (an object for multiple entry points).build.lib.formats: defaults to['es', 'umd']for a single entry;['es', 'cjs']is common for npm packages.nameis required forumd/iife(the global variable).build.lib.fileName: base name for output files.build.rolldownOptions.external: dependencies and peer dependencies that consumers install, e.g.react,react/jsx-runtime. Otherwise you ship a second copy of React inside your package.
What Vite does not do for you:
- Type declarations: run
tsc --emitDeclarationOnlyor a plugin such asvite-plugin-dts. - package.json: point
exports(withtypes,import,requireconditions) at the generated files and list them infiles. - CSS is emitted as a separate file that consumers must import; document it.
For pure TypeScript libraries without CSS or framework transforms, dedicated tools (tsdown, built on Rolldown, or plain tsc) are often simpler. Library mode shines for component libraries that need Vite's CSS and framework plugins.
Example
// vite.config.js
import { defineConfig } from "vite";
import { fileURLToPath } from "node:url";
export default defineConfig({
build: {
lib: {
entry: fileURLToPath(new URL("./lib/index.js", import.meta.url)),
formats: ["es", "cjs"],
fileName: "ann-dates", // dist/ann-dates.js and dist/ann-dates.cjs
},
rolldownOptions: {
external: ["date-fns"], // a dependency: don't bundle it
},
},
});
// package.json:
// "exports": { ".": { "import": "./dist/ann-dates.js", "require": "./dist/ann-dates.cjs" } },
// "files": ["dist"], "dependencies": { "date-fns": "^4.1.0" }
// dist/ann-dates.js starts with: import { format as e } from "date-fns";Remember
build.libsets entry, formats and file names- Externalize dependencies and peer dependencies
- Generate .d.ts separately; wire
exportsandfilesyourself - Consider tsdown or tsc for plain TypeScript libraries
Watch out for
- Forgetting to externalize React in a component library, shipping a second React copy.