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 17, 2026

vite-plugin-css-injected-by-js has 353,216 recorded weekly downloads on npm, a decrease of 53.3% over the past 30 days, ranking #284 of 2,256 tracked listings.

Weekly downloads
353,216
Official API · Oct 17, 2026
7-day growth
-56.4%
-457K weekly downloads
30-day growth
-53.3%
-403.8K weekly downloads
90-day growth
-60.6%
-543.4K weekly downloads
Rank
#284
Among tracked npm listings

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

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

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 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

or

or

Usage

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 case | Recommended approach |

| Component-level granular lazy-loading | Vite'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

⚠️ 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:

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.

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:

The InjectCSSOptions interface:

How it works under the hood

Build mode (Queue & Unlock)

During the build, each chunk's CSS injection code is wrapped in a function and pushed onto a global queue (globalThis.VITE_CSS_QUEUE). The CSS is not injected until you call injectCSS(). When called:

  1. A global flag (globalThis.VITE_CSS_UNLOCKED) is set to true. 2. The queue is flushed — all pending CSS is injected. 3. Any future lazy-loaded chunks that arrive after the unlock inject their CSS immediately.

This ensures correct behavior with relativeCSSInjection and code-split chunks that load asynchronously.

Dev mode (Mute & Observe)

In development, Vite handles CSS natively for HMR. The virtual module uses a MutationObserver to mute all tags (by setting media="not all") as soon as they appear. When you call injectCSS():

  1. The observer is disconnected. 2. All cached style nodes are unmuted (media attribute removed). 3. If a target is provided, the style nodes are moved into that target.

SSR & Web Worker safety

All DOM operations are guarded by typeof document !== 'undefined' checks and globalThis is used instead of window. The injectCSS() call is a safe no-op in SSR or Web Worker contexts.

Source Maps

The plugin correctly preserves source maps when prepending CSS injection code to your chunks. When build.sourcemap is enabled and topExecutionPriority is true (the default), the injected CSS code is flattened into a single line and prepended to the chunk. The source map mappings string is shifted by prepending a single ; character, which moves all original mappings down by exactly one row. This ensures debugger breakpoints remain accurate.

No additional configuration is needed — source maps work automatically with all injection modes (topExecutionPriority, relativeCSSInjection, and the virtual module).

Configurations

When you add the plugin, you can provide a configuration object. Below you can find all configuration parameters available.

cssAssetsFilterFunction (function)

The cssAssetsFilterFunction parameter allows you to specify a filter function that will enable you to exclude some output css assets.

This option is not applied to relativeCSSInjection logic.

Here is an example of how to use the cssAssetsFilterFunction:

dev (object)

EXPERIMENTAL Why experimental? Because it uses a non-conventional solution.

Previously, the plugin strictly applied logic solely during the build phase. Now, we have the capability to experiment with it in the development environment.

To activate the plugin in the development environment as well, you need to configure a dev object and set the enableDev parameter to true.

Here's an example:…

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: 353,216 weekly downloads as of Oct 17, 2026, -60.6% over 90 days.vite-plugin-css-injected-by-jsWeekly downloads on npm · Last 90 days353,216downloads / week-60.6% over 90 days0200K400K600K800K1M1.2MJul 19Aug 3Aug 18Sep 2Sep 17Oct 2Oct 17downloads / weekobservedarchived (Internet Archive)no observationsJul 22, 2026 – Oct 17, 2026 · 88 observations · Updated Oc…pluginstats.com
vite-plugin-css-injected-by-js weekly downloads on npm, last 90 days: 353,216 weekly downloads as of Oct 17, 2026, -60.6% over 90 days.

7/30/90-day growth

vite-plugin-css-injected-by-js weekly downloads growth on npm: -56.4% over 7 days, -53.3% over 30 days, -60.6% over 90 days.vite-plugin-css-injected-by-jsWeekly downloads growth on npm353,216downloads / week now7-day growth-457,042 weekly downloads-56.4%30-day growth-403,762 weekly downloads-53.3%90-day growth-543,400 weekly downloads-60.6%Growth vs. nearest observation to each baseline date · Updated Oct 17, 2026pluginstats.com
vite-plugin-css-injected-by-js weekly downloads growth on npm: -56.4% over 7 days, -53.3% over 30 days, -60.6% over 90 days.

Ranking history

vite-plugin-css-injected-by-js npm ranking history: currently #284 (by weekly downloads).vite-plugin-css-injected-by-jsnpm ranking · by weekly downloads · Last 90 days#284current rank#282#283#284#285#286Jul 21Aug 5Aug 20Sep 4Sep 19Oct 4Oct 19rankOct 18, 2026 – Oct 19, 2026 · 2 observations · Updated Oct 17, 2026pluginstats.com
vite-plugin-css-injected-by-js npm ranking history: currently #284 (by weekly downloads).

Listing placement

All npm2,256 listings · 113 pages · 1,130 shown · page 15, #4 (overall #284)
All npm: every listing in weekly downloads order

Listing placement

Vite plugins250 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 (121)
Recent weekly downloads observations for vite-plugin-css-injected-by-js
Date (UTC)Weekly downloadsChange vs. previous
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+10.2K
1,025,868—

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 19, 2026. See the methodology.