@birdycom/omniacss-migrate

中文文档
0.14.3发布于 2026/11/05MITES Module构建来源已验证近 30 天下载 2892

Switch a Laravel / Vue / React project from Tailwind CSS to OmniaCSS and keep your class names (PostCSS + Vite plugin, scan, setup, codemod), or convert a Bootstrap 3/4/5 site to OmniaCSS + OmniaUI.

原始使用文档
文档目录9 节
  1. Laravel in 3 steps
  2. What the plugin does
  3. Colors
  4. Scales
  5. CLI
  6. Codemod (optional)
  7. From Bootstrap
  8. Options (PostCSS / Vite)
  9. Known gaps

@birdycom/omniacss-migrate

Switch a Laravel, Vue or React project from Tailwind CSS to OmniaCSS and keep your class names. flex items-center gap-4 p-4 md:p-8 bg-white dark:bg-gray-900 hover:bg-red-500/50 w-[37px] keeps working: the classes are resolved on demand and emitted as CSS that only uses OmniaCSS tokens (Omnia palette in OKLCH, rem scales, Omnia shadows and breakpoints).

Coming from Bootstrap 3, 4 or 5? See From Bootstrap.

This is the only package that names Tailwind and Bootstrap, because it is a migration tool.

Laravel in 3 steps

# 1. see what changes (dry run, nothing is written) and how much of your markup is covered
npx @birdycom/omniacss-migrate scan .
npx @birdycom/omniacss-migrate setup .

# 2. apply the switch: removes the Tailwind packages from package.json, swaps the Vite/PostCSS plugin, carries your theme into CSS
npx @birdycom/omniacss-migrate setup . --write
npm uninstall tailwindcss @tailwindcss/vite @tailwindcss/postcss && npm install -D @birdycom/omniacss-migrate

# 3. build as usual
npm run dev

Your Blade, Vue and React files stay exactly as they are. By hand it is two edits:

// vite.config.js
import omniaMigrate from "@birdycom/omniacss-migrate/vite";   // was: import tailwindcss from "@tailwindcss/vite"
export default defineConfig({ plugins: [laravel({ input: ["resources/css/app.css", "resources/js/app.js"] }), omniaMigrate()] });
/* resources/css/app.css: the entry, under our own name (setup --write renames @import "tailwindcss" to it): */
@import "@birdycom/omniacss-migrate";
/* the Tailwind forms keep working too: */
@import "tailwindcss";
@tailwind base; @tailwind components; @tailwind utilities;

Not using Vite? Use the PostCSS plugin instead:

// postcss.config.js
import omniaMigrate from "@birdycom/omniacss-migrate/postcss";
export default { plugins: [omniaMigrate({ content: ["resources/views/**/*.blade.php", "resources/js/**/*.{vue,tsx,jsx,js}"] })] };

What the plugin does

  • Replaces @import "@birdycom/omniacss-migrate" / @import "tailwindcss" / @tailwind base|components|utilities with Omnia core (tokens + the Omnia classes you use), a small base reset and the compat CSS for the classes it finds in your content.
  • Expands @apply (with variants, !important, and your own classes), theme(colors.red.500), --spacing(4), @theme, @custom-variant, @variant, @source, @source inline("…"); ignores @plugin and @config.
  • Reads tailwind.config.{js,cjs,mjs} (darkMode, theme.colors/extend.colors, fontFamily, borderRadius, spacing, boxShadow, screens, container, prefix, important) and your @theme blocks.
  • Output is wrapped in cascade layers omnia, theme, base, components, utilities: Omnia's reset and tokens lowest; the Omnia classes (for example what the codemod wrote) and the Tailwind-style names together in utilities, sorted the Tailwind way (variants after the base class, shorthands before longhands, the class with more properties first). So an Omnia class beats every reset and your own @layer components, and wins or loses against a Tailwind-style class in the same class exactly as before the codemod.

