
CSSForge is a safety-first, lossless semantic CSS refactoring engine and interactive terminal workbench written in Rust. It modernizes flat legacy CSS into native nesting, Range media queries, :is() factoring, and @layer consolidation with zero declaration loss and byte-range surgical precision.
📦 Published Workspace Crates
| Package |
Type |
Crates.io |
Description |
| cssforge |
CLI / TUI Binary |
 |
Standalone executable with both an interactive visual terminal UI (TUI workbench) and headless CLI. |
| cssforge-core |
Pure Rust Library |
 |
Headless AST parser, specificity calculator, and 27 transformation rules with zero UI dependencies. |
| cssforge-tui |
UI Component |
 |
Reusable Ratatui/Crossterm interface, ASCII banner, step-by-step wizard, and unified diff viewer. |
Option 1: Via Cargo (All Platforms — Recommended)
Option 2: Pre-compiled Standalone Binaries
Download from GitHub Releases:
# Extract and copy to local user bin (no sudo needed):
tar -xzf cssforge-v0.4.0-linux-x64.tar.gz
cp cssforge-v0.4.0-linux-x64/cssforge ~/.local/bin/
chmod +x ~/.local/bin/cssforge
🍏 macOS (Apple Silicon M-Series)
tar -xzf cssforge-v0.4.0-macos-arm64.tar.gz
cp cssforge-v0.4.0-macos-arm64/cssforge ~/.local/bin/
chmod +x ~/.local/bin/cssforge
🪟 Windows (x64 / ARM64 Snapdragon)
Extract cssforge.exe from cssforge-v0.4.0-windows-x64.zip and move it to any directory in your system Path (e.g. C:\Windows\System32 or your tools folder).
📁 Smart File Discovery & Default Ignored Conventions
When executing cssforge without arguments in any project directory (.), CSSForge automatically scans for human-authored .css files while applying zero-config safe discovery rules:
🚫 Automatically Ignored Directories & Purposes
- node_modules/, vendor/ — Third-party dependencies that should never be mutated by local refactoring tools.
- target/, dist/, build/, out/, .next/, .nuxt/, .turbo/, .svelte-kit/ — Ephemeral build and bundler output artifacts.
- .git/, .hg/, .svn/, .cache/ — Version control internals and compiler caches.
🚫 Automatically Ignored File Patterns & Purposes
- *.modern.css — Generated CSSForge output files (prevents infinite recursion loops).
- *.min.css, *.bundle.css, *.chunk.css — Minified/bundled CSS where identifiers and structures are intentionally mangled and not meant for source AST nesting.
- *.bak.css, *.backup.css — Safety backup files created prior to in-place overwrites.
- *.map.css — Source map artifacts.
Tip (Explicit Target Override): If you explicitly specify a file path (e.g. cssforge interactive ./dist/bundle.min.css), CSSForge will directly process the requested file. Standard .gitignore rules are also natively respected.
CSSForge automatically scans for CSS files in the current working directory or any path you pass:
1. Interactive TUI Workbench
# Go to ANY web project folder:
cd /path/to/my-project
# Launch interactive modernization:
cssforge
# Or target a specific folder / file:
cssforge interactive ./src/css
- [Enter] Next step / Apply
- [Space] Toggle file or rule selection
- [a] Select / Deselect All
- [p] Cycle presets (Conservative ➔ Modern ➔ Refactor ➔ Aggressive)
- [d] / [v] Open live unified code diff & safety proof checklist
- [q] Quit
2. Headless CLI (CI/CD & Automation)
# Analyze CSS files and report modernization findings
cssforge analyze ./src
# Analyze with structured JSON output
cssforge analyze ./src --json
# Apply modern preset to new files (*.modern.css)
cssforge apply ./src/app.css --preset modern --output new-file
# Overwrite in-place with automatic safety backup (.bak)
cssforge apply ./src/app.css --output overwrite-with-backup --yes
# List all 27 transformation rules
cssforge rules
🛠️ 27 Transformation Rules Summary
- Native Nesting: nest-pseudo-class, nest-pseudo-element, nest-attribute, nest-compound, nest-descendant, nest-combinator, factor-selector-list.
- Conditional At-Rules: nest-media, nest-supports, nest-container, nest-starting-style.
- Modern Selectors: consolidate-not, modernize-is, modernize-where, modernize-media-range-syntax.
- At-Rule Merging: merge-same-named-layer, merge-adjacent-media, merge-adjacent-supports, merge-adjacent-container, merge-identical-scope, merge-identical-starting-style.
- Deduplication & Pruning: merge-adjacent-identical-selector, merge-identical-rule-bodies, factor-identical-states-with-is, gather-related-selector-rules, prune-overridden-declarations.
- 27th — Nest layers under a selector: nest-layer-by-selector factors the exact same selector living in multiple named @layer blocks into .sel { @layer a { … } @layer b { … } }. Layer identity and first-declared layer order are preserved. It never nests @layer inside another @layer (that would create a child layer such as tokens.base). Gather stays inside one layer; this rule is the safe cross-layer counterpart.
For complete interactive visual examples of each rule, visit the Documentation Site.
🔒 Safety Guarantees & Why CSSForge
Unlike lowering tools (e.g. LightningCSS, esbuild) or destructive minifiers (e.g. cssnano), CSSForge is built strictly for lossless forward semantic modernization:
- 🛡️ Dual-Layer Zero-Regression Engine: LightningCSS validates the AST, but a surgical Byte Patch Engine mutates only the targeted byte ranges. Untouched lines, developer comments, custom indentation, and quote styles remain 100% byte-for-byte identical.
- 🔬 Mathematical Proof Engine: Calculates exact specificity vectors (a, b, c) with zero specificity drift guarantees.
- 🚫 Refusal as a Safety Feature: Refuses transformations that would break CSS matching (such as :is() specificity inflation on lower branches).
- ✨ Multi-Selector Cluster Factoring: Automatically factors multi-branch rules sharing identical bases into clean :is() blocks with nested children.
- 🔒 Git Dirty-Tree Guard: Blocks destructive in-place replacements if uncommitted Git changes are detected.
🚫 Strict Non-Goals (What We Do NOT & Will NOT Do)
- ❌ No BEM String Concatenation (&__element): Native CSS & is a selector token (desugars to :is()), NOT a Sass string concatenator. Writing .card { &__title { } } is invalid in native CSS.
- ❌ No Specificity Inflation / Lifting: If wrapping parent selectors in :is() would artificially lift the specificity of a lower-specificity branch and alter cascade priority, CSSForge refuses the refactor.
- ❌ No Destructive Re-Serialization: We never re-format untouched code, strip comments, convert colors, or drop intentional browser fallback duplicate declarations.
- ❌ No Unsound At-Rule Moving Across Barriers: We never hoist @media / @supports blocks across intervening selector barriers if moving them would invert the cascade.
MIT © Jayesh Mepani