@cssxio/unplugin

中文文档
0.12.9发布于 2026/11/03MITTypeScriptESM + CJS构建来源已验证近 30 天下载 2764

Universal bundler plugin for CSSX.

原始使用文档
文档目录5 节
  1. Naming and compiler coordination
  2. Vue 3 with Vite
  3. Programmatic API
  4. Options
  5. Extracted CSS

@cssxio/unplugin

CSSX has build tool adapters at these entrypoints:

import cssxEsbuild from '@cssxio/unplugin/esbuild';
import cssxRollup from '@cssxio/unplugin/rollup';
import cssxRspack from '@cssxio/unplugin/rspack';
import cssxVite from '@cssxio/unplugin/vite';
import cssxWebpack from '@cssxio/unplugin/webpack';

For Next.js, use the supported integration. It prepares one complete stylesheet, coordinates compiler workers, handles App Router inclusion and development updates, and sends CSS through Next's normal stylesheet pipeline. The browser bridge checks the stylesheet identity already included in the page, avoiding a redundant initial replacement even when transformed JavaScript is stale; later CSS-only edits are applied atomically without waiting for JavaScript HMR.

The integration requires app/layout.js, app/layout.jsx, app/layout.ts, app/layout.tsx, or the equivalent under src/app. It reports a configuration error for projects without an App Router root layout.

// next.config.mjs
import { withCSSX } from '@cssxio/unplugin/next';

export default withCSSX(
  {},
  {
    theme: '@theme reference { --color-brand: #171717; }',
    debug: true,
  },
);

CSSX defaults to serial s…x names and a persisted .cssx/classnames.json manifest in production withCSSX builds. Development uses source-addressed composite names based on module identity and CSSX call order, so changing literal text or its length leaves existing selectors stable. Development skips class-name compression, manifest writes, and reusable-fragment planning and caches project metadata so an existing source file is transformed again only when it changes. Next.js 16 projects can select either bundler with next dev --webpack / next build --webpack, or next dev --turbopack / next build --turbopack. MDX source files are compiled by the helper; install @mdx-js/mdx when a project contains .md or .mdx files. Configure serializable remark, rehype, or recma plugins with mdx. Use sourceRoots for linked workspace packages outside the project root.

withCSSX detects Next.js development versus production mode. Other adapters infer development from NODE_ENV=development, an active Vite server, a development compiler mode, or Rollup watch mode. esbuild has no standard mode signal, so set mode: 'development' explicitly. mode: 'production' disables development behavior.

withCSSX composes with a synchronous webpack(config) callback. It throws a clear error if an existing callback returns a Promise, since Next.js invokes that hook synchronously.

Naming and compiler coordination

The legacy stableClassNames: true option selects source-addressed composite names (d…) and overrides the expected serial composite output. This behavior is unchanged for compatibility. New configurations can choose naming: 'serial' | 'hash' | 'source' separately from coordination: 'memory' | 'manifest'. className controls serial or hash atomic names and prefixes; naming: 'source' selects source-addressed composites while atomic names continue to use className.

Manifest coordination stores identity assignments and the serial counter under a lock, then replaces the JSON file atomically. Keep the manifest between builds to retain serial assignments. A fresh manifest can assign different serial values. A custom classNameAllocator is in-process only and cannot be combined with manifest coordination or withCSSX.

For Webpack and Rspack, className configures CSSX's built-in allocator, which sibling compiler instances share when they have the same project root and plugin options. A custom classNameAllocator replaces that built-in allocator and must be supplied without className; it controls allocation only within the current process. Use manifest coordination when compiler processes must share serial assignments.

debug: true prints the effective naming mode, selector coverage, and compiler mapping status. debug: { reportFile: 'path/to/report.json' } writes a JSON report with utilities, source locations, generated classes, selector checks, manifest coordination status, and conflicting utility mappings. serverClientMappings.status is manifest-shared when a manifest is configured and collected modules agree, mismatch when one utility maps to different classes, or consistent-in-process when collected modules agree under an in-process allocator.

Add the selected generic adapter to your build tool plugins setting:

// vite.config.ts
import cssx from '@cssxio/unplugin/vite';

export default { plugins: [cssx()] };

Vue 3 with Vite

Place CSSX before Vue in the Vite plugin list. CSSX transforms create and sx calls in <script>, <script setup>, and :class="sx(...)" template bindings. Static plain class="..." attributes are intentionally left alone.

import cssx from '@cssxio/unplugin/vite';
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';

export default defineConfig({ plugins: [cssx(), vue()] });
// rollup.config.js
import cssx from '@cssxio/unplugin/rollup';

export default { plugins: [cssx({ cssFileName: 'assets/cssx.css' })] };
// webpack.config.js
import cssx from '@cssxio/unplugin/webpack';

