Skip to main content

A Vue Component Library Template With TypeScript and Vite

· 3 min read

I wanted to create a Vue component library, and it took me a few tries to get it right. The particular difficulty lies in how TypeScript and Vite need to be configured to generate the correct files for publishing.

This article serves as a note for me to understand how to set up a Vue component project, and it is up-to-date as of 2025. The sample component starter is available at GitHub, which can be used as a template, forked, or cloned for a quick start.

Below, I outline some critical points that I briefly walked through in the README of the starter template, which are the trickiest aspects to get right.

The Build Process

Usually, we distribute JavaScript files along with type declarations so that the component can be used in TypeScript projects seamlessly. While Vite can generate both JavaScript files from TypeScript and type declarations (via a Vite plugin), we can separate the workload between Vite and the TypeScript compiler. The split is as follows:

  • vue-tsc (a wrapper around tsc) will generate type declaration files.
  • Vite will emit JavaScript (and other) files.

vite.config.ts

In vite.config.ts, we need to configure the build settings to ensure the project is ready as a library. This includes defining the entry point and specifying the file name of the final JavaScript output.

One issue I got stuck on was the build process: Vite automatically deletes the entire dist folder, which removes the type declaration files generated by vue-tsc. This can be avoided by setting emptyOutDir: false. With this, we must configure the build script to clean the folder at the start of every build manually. Another approach is to adjust the procedure—run vite build first, then generate the type files.

package.json

Several fields are important for configuring the project:

  • exports: Defines how your component can be consumed, including specifying where the type information is located.
  • build: If we need to manually empty the output directory, we may use something like:
    "build": "rm -rf dist && vue-tsc -b && vite build"
  • files: Controls which files are uploaded to the npm registry.

tsconfig.app.json

In a project scaffolded from Vite's vue-ts template, it separated TypeScript settings into different JSON files. The most important one is tsconfig.app.json, which controls TypeScript compilation for the Vue component.

{
"noEmit": false, // This is important to generate type declaration files
"emitDeclarationOnly": true, // Prevents the generation of JS files, which is handled by Vite
"declaration": true,
"declarationMap": true,
"outDir": "dist/types",
"rootDir": "src"
}

I struggled for a long time trying to figure out why no type declarations were generated despite tweaking the configuration. It turns out that the noEmit field is set to true in the default extended config of the vue-ts template. We need to allow emitting type files by setting noEmit to false, and to avoid generating JavaScript files (which is handled by Vite), we set emitDeclarationOnly to true. Other fields above are also important.

Summary

All configurations must be set up correctly to make the package ready for publishing. The full sequence from scaffolding to publishing is included in the README.md if you want to follow along.