Skip to content
PluginStats

vite-plugin-css-injected-by-js weekly downloads statistics

By marco-prontera · npm · Vite plugins

A Vite plugin that takes the CSS and adds it to the page through the JS. For those who want a single JS file.

View on npm Stale · Oct 18, 2026

vite-plugin-css-injected-by-js has 392,194 recorded weekly downloads on npm, a decrease of 48.2% over the past 30 days, ranking #291 of 2,391 tracked listings.

Weekly downloads
392,194
Official API · Oct 18, 2026
7-day growth
-50.7%
-403K weekly downloads
30-day growth
-48.2%
-365.5K weekly downloads
90-day growth
-56.1%
-500.7K weekly downloads
Rank
#291
Among tracked npm listings

About vite-plugin-css-injected-by-js

vite-plugin-css-injected-by-js 🤯

npm version

A Vite plugin that bundles your CSS into JavaScript at build time, removing separate CSS files and enabling single-file deployments.

How does it work

By default, Vite extracts CSS into separate files during the build process. This plugin instead gathers all generated CSS and embeds it directly into the JavaScript bundle, injecting it at runtime. As a result, no standalone CSS file is produced and the corresponding <link> tag is removed from the generated HTML. You can also control the timing of the injection, specifying whether the styles should be applied before or after your application code executes.

Installation

npm install vite-plugin-css-injected-by-js --save-dev

or

yarn add vite-plugin-css-injected-by-js -D

or

pnpm add vite-plugin-css-injected-by-js -D

Usage

import { defineConfig } from 'vite'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'

export default defineConfig({
  plugins: [
    cssInjectedByJsPlugin()
  ]
})

By default, the CSS is injected automatically when the JavaScript bundle loads. If you need explicit control over when the CSS is injected (e.g. for Web Components, Shadow DOM, or SPAs that need to defer rendering), see the Virtual Module section below.


Virtual Module: On-Demand Injection

The plugin exposes an optional virtual module virtual:css-injected-by-js that gives you explicit control over when and where the bundled CSS is injected into the DOM.

When to use this
Use caseRecommended approach
Component-level granular lazy-loadingVite's native ?inline query
Macro-level injection control (Library authors, Web Components, SPAs)Virtual module virtual:css-injected-by-js

?inline vs Virtual Module: For component-level CSS that you want to control per-file, use Vite's built-in ?inline query (e.g. import css from './my.css?inline'). The virtual module is designed for macro-level control over the entire bundled CSS payload — deferring injection until your app is ready, or targeting a specific DOM node like a ShadowRoot.

Basic example
// vite.config.ts
import { defineConfig } from 'vite'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'

export default defineConfig({
  plugins: [
    cssInjectedByJsPlugin()
  ]
})
// src/main.ts
import { injectCSS, removeCSS } from 'virtual:css-injected-by-js'

// Your application setup...
const app = createApp()
app.mount('#app')

// Inject all bundled CSS when you're ready
injectCSS()

// If you need to clean the environment you can also remove the CSS
removeCSS()
⚠️ Advanced Configuration Limitations

When using the virtual:css-injected-by-js module, please be aware of the following architectural boundaries:

  • topExecutionPriority is ignored: When using the virtual module, the plugin forces the injection payload to the absolute top of your chunks. This is mathematically required to ensure the CSS Queue is initialized before your application code calls injectCSS().
  • Custom injectCode Boundaries: The removeCSS() function uses a synchronous MutationObserver on the target element. It will fail to track and remove your styles if your custom code:
    1. Injects into an element other than the configured target.
    2. Uses asynchronous logic (setTimeout, Promises, requestAnimationFrame).
    3. Uses Constructable Stylesheets (new CSSStyleSheet()) instead of actual DOM nodes.
Shadow DOM example

Pass a target option to inject the CSS into a ShadowRoot instead of document.head:

import { injectCSS } from 'virtual:css-injected-by-js'

class MyWidget extends HTMLElement {
  connectedCallback() {
    const shadow = this.attachShadow({ mode: 'open' })
    shadow.innerHTML = `<div class="widget">Hello</div>`

    // Inject the bundled CSS into this Shadow DOM
    injectCSS({ target: shadow })
  }
}

customElements.define('my-widget', MyWidget)
Server-Side Rendering (SSR) extraction

In SSR environments (like Next.js, Nuxt, or custom Node servers), DOM methods like document.head.appendChild are not available. Calling injectCSS() will safely do nothing. Instead, you can extract the raw CSS string to manually inject it into your server-rendered HTML payload.

import { getRawCSS } from 'virtual:css-injected-by-js'

