cssforge 0.2.0

Safety-first semantic CSS refactoring and modernization workbench
cssforge-0.2.0 is not a library.

CSSForge

CSSForge is a safety-first semantic CSS refactoring and modernization workbench written in Rust.

Features

  • Reusable cssforge-core analysis and refactoring engine library
  • cssforge non-interactive CLI for analysis, planning, applying transforms, and rule discovery
  • Ratatui/Crossterm interactive TUI with visual 4-step wizard workflow and unified diff preview
  • Lightning CSS integration for strict semantic AST validation
  • Lossless source-range scanning and patch-based rewriting
  • Conservative adjacent and local native CSS nesting transformations
  • Transformation safety states and proof verification metadata
  • Flexible output modes: dry-run, new-file, output-directory, overwrite-with-backup, overwrite, patch, and stdout
  • Git dirty-tree protection for destructive write operations
  • Structured JSON reporting for integration with automated workflows

Rules & Capabilities

CSSForge features 26 automated transformations split into Modernization and Structural Refactoring:

1. Modernization (Native Nesting, Range Syntax & Selectors)

Native Nesting & Selector Factoring

  • Nest pseudo-classes (nest-pseudo-class): .button:hover.button { &:hover { ... } }
  • Nest pseudo-elements (nest-pseudo-element): .card::before.card { &::before { ... } }
  • Nest attribute states (nest-attribute): .button[disabled].button { &[disabled] { ... } }
  • Nest compound states (nest-compound): .item.active.item { &.active { ... } }
  • Nest descendants (nest-descendant): .card .title.card { .title { ... } }
  • Nest combinators (nest-combinator): .card > .title, .card + .peer, .card ~ .peer
  • Factor selector lists (factor-selector-list): Factor comma-separated selectors sharing a base (.marker, .marker::before.marker { &, &::before })

At-Rule Inlining

  • Nest local @media (nest-media): Inline immediately-following @media blocks with matching selectors into nested rules
  • Nest local @supports (nest-supports): Inline immediately-following @supports blocks with matching selectors into nested rules
  • Nest local @container (nest-container): Inline immediately-following @container query blocks into nested rules
  • Nest @starting-style (nest-starting-style): Inline immediately-following @starting-style blocks into parent selector rules

Modern Selectors & Media Syntax

  • Consolidate :not() selectors (consolidate-not): Consolidate chained :not() selectors (:not(a):not(b):not(a, b))
  • Factor with :is() (modernize-is): Factor selector-list alternatives with uniform specificity into :is(...) grouping
  • Modernize with :where() (modernize-where): Factor selector-list alternatives into :where(...) for zero-specificity defaults
  • Modernize media range syntax (modernize-media-range-syntax): Convert min-width / max-width / min-height / max-height to CSS Range Syntax (e.g. (width >= 800px))

2. Refactoring (Consolidation, Deduplication & Structural Cleanup)

At-Rule Block Merging

  • Merge same named @layer blocks (merge-same-named-layer): Consolidate separated blocks of the same named @layer into their canonical first occurrence
  • Merge adjacent @media queries (merge-adjacent-media): Combine consecutive @media blocks having identical query conditions
  • Merge adjacent @supports queries (merge-adjacent-supports): Combine consecutive @supports blocks having identical feature conditions
  • Merge adjacent @container queries (merge-adjacent-container): Combine consecutive @container blocks having identical container name & query conditions
  • Merge adjacent @scope blocks (merge-identical-scope): Combine consecutive @scope blocks having identical root and limit parameters
  • Merge adjacent @starting-style blocks (merge-identical-starting-style): Combine consecutive top-level @starting-style blocks into a single block

Selector & Body Deduplication

  • Merge adjacent identical selectors (merge-adjacent-identical-selector): Combine consecutive style rules sharing exact same selector
  • Merge identical rule bodies (merge-identical-rule-bodies): Combine selectors sharing identical declaration bodies into a unified comma-separated rule
  • Factor identical states with :is() (factor-identical-states-with-is): Combine multiple states of the same element sharing identical bodies into &:is(:hover, :focus, ...) form
  • Gather related selector rules (gather-related-selector-rules): Gather scattered non-adjacent occurrences of the same selector — including exact duplicates, directly-attached pseudo-classes/elements (&:hover, &::before), combinator variants (+ *, > .child, ~ .peer), and whitespace-descendant variants (:not(*)) — into the canonical first rule block
  • Prune overridden declarations & rules (prune-overridden-declarations): Remove dead declarations and entire rules overridden by later identical selectors in the cascade