export default { plugins: [cssx()] };
// rspack.config.js
import cssx from '@cssxio/unplugin/rspack';

export default { plugins: [cssx()] };
// build.mjs
import cssx from '@cssxio/unplugin/esbuild';
import { build } from 'esbuild';

await build({ entryPoints: ['src/main.ts'], bundle: true, plugins: [cssx()] });

Programmatic API

The main entrypoint exports the low-level unpluginFactory, the universal unplugin adapter instance, and named callable factories for Vite, Rollup, webpack, Rspack, and esbuild. Most applications should import one platform entrypoint shown above.

import { transformCssxModule, compileCssxStylesheet } from '@cssxio/unplugin';

const transformed = await transformCssxModule(source, 'src/button.tsx');
const stylesheet = await compileCssxStylesheet([
  {
    id: 'src/button.tsx',
    candidates: transformed?.candidates ?? {},
    origins: transformed?.origins,
    composites: transformed?.composites,
    atomicClasses: transformed?.atomicClasses,
  },
]);

transformCssxModule returns null unless the source module imports the configured CSSX runtime. Otherwise it returns transformed JavaScript, candidate metadata, composite-to-atomic selector metadata, source locations, and a JavaScript source map when the transform creates one. Pass an earlier compatible version 3 source map as its fourth argument to continue that map.

compileCssxStylesheet combines module metadata in stable module and utility order, removes duplicate utilities, aliases each winning atomic rule to the composite classes that use it, and returns generated CSS. It also returns a CSS source map when collected metadata includes source locations. CssxPluginOptions, TransformResult, IncomingSourceMap, CssxSourceModule, and stylesheet source-map types are exported from the main entrypoint.

Options

OptionDefaultWhat it does
importSource@cssxio/cssxModule specifier that identifies source files to transform. A source file must contain this text and have a JavaScript or TypeScript extension.
modeinferredSelects development or production behavior. esbuild requires an explicit development mode.
cssFileNamecssx.cssRelative CSS output path. It must be non-empty, end in .css, and stay within the bundler output directory. [hash] is replaced with a stable hash of the generated CSS.
namingserialSelects generated composite naming: serial, hash, or source-addressed source. Independent of compiler coordination.
coordinationmemoryCoordinates assignments within one adapter instance (memory) or through a persisted manifest (manifest).
manifestPath—JSON file used when coordination: 'manifest'. Independent compiler workers must share this path.
classNameserial s…xControls atomic naming format, prefix, suffix, and hash length. Respected by compiler allocators used in every adapter.
classNameAllocator—Custom allocator for in-process integrations. Omit className when supplying one; manifest coordination uses CSSX's persisted allocator instead.
stableClassNamesfalseDeprecated compatibility alias for naming: 'source'; emits source-addressed d… composites and overrides serial composite output.
stableClassNameStrategysource-locationChooses source location identities or module-order identities for source-addressed composites. Development adapters select module-order.
debugfalsePrints a concise output summary or writes a class/source/selector diagnostic JSON report.
sourceRootsproject rootAdditional source directories included in project metadata scans, such as linked workspace packages.
sourceMaptrueWhether to generate a separate CSS source map. Development defaults to false to keep warm updates lighter; set sourceMap: true to include development CSS maps.
layer—CSS layer name that wraps generated CSS. It must be a single valid layer identifier, such as cssx.
theme—Inline CSSX @theme source used while transforming and compiling CSS. The theme is compiled into generated rules; it does not add a global stylesheet.
themeFile—Path, relative to the current working directory, to a CSSX @theme file. It is reread when CSS is generated; Rollup-compatible adapters register it as a watched dependency. Do not use it with theme.
darkModemediaActivates dark: utilities with the system color-scheme media query (media), [data-theme=dark] (selector), or a .dark ancestor (class). Use the selector that matches your theme controller.
preflighttrueAdds Tailwind-compatible browser baseline rules before utilities. Set it to false only when the application deliberately owns a different global reset.

The universal adapter validates options when it is created. theme and themeFile cannot be used together. Invalid CSS paths and layer names fail the build before CSS is emitted.

CSSX emits the Tailwind-compatible browser baseline by default, so utility migrations retain box sizing, inherited typography, link treatment, and native form-control normalization. Set preflight: false only when an existing app stylesheet deliberately owns different global element styles.

Extracted CSS

Each production adapter collects CSS from the source files used by the final build. It does not create a CSS file when no used file has CSSX utilities. The default file is cssx.css. Set cssFileName to use another relative path. CSSX emits one composite class in markup for each static style composition while sharing declarations across composite selectors in the stylesheet.