export function render() {
  const appHtml = renderToString(MyApp)
  const cssString = getRawCSS()

  return `
    <!DOCTYPE html>
    <html>
      <head>
        <style>\${cssString}</style>
      </head>
      <body>
        <div id="app">\${appHtml}</div>
      </body>
    </html>
  `
}

Note: In Vite Dev Mode (npm run dev), getRawCSS() will return an empty string because Vite handles CSS natively via HMR. Test your SSR CSS extraction using the production build (npm run build).

TypeScript support

The plugin ships type declarations for the virtual module. Add it to your tsconfig.json:

{
  "compilerOptions": {
    "types": ["vite-plugin-css-injected-by-js/dist/esm/declarations/client"]
  }
}

The InjectCSSOptions interface:

declare module 'virtual:css-injected-by-js' {
  export interface InjectCSSOptions {
    /**
     * The DOM element where the <style> tag will be injected.
     * @default document.head
     */
    target?: HTMLElement | ShadowRoot;
  }

  export function injectCSS(options?: InjectCSSOptions): void;
  export function removeCSS(): void;
  
  /**
   * Returns the raw extracted CSS string. 
   * Highly useful for Server-Side Rendering (SSR) where DOM injection is impossible.
   */
  export function getRawCSS(): string;
}
How it works under the hood…

Description from the npm listing.

  • vite
  • vite-plugin
  • plugin
  • typescript
  • css-injected-by-js
  • single-js-file
  • css
  • js

README badge

Show your rank in a README or on your website. The badge updates automatically.

Charts

Images: 30d · 1y · all time · 1600×900 dark

Adoption over time

vite-plugin-css-injected-by-js weekly downloads on npm, last 90 days: 392,194 weekly downloads as of Oct 18, 2026, -56.1% over 90 days.vite-plugin-css-injected-by-jsWeekly downloads on npm · Last 90 days392,194downloads / week-56.1% over 90 days0200K400K600K800K1M1.2MJul 20Aug 4Aug 19Sep 3Sep 18Oct 3Oct 18downloads / weekobservedarchived (Internet Archive)no observationsJul 23, 2026 – Oct 18, 2026 · 88 observations · Updated Oc…pluginstats.com
vite-plugin-css-injected-by-js weekly downloads on npm, last 90 days: 392,194 weekly downloads as of Oct 18, 2026, -56.1% over 90 days.

7/30/90-day growth

vite-plugin-css-injected-by-js weekly downloads growth on npm: -50.7% over 7 days, -48.2% over 30 days, -56.1% over 90 days.vite-plugin-css-injected-by-jsWeekly downloads growth on npm392,194downloads / week now7-day growth-402,974 weekly downloads-50.7%30-day growth-365,466 weekly downloads-48.2%90-day growth-500,749 weekly downloads-56.1%Growth vs. nearest observation to each baseline date · Updated Oct 18, 2026pluginstats.com
vite-plugin-css-injected-by-js weekly downloads growth on npm: -50.7% over 7 days, -48.2% over 30 days, -56.1% over 90 days.

Ranking history

vite-plugin-css-injected-by-js npm ranking history: currently #291 (by weekly downloads).vite-plugin-css-injected-by-jsnpm ranking · by weekly downloads · Last 90 days#291current rank#282#284#286#288#290#292#294Jul 23Aug 7Aug 22Sep 6Sep 21Oct 6Oct 21rankOct 18, 2026 – Oct 21, 2026 · 4 observations · Updated Oct 18, 2026pluginstats.com
vite-plugin-css-injected-by-js npm ranking history: currently #291 (by weekly downloads).

Listing placement

All npm2,389 listings · 120 pages · 1,195 shown · page 15, #11 (overall #291)
All npm: every listing in weekly downloads order

Listing placement

Vite plugins257 listings · 13 pages · page 2, #13 (overall #33)
Vite plugins: every listing in weekly downloads order

Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.

Each band is one page of 20. Weekly downloads on a linear scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.

Recent observations

Full history (122)
Recent weekly downloads observations for vite-plugin-css-injected-by-js
Date (UTC)Weekly downloadsChange vs. previous
392,194+39K
353,216-47.8K
400,980+7.4K
393,580-183.9K
577,437-185K
762,4400
762,440-32.7K
795,168-15.1K
810,258-12.1K
822,357-7.5K
829,827-839
830,666-6.9K
837,546-198.6K
1,036,102—

Data source

Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.

Listing: https://www.npmjs.com/package/vite-plugin-css-injected-by-js. First seen Oct 16, 2026; last successful collection Oct 21, 2026. See the methodology.