zmoazeni/csscss
A CSS redundancy analyzer that analyzes redundancy.
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓5 active contributors
- ✓MIT licensed
- ✓CI configured
Show 3 more →Show less
- ✓Tests present
- ⚠Stale — last commit 7y ago
- ⚠Single-maintainer risk — top contributor 89% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/zmoazeni/csscss)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/zmoazeni/csscss on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: zmoazeni/csscss
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/zmoazeni/csscss shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 5 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 7y ago
- ⚠ Single-maintainer risk — top contributor 89% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live zmoazeni/csscss
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/zmoazeni/csscss.
What it runs against: a local clone of zmoazeni/csscss — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in zmoazeni/csscss | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 2750 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of zmoazeni/csscss. If you don't
# have one yet, run these first:
#
# git clone https://github.com/zmoazeni/csscss.git
# cd csscss
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of zmoazeni/csscss and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "zmoazeni/csscss(\\.git)?\\b" \\
&& ok "origin remote is zmoazeni/csscss" \\
|| miss "origin remote is not zmoazeni/csscss (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "lib/csscss.rb" \\
&& ok "lib/csscss.rb" \\
|| miss "missing critical file: lib/csscss.rb"
test -f "lib/csscss/redundancy_analyzer.rb" \\
&& ok "lib/csscss/redundancy_analyzer.rb" \\
|| miss "missing critical file: lib/csscss/redundancy_analyzer.rb"
test -f "lib/csscss/parser/css.rb" \\
&& ok "lib/csscss/parser/css.rb" \\
|| miss "missing critical file: lib/csscss/parser/css.rb"
test -f "lib/csscss/cli.rb" \\
&& ok "lib/csscss/cli.rb" \\
|| miss "missing critical file: lib/csscss/cli.rb"
test -f "lib/csscss/parser/base.rb" \\
&& ok "lib/csscss/parser/base.rb" \\
|| miss "missing critical file: lib/csscss/parser/base.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 2750 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2720d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/zmoazeni/csscss"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
csscss is a Ruby gem that parses CSS/SCSS/LESS files and identifies redundancy by detecting which rulesets share identical declarations. It reports which selectors could be consolidated to reduce stylesheet duplication, helping maintainers refactor CSS without manually reviewing all rules. Single-gem architecture: lib/csscss.rb is the entry point; lib/csscss/cli.rb handles command-line interface; lib/csscss/parser/ contains specialized parsers (base.rb abstracts CSS parsing logic, submodules handle background, border, font, margin, padding properties via multi_side_transformer.rb); lib/csscss/redundancy_analyzer.rb identifies duplicate rulesets; reporters (reporter.rb, json_reporter.rb) format output.
👥Who it's for
CSS maintainers and front-end developers who want to audit and reduce stylesheet bloat in production sites. Especially useful for teams managing large legacy CSS codebases or integrating into build pipelines via Compass, Grunt, or Gulp plugins.
🌱Maturity & risk
Moderately mature but declining. The project has Travis CI and Code Climate integration, structured test suite, and stable gem release (installed via gem install csscss), but the master branch shows no recent commit metadata visible and the README references only 1.9.x Ruby support (now ancient). Production-ready for analysis workflows but not actively developed.
Single maintainer (zmoazeni) with no visible co-maintainers. Ruby 1.9+ requirement is obsolete (released 2011). Depends on optional gems (sass, less, therubyracer/therubyrhino) that may have security or compatibility issues. No visible issue tracker data provided, so unknown open issue backlog.
Active areas of work
No active development visible from repo metadata. README indicates Sass/LESS support was added historically, and community extensions (grunt-csscss, gulp-csscss, compass-csscss) were built but are maintained separately.
🚀Get running
git clone https://github.com/zmoazeni/csscss.git
cd csscss
bundle install
bundle exec ./bin/csscss path/to/styles.css
Daily commands:
bundle exec ./bin/csscss path/to/styles.css
bundle exec ./bin/csscss -v path/to/styles.css
bundle exec ./bin/csscss -n 10 path/to/styles.css
🗺️Map of the codebase
lib/csscss.rb— Main entry point that loads and exposes the core API for CSS redundancy analysislib/csscss/redundancy_analyzer.rb— Core engine that detects duplicate CSS declarations across rulesets—the heart of the toollib/csscss/parser/css.rb— Primary CSS parser that tokenizes and normalizes stylesheets before redundancy analysislib/csscss/cli.rb— Command-line interface handling user input, file processing, and output formattinglib/csscss/parser/base.rb— Base parser class defining the interface for all CSS property parsers and shorthand expansionlib/csscss/types.rb— Type definitions and data structures representing parsed CSS declarations and rulesets
🧩Components & responsibilities
- CLI Handler (cli.rb) (Ruby, OptionParser, File I/O) — Orchestrates file reading, parser invocation, analyzer execution, and report generation; handles user arguments and I/O
- Failure mode: Invalid file paths, malformed arguments, or I/O errors cause graceful error messages to stderr
- CSS Parser (parser/css.rb + property parsers) (Custom tokenizer, regex, property-specific parsers) — Tokenizes raw CSS, expands shorthand properties into individual declarations, and normalizes rule structure
- Failure mode: Malformed CSS may silently skip unparseable sections; incomplete shorthand expansion may miss declarations
- Redundancy Analyzer (redundancy_analyzer.rb) (Set intersection, threshold matching) — Compares parsed rulesets to find shared declarations; applies thresholds to determine reportable redundancies
- Failure mode: Threshold tuning issues may produce false positives (over-reporting) or false negatives (missing real redundancy)
- Reporter (reporter.rb, json_reporter.rb) — Formats redundancy results into human-readable text or JSON for downstream
🛠️How to make changes
Add a new CSS shorthand property parser
- Create a new parser class in lib/csscss/parser/ that extends Base and implements parse() method to expand shorthand into individual properties (
lib/csscss/parser/new_property.rb) - Register the parser in the CSS parser's property handler dispatch logic (
lib/csscss/parser/css.rb) - Add comprehensive test cases covering edge cases and variations (
test/csscss/parser/new_property_test.rb)
Add a new output format/reporter
- Create a new reporter class inheriting from Reporter or JsonReporter in lib/csscss/ (
lib/csscss/custom_reporter.rb) - Implement format_redundancies() method to transform Redundancy objects into desired output (
lib/csscss/custom_reporter.rb) - Wire the reporter into CLI with a new --format flag in cli.rb (
lib/csscss/cli.rb) - Add tests verifying output formatting (
test/csscss/custom_reporter_test.rb)
Add support for a new CSS preprocessor or language
- Create language-specific extension file (e.g. lib/csscss/less_include_extensions.rb) to compile to CSS before analysis (
lib/csscss/less_include_extensions.rb) - Update CLI to detect file extension and trigger appropriate preprocessor compilation (
lib/csscss/cli.rb) - Add integration tests with sample preprocessor files (
test/csscss/less_integration_test.rb)
Improve redundancy detection algorithm
- Review current algorithm in redundancy_analyzer.rb and understand ruleset comparison logic (
lib/csscss/redundancy_analyzer.rb) - Modify the comparison thresholds or add new heuristics for detecting partial redundancies (
lib/csscss/redundancy_analyzer.rb) - Add test cases covering new edge cases and improvements (
test/csscss/redundancy_analyzer_test.rb)
🔧Why these technologies
- Ruby — Dynamic language suitable for text parsing and CLI tools; established ecosystem for CSS/SASS tooling
- Gem-based distribution — Standard Ruby packaging model enabling easy installation and dependency management via Bundler
- PEG-style parser (custom tokenizer) — Lightweight approach to parse CSS without external parser dependencies; custom handling of shorthands
⚖️Trade-offs already made
-
Manual shorthand expansion (border, margin, padding, font) rather than using CSS parsing library
- Why: Allows fine-grained control over property normalization and ensures consistent redundancy detection
- Consequence: More code to maintain; each new shorthand requires a custom parser module
-
Simple string-matching and set intersection for redundancy detection
- Why: Fast and deterministic; easy to reason about; no external ML/heuristic dependencies
- Consequence: May miss semantic redundancies (e.g., color: red vs color: #ff0000); threshold-based matching is rigid
-
No CSS validation or normalization of selectors (treated as opaque strings)
- Why: Simplicity; doesn't require knowledge of specificity or selector semantics
- Consequence: Cannot identify structurally identical selectors with different syntax (e.g., .foo vs .foo:root)
-
CLI-only interface with optional JSON output
- Why: Lightweight, Unix-philosophy approach; easy to integrate into build pipelines
- Consequence: No GUI or IDE plugin; integration requires shell scripting or custom tooling
🚫Non-goals (don't propose these)
- Does not suggest CSS refactoring or recommend which selectors to merge
- Does not validate CSS syntax; assumes input is valid CSS
- Does not optimize compiled output or minification
- Does not provide real-time IDE/editor integration
- Does not handle CSS preprocessor variables or mixins (SASS/LESS) at analysis time; only supports post-compilation analysis
- Does not track which browser versions or CSS specs are supported
🪤Traps & gotchas
Ruby 1.9+ only (no 1.8 support), but 1.9 is now obsolete—test on Ruby 2.x+. LESS requires therubyracer (V8) or therubyrhino (JRuby) which can fail to compile. Sass integration via gem install sass is optional but auto-detected if present. The --ignore-sass-mixins flag is marked experimental and behavior may be unreliable. No .env or config file support visible; all options are CLI flags.
🏗️Architecture
💡Concepts to learn
- CSS Shorthand Property Expansion — csscss must expand margin: 10px 20px into margin-top, margin-right, margin-bottom, margin-left to detect true duplicates; multi_side_transformer.rb does this non-trivially.
- Selector Specificity & Grouping — csscss matches rulesets by declaration content, not selector specificity, so .foo and #bar can be flagged as redundant despite different specificity; understanding CSS cascade is key to interpreting results.
- AST Parsing & Traversal — lib/csscss/parser/css.rb tokenizes stylesheets into an AST and dispatches to property parsers; understanding recursive descent parsing helps extend the parser.
- Sass/LESS Transpilation Integration — csscss optionally depends on sass and less gems to preprocess before analysis; this allows detection of duplicates hidden in mixins or variables.
- Declaration Comparison & Hashing — redundancy_analyzer.rb must normalize and compare CSS declarations to find matches; understanding how values are normalized (color formats, unit conversion) is critical.
- Regex-based CSS Tokenization — parser/common.rb likely uses regex patterns to split selectors and extract values; this is fragile and explains why csscss has limits on edge-case CSS.
🔗Related repos
stylelint/stylelint— Modern CSS linter that also detects duplication and style inconsistencies; successor approach using Node.js instead of Rubysass/dart-sass— Official Sass transpiler that csscss integrates with; understanding Sass AST helps extend csscss for preprocessor featurestwbs/bootstrap— Large CSS codebase that would benefit from csscss analysis; demonstrates real-world use case for redundancy detectionComcast/compass-csscss— Official community extension that wraps csscss for Compass projects; shows integration pattern for build systemsPurifyCSS/purifycss— Complementary tool that removes unused CSS; often used alongside csscss for complete stylesheet cleanup workflow
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive test coverage for lib/csscss/parser/css.rb
The css.rb parser is the main entry point for CSS parsing but lacks dedicated test coverage. Looking at test/csscss/parser/, there's a css_test.rb file but given the complexity of parsing CSS shorthand properties (background, border, font, etc.), the main parser likely needs more edge case tests for property expansion, nested selectors, and malformed input handling.
- [ ] Review lib/csscss/parser/css.rb to identify untested code paths
- [ ] Add tests in test/csscss/parser/css_test.rb for edge cases: multiple selectors, pseudo-selectors, media queries, and property expansion chains
- [ ] Test interaction between css.rb and shorthand parsers (background.rb, border.rb, font.rb)
- [ ] Add tests for error handling and malformed CSS input
Implement missing test coverage for lib/csscss/redundancy_analyzer.rb
The redundancy_analyzer.rb is a core component that identifies duplicate declarations across rulesets, but the existing test file (redundancy_analyzer_test.rb) likely has gaps. This tool needs robust testing for complex scenarios: multiple selectors sharing declarations, pseudo-classes, media query interactions, and specificity-aware redundancy detection.
- [ ] Audit test/csscss/redundancy_analyzer_test.rb for coverage gaps
- [ ] Add test cases for nested/chained selectors and pseudo-classes (::before, :hover, etc.)
- [ ] Add tests for media query blocks and @-rule handling
- [ ] Add tests for specificity handling when detecting redundancy across different selector weights
- [ ] Test performance with large stylesheets (1000+ rulesets)
Add integration tests for CLI output formats and migrate Travis CI to GitHub Actions
The .travis.yml file indicates the project uses Travis CI, which is increasingly deprecated. Additionally, lib/csscss/json_reporter.rb exists but there are likely missing integration tests validating CLI output for both default and JSON formats. Modern CI/CD with GitHub Actions would improve maintainability and reduce dependency on external CI services.
- [ ] Create .github/workflows/test.yml with Ruby matrix testing (2.6, 2.7, 3.0, 3.1+)
- [ ] Add integration tests in test/ directory validating CLI output: bin/csscss against sample CSS files with various flags (--json, --verbose, etc.)
- [ ] Verify json_reporter.rb output format against JSON schema in integration tests
- [ ] Test CLI error handling and exit codes for invalid inputs and missing files
- [ ] Remove or archive .travis.yml once GitHub Actions is confirmed working
🌿Good first issues
- Add unit tests for
lib/csscss/parser/common.rb—no corresponding test file exists in test/csscss/parser/, likely missing coverage for utility functions used by all property parsers. - Add support for CSS Grid properties (grid-row, grid-column, grid-auto-flow)—the parser only handles legacy layout properties; add grid.rb following the multi_side_transformer pattern.
- Update Ruby version requirement and CI config: .ruby-version and .travis.yml likely specify 1.9/2.0 syntax; modernize to 2.6+ and update dependency compatibility in gemspec.
⭐Top contributors
Click to expand
Top contributors
- @zmoazeni — 89 commits
- @carsonmcdonald — 6 commits
- [@JoseLuis Torres](https://github.com/JoseLuis Torres) — 2 commits
- @prsimp — 2 commits
- @laserlemon — 1 commits
📝Recent commits
Click to expand
Recent commits
bac3e42— Ignore vscode settings (zmoazeni)01eb853— Fixes warning about shadowing (zmoazeni)9a50341— Allow docker version to be changed (zmoazeni)a0c0e7e— Use latest ruby version (zmoazeni)709fb6a— Remove unnecessary method (zmoazeni)97c0941— Add docker-ruby command (zmoazeni)37e5e33— Use best practice when declaring structs (zmoazeni)b8b03c3— Bump version file (zmoazeni)414f7c7— Fixes test (zmoazeni)00664a6— Relocking the dependencies (zmoazeni)
🔒Security observations
The csscss project shows a reasonable security posture for a CSS analysis utility. Primary concerns include outdated Ruby version requirements, missing dependency information for vulnerability assessment, and potential input validation gaps in the CLI. No hardcoded secrets, SQL injection risks, or critical infrastructure misconfigurations are evident from the file structure. The codebase appears to be a relatively straightforward command-line tool with parser logic and reporting functionality, limiting attack surface. Recommended actions: update Ruby version support, provide dependency manifest for audit, implement input validation, and modernize CI/CD infrastructure.
- Medium · Missing Dependency Information —
Gemfile, Gemfile.lock. The Gemfile and Gemfile.lock files are referenced but not provided for analysis. This makes it impossible to detect vulnerable gem dependencies or supply chain risks. Fix: Provide Gemfile and Gemfile.lock content for dependency vulnerability scanning. Regularly audit dependencies using tools like 'bundle audit' or 'bundler-audit'. - Low · Outdated Ruby Version —
.ruby-version, README.md. The README indicates the project requires Ruby 1.9.x and up, which is significantly outdated. Ruby versions prior to 2.7.0 are no longer receiving security updates. Fix: Update to Ruby 2.7.0 or newer (ideally 3.0+). Ensure all dependencies are compatible with modern Ruby versions. - Low · Travis CI Configuration Present —
.travis.yml. The presence of .travis.yml indicates use of Travis CI for CI/CD. Travis CI free tier has been discontinued. Configuration may be outdated or non-functional. Fix: Migrate to actively maintained CI/CD platforms such as GitHub Actions, GitLab CI, or CircleCI. Ensure security scanning is integrated into the pipeline. - Low · No Evidence of Security Headers or Input Validation —
lib/csscss/cli.rb, lib/csscss/json_reporter.rb. The CLI tool accepts file paths as input without apparent validation. The JSON reporter outputs data without apparent sanitization, which could pose XSS risks if output is rendered in web contexts. Fix: Implement input validation for file paths. Ensure JSON output properly escapes special characters when used in web contexts. Add path traversal protection.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.