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.
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.
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 <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 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 |
?inlinevs Virtual Module: For component-level CSS that you want to control per-file, use Vite's built-in?inlinequery (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 aShadowRoot.
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:
topExecutionPriorityis 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 callsinjectCSS().- Custom
injectCodeBoundaries: TheremoveCSS()function uses a synchronousMutationObserveron the target element. It will fail to track and remove your styles if your custom code:- Injects into an element other than the configured
target. - Uses asynchronous logic (
setTimeout, Promises,requestAnimationFrame). - Uses Constructable Stylesheets (
new CSSStyleSheet()) instead of actual DOM nodes.
- Injects into an element other than the configured
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
7/30/90-day growth
Ranking history
Listing placement
Listing placement
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)Similar npm Vite plugins plugins
All 20 vite-plugin-css-injected-by-js alternativesData 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.