npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vite-plugin-generate-html

v0.3.0

Published

A Vite plugin to generate separate output files for JavaScript and CSS bundles with customizable attributes.

Readme

Vite Plugin Generate HTML

A Vite plugin that writes generated <script> and <link> tags to separate files during the build.

The plugin reads Vite/Rollup output entry chunks, uses their final hashed asset filenames, and writes:

  • one file containing <script> tags for JavaScript entry chunks
  • one file containing <link> tags for CSS imported by those entry chunks

This is useful when your application shell is rendered outside Vite, for example in .html, .cshtml (Razor), .php, or another server-rendered template, but you still need references to Vite's hashed build assets.

It is inspired by Webpack's HtmlWebpackPlugin and is intended for similar use cases in Vite projects where generated asset tags need to be written into external template files.


Installation

npm install --save-dev vite-plugin-generate-html

Requirements

  • Node.js 18 or newer
  • npm 8 or newer

Usage

// vite.config.ts
import { resolve } from "node:path";
import { defineConfig } from "vite";
import generateHtmlFiles from "vite-plugin-generate-html";

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        app: resolve(__dirname, "src/main.ts"),
      },
    },
  },
  plugins: [
    generateHtmlFiles({
      publicDir: "/dist/",
      jsEntryFile: resolve(__dirname, "../templates/javascript.html"),
      cssEntryFile: resolve(__dirname, "../templates/css.html"),
    }),
  ],
});

If src/main.ts imports CSS:

import "./styles.css";

the generated files can look like this after a Vite build.

javascript.html:

<script type="module" src="/dist/app.abc123.js"></script>

css.html:

<link href="/dist/app.abc123.css" rel="stylesheet" media="all" />

The plugin overwrites both configured output files on each build.


Options

interface VitePluginGenerateHtmlOptions {
  /**
   * URL prefix added before generated JavaScript and CSS filenames.
   *
   * @default "/dist/"
   */
  publicDir?: string;

  /**
   * File path where generated `<script>` tags are written.
   */
  jsEntryFile: string;

  /**
   * File path where generated `<link>` tags are written.
   */
  cssEntryFile: string;

  /**
   * Custom attributes for generated tags by entry chunk name.
   */
  output?: Array<
    Record<
      string,
      {
        attrs: string[];
        linkAttrs: string[];
      }
    >
  >;

  /**
   * Limit generation to specific entry chunk names.
   * By default, all entry chunks are handled.
   */
  chunks?: string[];
}

publicDir

publicDir is used as a URL prefix for generated asset references. It is not read from disk.

For example, with publicDir: "/assets/" and an output chunk named app.abc123.js, the generated script tag uses:

<script type="module" src="/assets/app.abc123.js"></script>

jsEntryFile

Required. The file path where generated <script> tags are written.

cssEntryFile

Required. The file path where generated <link> tags are written.

Only CSS imported by handled Vite entry chunks is included. If a handled entry chunk has no imported CSS, no link tag is generated for that chunk.

output

Use output to customize attributes for specific entry chunk names.

generateHtmlFiles({
  publicDir: "/dist/",
  jsEntryFile: resolve(__dirname, "../templates/javascript.html"),
  cssEntryFile: resolve(__dirname, "../templates/css.html"),
  output: [
    {
      app: {
        attrs: ['type="module"', "defer", 'data-entry="app"'],
        linkAttrs: ['rel="stylesheet"', 'media="all"'],
      },
    },
  ],
});

Generated output:

<script type="module" defer data-entry="app" src="/dist/app.abc123.js"></script>
<link href="/dist/app.abc123.css" rel="stylesheet" media="all" />

When output is provided, each handled entry chunk must have a matching key for script generation. If you only want to configure some entries, combine output with chunks.

Default attributes are used when output is omitted:

  • <script>: type="module"
  • <link>: rel="stylesheet" media="all"

chunks

Use chunks to generate files for only specific entry chunk names.

generateHtmlFiles({
  publicDir: "/dist/",
  jsEntryFile: resolve(__dirname, "../templates/admin-javascript.html"),
  cssEntryFile: resolve(__dirname, "../templates/admin-css.html"),
  chunks: ["admin"],
});

This is helpful when a Vite build has multiple entry points and you want separate generated files for different pages or templates.


Multiple Entry Points

You can use the plugin more than once to write separate files for different entry chunks.

plugins: [
  generateHtmlFiles({
    publicDir: "/dist/",
    jsEntryFile: resolve(__dirname, "../templates/app-js.html"),
    cssEntryFile: resolve(__dirname, "../templates/app-css.html"),
    chunks: ["app"],
  }),
  generateHtmlFiles({
    publicDir: "/dist/",
    jsEntryFile: resolve(__dirname, "../templates/admin-js.html"),
    cssEntryFile: resolve(__dirname, "../templates/admin-css.html"),
    chunks: ["admin"],
    output: [
      {
        admin: {
          attrs: ['type="module"', 'data-entry="admin"'],
          linkAttrs: ['rel="stylesheet"', 'media="all"'],
        },
      },
    ],
  }),
];

Errors

The plugin throws an error when:

  • jsEntryFile is missing
  • cssEntryFile is missing
  • output is not an array
  • no handled entry chunks are found
  • output is provided but a handled entry chunk has no matching configuration
  • attrs or linkAttrs is not an array for a matching entry

License

This project is licensed under the MIT License.