Safety rules strictly prohibit moving candidate rules across comments or unrelated CSS blocks. Parent selector lists, BEM token-concatenation lookalikes, and pseudo-element parent selectors are safely preserved.

Requirements

  • Rust 1.85+ (Edition 2024, pinned to toolchain 1.97.1 in rust-toolchain.toml)

Build

cargo build --release

The binary will be created at:

target/release/cssforge

Interactive TUI

Run interactive mode in the current directory:

cargo run -p cssforge --

Or target a specific path:

cargo run -p cssforge -- interactive ./styles.css

TUI Step-by-Step Wizard Flow

CSSForge features an intuitive, 4-step workflow:

  1. Select Files: Choose target CSS files (Space to toggle, a for all, Enter to confirm).
  2. Select Rules: Choose modernization rules or presets (Space to toggle, p for preset, Enter to confirm).
  3. Output Settings & Review: Select output mode (↑/↓ or 1-7 to choose, d for diff preview, Enter to apply).
  4. Done: View transformation summary and target paths (Enter or q to exit, r to start over).
Key Action
Enter Primary action: Confirm & advance to next step / Apply & Finish
Esc / Backspace / b Go back to previous step
Space Toggle highlighted item (file / rule / output mode)
or j k Move cursor / select option
a Toggle all (files or rules) / refresh analysis
p Cycle rule preset (Conservative ➔ Modern ➔ Aggressive ➔ Custom)
d / v Inspect unified code diff and semantic proof checklist
Tab / Shift+Tab Cycle steps forward / backward
14 Jump directly to step 1 (Files), 2 (Rules), 3 (Output), 4 (Done)
r Rediscover CSS files from disk / Start over
q Quit

CLI Usage

Analyze:

cssforge analyze ./src --preset conservative
cssforge analyze ./src --preset modern --json

Generate transformation plans without modifying files:

cssforge plan ./src --preset conservative
cssforge plan ./src --json

Apply to new sibling files (default non-destructive mode):

cssforge apply ./src --preset conservative --output new-file

Dry run:

cssforge apply ./src --preset conservative --output dry-run

Write a mirrored tree to an output directory:

cssforge apply ./src --output out-dir --out-dir ./modern-css

Generate .patch files:

cssforge apply ./src --output patch

Overwrite with backup (requires acknowledgement):

cssforge apply ./src --output overwrite-with-backup --yes

Destructive overwrite modes are automatically blocked if Git reports an uncommitted working tree.

List available modernization rules:

cssforge rules

Presets

  • Analysis — No mutating rules enabled; surfaces modernization findings only.
  • Conservative — Enables pseudo-class, pseudo-element, attribute, compound, local @media, and local @supports nesting.
  • Modern — Enables all implemented nesting and combinator rules.
  • Aggressive — Maps to the modern rule set; unsafe architectural transformations are intentionally excluded.
  • Custom — Manual rule selection via the interactive TUI.

Safety Model

Every generated transformation plan includes verification proof flags:

  • Safety classification (SAFE, REVIEW, UNSAFE)
  • Exact source byte ranges
  • Original and proposed CSS text
  • Selector-set proof flag
  • Specificity proof flag
  • Cascade-context proof flag
  • Source-order proof flag
  • Layer/scope proof flags
  • Declaration and !important preservation proof flags
  • Human-readable reason and warnings

Only verified SAFE plans are applied by default. The CLI can opt into REVIEW plans with --allow-review.

Source-Preservation Approach

Lightning CSS is used to validate CSS syntax and AST structures. CSSForge does not reserialize the full stylesheet through Lightning CSS; instead, the source scanner targets exact byte ranges and replaces only the structural cluster being transformed. Declaration bodies are preserved directly from the original source text, retaining formatting, comments, custom properties, and !important flags.

Unchanged ranges remain untouched.

Workspace Structure

cssforge/
├── Cargo.toml
├── rust-toolchain.toml
├── crates/
│   ├── cssforge-core/
│   │   └── src/
│   │       ├── discovery.rs
│   │       ├── engine.rs
│   │       ├── lib.rs
│   │       ├── model.rs
│   │       ├── output.rs
│   │       └── scanner.rs
│   ├── cssforge-tui/
│   │   └── src/
│   │       ├── app.rs
│   │       ├── banner.rs
│   │       ├── lib.rs
│   │       └── ui.rs
│   └── cssforge-cli/
│       └── src/main.rs
└── LICENSE

Testing

Run workspace test suite:

cargo test --workspace