Class coverage: layout, flex/grid, spacing, sizing, typography, colors (text, bg, border, ring, outline, fill, stroke, divide, accent, caret, decoration, gradients from-/via-/to-), borders, radius, shadow, ring, opacity, filters and backdrop filters, transitions, animations, transforms, display, position, z-index, overflow, cursor, scroll snap, tailwindcss-animate classes, arbitrary values (w-[37px], bg-(--brand), [mask-type:luminance]), opacity modifiers (bg-red-500/50), negatives (-mt-2), !important, and variants hover: focus: active: disabled: first: odd: before: after: placeholder: file: marker: selection:, sm: md: lg: xl: 2xl: max-md: min-[…]:, @md: container queries, dark:, group-*, peer-*, data-[…]:, aria-*:, has-[…]:, not-*, in-*, supports-[…]:, *:, arbitrary variants [&>svg]:, motion-safe:, print:, rtl:.

Colors

Tailwind palette names map to the nearest Omnia palette token (src/data/colors.json, generated by scripts/build-color-map.mjs with nearestOmnia()): bg-red-500 becomes var(--color-red-50). Arbitrary colors (bg-[#0041a7]) are mapped to the nearest token too (arbitraryColors: "keep" keeps the literal). Opacity modifiers use color-mix(in oklab, <token> 50%, transparent). Colors from tailwind.config are mapped to Omnia tokens as well (--keep-brand-colors / keepBrandColors keeps them); values that are var(...)/hsl(var(...)) (shadcn style) stay as you wrote them.

Scales

Spacing, sizing, font sizes, radius, blur and containers use the familiar numbers (p-4 = 1rem). Shadows reuse Omnia's own shadow values. Breakpoints follow OmniaCSS (sm 36rem, md 50rem, lg 64rem; xl 80rem and 2xl 96rem exist for compatibility). Use breakpoints: "tailwind" for 40/48/64/80/96rem.

Names that exist in both systems (p-4, flex, shadow-md …) never collide: classes the compat layer resolves are removed from the Omnia core output.

CLI

omniacss-migrate scan <dir>                    coverage: % of class occurrences supported + the unsupported list
omniacss-migrate setup <project> [--write]     plan (dry run) or apply: package.json, vite/postcss config, CSS @theme + dark mode
omniacss-migrate codemod <dir> [--write]       rewrite to native OmniaCSS class names where the CSS is identical
omniacss-migrate build [-c glob] [-o file]     write the CSS once (no Vite or PostCSS)
omniacss-migrate css "md:hover:bg-red-500/50"  print the CSS for one class

omniacss migrate scan . does the same through the main CLI (npm i -D @birdycom/omniacss-migrate).

setup and codemod are dry runs unless you pass --write. Commit first: the files are changed in place.

Codemod (optional)

codemod rewrites class/className/cn()/cva() strings to native OmniaCSS names when an Omnia class has exactly the same declarations (for example items-center becomes align-items-center, p-4 becomes p-1). Everything else is left alone and listed. After --write the file omniacss-migrate.manifest.json tells the compat layer which names are now native, so p-1 (Omnia, 1rem) is never confused with the old p-1 (0.25rem). Run it over the whole project, not a single folder. Tests and scripts (tests/, scripts/, *.test.*, *.spec.* …) are skipped and listed, because they often assert class names as data; add --include-tests to rewrite them too.

From Bootstrap

npx @birdycom/omniacss-migrate bootstrap scan .              # report only
npx @birdycom/omniacss-migrate bootstrap codemod . --write   # apply (commit first)
npx omniacss build -o css/omnia.css                          # OmniaCSS for exactly the classes you use

Works on HTML, PHP, Blade, Twig, ERB, Vue and JSX templates; template code inside a class attribute (<?php … ?>, {{ … }}) is left untouched.

  • Utilities become the OmniaCSS class with the same declarations, looked up in the installed OmniaCSS build: mt-3 (1rem) becomes mt-1, d-md-none becomes md:d-none, justify-content-between becomes justify-between. Theme colors (text-primary, bg-dark, border-danger) map to the nearest Omnia token.
  • Components become OmniaUI classes: btn btn-primary → oc-btn, alert alert-danger → oc-alert oc-alert--danger, form-control → oc-input (oc-select on a <select>), card-body/panel-body → oc-card-content, table table-striped → oc-table oc-table--striped.
  • Grid classes (container, row, col-*, offset-*, g-*, row-cols-*) stay, served by a generated bootstrap-compat.css with only the classes in use, at OmniaCSS breakpoints. Utilities without an OmniaCSS twin (border 1px, z-1, mt-n1) keep their exact CSS in the same file.
  • JavaScript components (modal, dropdown, collapse, carousel, navbar, tabs, offcanvas, toast) and icon fonts are reported with the native replacement (<dialog> + commandfor, popover, <details>, scroll snap).
  • The Bootstrap <link> is replaced by omnia.css, the OmniaUI CSS and bootstrap-compat.css in the same asset folder.
  • The report lists classes your JavaScript toggles (classList.add('btn-primary')) and Bootstrap 3 classes in a newer site, split into "still styled by your CSS" and "safe to delete".
  • --write records the classes it produced in omniacss-migrate.bootstrap.json, so running it again never reads the new mt-1 (OmniaCSS, 1rem) as Bootstrap's mt-1 (0.25rem).

Options: --bs 3|4|5 (default: detected from package.json, the <link>, a local bootstrap.css or the markup), --breakpoints exact (keep Bootstrap's pixel breakpoints as min-[48rem]:), --compat <file>, --omnia-href, --omniaui-href, --compat-href.

Options (PostCSS / Vite)

OptionDefaultMeaning
contentdetected (Laravel, Astro, Nuxt, Vite)globs with class names; @source is honoured too
coretruetrue Omnia core on demand, "tokens" only the color tokens and base, false you load Omnia yourself
preflighttrueinclude the base reset
layerstruecascade layers
tailwinddetected3 or 4 naming (shadow-sm, rounded-sm, ring, blur-sm differ)
darkModedetected"class" (.dark) or "media"
breakpoints"omnia"or "tailwind"
arbitraryColors"nearest"or "keep"
safelist[]extra classes

Known gaps

  • Plugin classes other than tailwindcss-animate (typography prose, forms, Iconify icon-[…], container-queries plugin utilities) are not generated.
  • theme.extend.keyframes/animation from tailwind.config are not carried over.
  • bg-opacity-*/text-opacity-* (Tailwind 2 style) and mask-* utilities are not generated.
  • Classes assembled from fragments at runtime ("bg-" + color + "-500") cannot be found by any scanner: add them to safelist.
  • Breakpoints, shadows and nearest-palette colors differ slightly from Tailwind by design: check the result visually.
  • The first build parses the full Omnia CSS (a few seconds); later builds are cached. core: "tokens" is instant.

Node.js 22+. MIT

版本与发布记录

@birdycom/omniacss-migrate 共发布 16 个版本,首次发布于 2026/10/28;过去 12 个月发布了 16 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.14.3latest2026/11/053 天前
0.14.22026/11/053 天前
0.14.12026/11/044 天前
0.14.02026/11/034 天前
0.13.02026/11/035 天前
0.12.62026/11/025 天前

关于 @birdycom/omniacss-migrate 的常见问题

@birdycom/omniacss-migrate 是什么?

Switch a Laravel / Vue / React project from Tailwind CSS to OmniaCSS and keep your class names (PostCSS + Vite plugin, scan, setup, codemod), or convert a Bootstrap 3/4/5 site to OmniaCSS + OmniaUI.

如何安装 @birdycom/omniacss-migrate?

在项目目录运行 npm install @birdycom/omniacss-migrate,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 omniacss-migrate,可以用 npx omniacss-migrate 直接运行。

@birdycom/omniacss-migrate 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/birdycom__omniacss-migrate 是否存在。

@birdycom/omniacss-migrate 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@birdycom/omniacss-migrate 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@birdycom/omniacss-migrate 可以商用吗?

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

@birdycom/omniacss-migrate 的下载量有多少?

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

@birdycom/omniacss-migrate 还在维护吗?

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