For legacy stableClassNames: true with webpack or Rspack, CSSX scans the project source tree before emitting its public stylesheet. The Next.js integration owns the source preparation pass and does not require consumers to add a scanner, asset remapper, stylesheet link, or plugin hook.

The Rollup-compatible adapters retain transformed module metadata until generateBundle, then emit CSS and its map as build assets. The webpack and Rspack adapters retain metadata on native modules and emit assets at the additions stage of processAssets. The direct esbuild adapter enables the metafile, removes data for source files absent from it, and generates CSS in onEnd.

When sourceMap is enabled and source locations are available, generated CSS has a separate .css.map file and a source-map comment. Each mapping points to the source module location of the static utility string that created the rule. transformCssxModule can accept and return JavaScript source maps for build tools that provide a compatible input map.

During development, all adapters use a cached source coordinator and push stylesheet revisions over a development-only event stream independently of JavaScript bundle completion. Vite serves its event stream beneath the configured base path; Next.js, Webpack, Rspack, Rollup watch, and explicitly enabled esbuild development builds use a loopback transport. The injected browser bridge replaces the stylesheet automatically, preserving page state and avoiding a manual refresh. Keep the generated stylesheet in the initial document so CSS is present before the first update. Development watchers and browser transport are omitted from production builds.

CSS source maps are off by default during development to reduce stylesheet compilation time and memory use. Set sourceMap: true when you need to debug generated CSS mappings; production keeps the default source map behavior.

Resource use is bounded during development. The shared project scanner opens at most 64 directory watchers across all active CSSX projects in one process. Vite and esbuild use a native fast path capped at eight additional directory watchers; they watch directories rather than individual files and fall back to the bundler watcher if native watching fails or reaches the cap. Vite coalesces duplicate notifications and stylesheet compiles, transforms at most four changed modules concurrently, and caps distinct in-flight paths at 256. Rollup prepares CSS-only updates in its existing watchChange hook before scheduling the rebuild and serializes at most 256 pending changed modules through one queue. The scanner caps pending paths at 256, coalesces overflow into one reconciliation, and processes changed modules sequentially. Stopped coordinators release their metadata cache; at most eight inactive project snapshots are retained. Fixed-size digests avoid retaining full source text for edit checks. Vite keeps at most 64 prepared digests; Rollup and esbuild each cap prepared transforms at 64 entries and 16 MiB of estimated retained transform data. The Next.js stylesheet stream accepts at most 64 browser clients per app and keeps only the newest update queued for a slow client.

If a Vite-powered SSR framework skips Vite's HTML transform hook, CSSX injects its bridge in the rendered response. The fallback buffers at most 1 MiB and 4,096 chunks per response, with at most eight responses buffered at once; oversized or excess responses pass through without injection.

The 100 ms goal measures a warm existing-style save until the changed computed style is visible after the next animation frame. It does not include cold startup, newly introduced call sites, JavaScript edits, full-theme changes, or composition-structure changes. Run pnpm benchmark:dev-hmr for the cached compiler benchmark and pnpm test:hmr for browser save-to-visible benchmarks across esbuild, Rollup, Webpack, and Rspack. Vite and Next.js browser benchmarks run in the visual test matrix. Compiler timing alone is not a browser save-to-visible measurement.

With esbuild, outdir places CSS below that directory. outfile places it beside the output file. Without either option, it is placed below the working directory. With write: false, CSS and its map are appended to esbuild's in-memory outputFiles; otherwise they are written to disk. A later esbuild build removes CSS files that CSSX wrote when no utilities remain.

See the workspace README for CSSX syntax, supported utilities, and current exclusions.

版本与发布记录

@cssxio/unplugin 共发布 23 个版本,首次发布于 2026/09/03;过去 12 个月发布了 23 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.12.9latest2026/11/037 天前
0.12.82026/11/029 天前
0.12.72026/10/3110 天前
0.12.62026/10/3110 天前
0.12.52026/10/3111 天前
0.12.32026/10/3111 天前

关于 @cssxio/unplugin 的常见问题

@cssxio/unplugin 是什么?

Universal bundler plugin for CSSX.

如何安装 @cssxio/unplugin?

在项目目录运行 npm install @cssxio/unplugin,或使用 pnpm add / yarn add / bun add。

@cssxio/unplugin 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cssxio/unplugin 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cssxio/unplugin 可以商用吗?

@cssxio/unplugin 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cssxio/unplugin 的下载量有多少?

根据 npm 官方下载统计,@cssxio/unplugin 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,764 次,日均约 92 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cssxio/unplugin 还在维护吗?

最新版本 0.12.9 发布于 2026/11/03(7 天前);至今共发布 23 个版本,其中过去 12 个月发布了 23 个;首次发布于 2026/09/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。