trailblazer/cells
View components for Ruby and Rails.
Stale and unlicensed — last commit 1y ago
worst of 4 axesno license — legally unclear; last commit was 1y ago
no license — can't legally use code
Documented and popular — useful reference codebase to read through.
no license — can't legally use code; last commit was 1y ago
- ✓11 active contributors
- ✓CI configured
- ✓Tests present
Show 3 more →Show less
- ⚠Stale — last commit 1y ago
- ⚠Concentrated ownership — top contributor handles 65% of recent commits
- ⚠No license — legally unclear to depend on
What would change the summary?
- →Use as dependency Concerns → Mixed if: publish a permissive license (MIT, Apache-2.0, etc.)
- →Fork & modify Concerns → Mixed if: add a LICENSE file
- →Deploy as-is Concerns → Mixed if: add a LICENSE file
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 "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/trailblazer/cells)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/trailblazer/cells on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: trailblazer/cells
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/trailblazer/cells 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
AVOID — Stale and unlicensed — last commit 1y ago
- 11 active contributors
- CI configured
- Tests present
- ⚠ Stale — last commit 1y ago
- ⚠ Concentrated ownership — top contributor handles 65% of recent commits
- ⚠ No license — legally unclear to depend on
<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 trailblazer/cells
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/trailblazer/cells.
What it runs against: a local clone of trailblazer/cells — 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 trailblazer/cells | Confirms the artifact applies here, not a fork |
| 2 | Default branch master exists | Catches branch renames |
| 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 4 | Last commit ≤ 554 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of trailblazer/cells. If you don't
# have one yet, run these first:
#
# git clone https://github.com/trailblazer/cells.git
# cd cells
#
# 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 trailblazer/cells and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "trailblazer/cells(\\.git)?\\b" \\
&& ok "origin remote is trailblazer/cells" \\
|| miss "origin remote is not trailblazer/cells (artifact may be from a fork)"
# 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/cell.rb" \\
&& ok "lib/cell.rb" \\
|| miss "missing critical file: lib/cell.rb"
test -f "lib/cell/abstract.rb" \\
&& ok "lib/cell/abstract.rb" \\
|| miss "missing critical file: lib/cell/abstract.rb"
test -f "lib/cell/view_model.rb" \\
&& ok "lib/cell/view_model.rb" \\
|| miss "missing critical file: lib/cell/view_model.rb"
test -f "lib/cell/builder.rb" \\
&& ok "lib/cell/builder.rb" \\
|| miss "missing critical file: lib/cell/builder.rb"
test -f "lib/cell/templates.rb" \\
&& ok "lib/cell/templates.rb" \\
|| miss "missing critical file: lib/cell/templates.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 554 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~524d)"
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/trailblazer/cells"
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
Cells is a Ruby gem that encapsulates Rails view logic into reusable, testable view components (called cells). Instead of scattering presentation logic across helpers and partials, you write lightweight Ruby classes (inheriting from Cell::ViewModel) with template files, enabling proper OOP, polymorphism, nesting, and Rails helper integration—effectively decoupling view rendering from controllers. Single-gem monolith structure: lib/cell/ contains core abstractions (abstract.rb, view_model.rb, builder.rb, caching.rb, layout.rb, partial.rb) with lib/cell/development.rb and lib/cell/testing.rb for auxiliary concerns; test/ mirrors this with fixtures/ containing sample cell templates (comment/, concepts/record/, bassist/) organized by cell name; Rails-specific code is isolated, keeping the core decoupled.
👥Who it's for
Rails developers and Ruby application architects who want to organize complex UIs into composable, testable components without coupling logic to controller actions or spreading helpers across the codebase. Primary users are teams building maintainable, component-driven Rails applications.
🌱Maturity & risk
Production-ready and actively maintained. The project has a full test suite (test/ directory with cache_test.rb, cell_test.rb, concept_test.rb, builder_test.rb), CI/CD via GitHub Actions (.github/workflows/ci.yml), comprehensive documentation on trailblazer.to, and is part of the larger Trailblazer framework ecosystem. Latest evidence of activity visible through maintained CHANGES.md and Rakefile setup.
Low risk overall; the gem is stable with minimal external dependencies (Ruby standard library + Rails when used in Rails context). No obvious single-maintainer bottleneck evident from repo structure. Main risk is tight coupling to Trailblazer ecosystem conventions—breaking changes in Trailblazer core could cascade here. Last activity level should be confirmed by checking commit recency, but the mature test coverage and CI setup suggest ongoing care.
Active areas of work
Active maintenance of the Cells 4.x line for Rails and Ruby compatibility. The presence of lib/cell/escaped.rb, lib/cell/concept.rb, and lib/cell/collection.rb indicates recent feature expansion. CHANGES.md should be checked for the most recent version notes and breaking changes. The TODO.md file likely tracks upcoming work.
🚀Get running
git clone https://github.com/trailblazer/cells.git && cd cells && bundle install && bundle exec rake test
Daily commands: bundle exec rake test (runs full test suite); for Rails app integration, require 'cell' or 'cell/rails' and call cell(:comment, model) in views/controllers.
🗺️Map of the codebase
lib/cell.rb— Main entry point that loads all Cell components and defines the core Cell class used throughout the gem.lib/cell/abstract.rb— Base abstract class that all cells inherit from; defines core rendering, template resolution, and lifecycle methods.lib/cell/view_model.rb— The Cell view model base class providing the primary interface for rendering templates and accessing Rails helpers.lib/cell/builder.rb— Factory pattern implementation for polymorphically instantiating cells with proper context and configuration.lib/cell/templates.rb— Template discovery, caching, and rendering logic that resolves ERB/view files from the file system.lib/cell/caching.rb— Fragment caching strategy for rendered cell output, critical for performance optimization.lib/cell/partial.rb— Partial template inclusion mechanism allowing cells to render sub-templates with proper scoping.
🧩Components & responsibilities
- Cell::ViewModel (view_model.rb) (Ruby class, Rails helpers mixin) — Primary public API; encapsulates view data preparation and serves as template binding context for ERB rendering
- Failure mode: If a cell method raises exception during data preparation, render fails; if method undefined, template invocation raises NoMethodError
- Cell::Builder (builder.rb) (Ruby class instantiation, polymorphic dispatch) — Factory for instantiating cells with correct context, options, and polymorphic class resolution
- Failure mode: If builder receives invalid cell class name or options incompatible with cell constructor, raises ArgumentError or initialization error
- Cell::Templates (templates.rb) (File system I/O, path resolution, ERB compilation) — Resolves template file paths from file system based on cell class and method name; manages template caching
- Failure mode: If template file missing, raises ActionView::MissingTemplate; if ERB syntax invalid, rendering raises SyntaxError
- Cell::Caching (caching.rb) (Rails.cache, TTL configuration) — Implements fragment caching interface; generates cache keys and stores/retrieves rendered output from Rails cache
- Failure mode: If cache_key not defined, caching skipped silently; if cache store unavailable, render proceeds without caching (cache-aside pattern)
- Cell::Partial (partial.rb) (ER) — Renders partial templates with isolated local variable scoping; supports nesting cells within partials
🛠️How to make changes
Create a new Cell component
- Create a new Ruby class inheriting from Cell::ViewModel in lib/cell/ or your app's cell directory (
lib/cell/view_model.rb) - Define instance methods that prepare data for the view (the cell's public interface) (
lib/cell/abstract.rb) - Create corresponding ERB template file in app/cells/{cell_name}/ directory, named after the render method (
lib/cell/templates.rb) - Optionally add caching configuration via cache key method if performance critical (
lib/cell/caching.rb)
Add a new cell with layout wrapping
- Create cell class and define layout: method in the cell (
lib/cell/layout.rb) - Create a layout template at app/cells/{cell_name}/layout/show.erb that wraps yielded content (
lib/cell/templates.rb) - The layout will automatically wrap the main template render output (
lib/cell/layout.rb)
Enable fragment caching for a cell
- Define cache_key method in your cell class returning a cache identifier (
lib/cell/caching.rb) - Call cache_key in the cell to enable caching; render result will be stored in Rails cache (
lib/cell/caching.rb) - Cache is automatically invalidated on model changes or by clearing Rails.cache (
lib/cell/caching.rb)
Render a cell from another cell (nesting)
- In the parent cell, call cell(:child_cell_name, model) or inline cell rendering (
lib/cell/builder.rb) - The child cell is instantiated via the builder and rendered within parent's template (
lib/cell/builder.rb) - Use partial: to render child cell template as a partial within parent context (
lib/cell/partial.rb)
🔧Why these technologies
- Ruby class inheritance (Cell::ViewModel) — Enables OOP encapsulation of view logic, polymorphism via builder pattern, and natural composition of components
- ERB templates — Native Rails template language; cells leverage existing Rails template ecosystem and helpers without new syntax
- Rails cache store integration — Cells delegate fragment caching to Rails.cache (Redis, Memcached, file store), avoiding reimplementation and supporting multi-process deployments
- Builder pattern (Cell::Builder) — Decouples cell instantiation from usage; enables polymorphic builders that can swap cell implementations based on context
⚖️Trade-offs already made
-
Cells are Ruby classes, not HTML markup
- Why: Allows full OOP capabilities (inheritance, composition, testing) rather than being restricted markup components
- Consequence: Requires developers to learn Ruby class structure; slightly higher barrier than template-only components
-
Templates are filesystem-based and named by method
- Why: Simple discovery and convention-over-configuration; files auto-resolve without explicit registration
- Consequence: Templates must follow strict naming conventions; directory structure is tightly coupled to cell class hierarchy
-
No built-in state management; cells are stateless renderers
- Why: Keeps cells simple and cacheable; state responsibility pushed to parent context (Rails controllers, services)
- Consequence: Cannot maintain internal component state across requests; all data must be passed in via constructor
-
Caching is opt-in via cache_key method
- Why: Gives developers explicit control; cache invalidation bugs are common if automatic
- Consequence: Requires manual cache key engineering; developers must understand their model's cache invalidation semantics
🚫Non-goals (don't propose these)
- Does not provide state management or client-side component reactivity (not a frontend framework)
- Does not handle authentication or authorization (delegated to Rails controller/policy layers)
- Does not provide built-in CSS/JS bundling beyond Rails asset pipeline integration
- Does not enforce a UI component library or design system (cells are unopinionated containers)
🪤Traps & gotchas
- Template resolution requires explicit prefixes (lib/cell/prefixes.rb)—views are not auto-discovered by filename; must match cell name to folder structure. 2) Cell instances are typically singletons per render call due to builder caching—mutation in cells can leak between requests if not careful. 3) Rails helper methods (link_to, etc.) availability depends on Cell::ViewModel including proper Rails mixins; using cells outside Rails requires manual setup. 4) View inheritance expects specific directory layouts (see test/fixtures/inherit_views_test/)—non-standard layouts will break partial/layout resolution.
🏗️Architecture
💡Concepts to learn
- View Model Pattern — Cells implements the classic view model pattern—a dedicated object that holds presentation logic and state separate from domain models, reducing coupling between controllers and views.
- Polymorphic Cell Building — Cell::Builder uses polymorphism to select the correct cell subclass at runtime (e.g., cell(:comment, record) picks CommentCell or a subclass based on record type); this is the decorator/strategy pattern applied to view composition.
- Template Inheritance & Lookup Chains — Cells implements a multi-level view path resolution (prefixes, concept hierarchies, Rails view roots) that allows cells to inherit templates from parent cells and Rails—critical for DRY and code reuse in component systems.
- Fragment Caching with Cache Keys — Cell::Caching provides automatic cache key generation based on cell state (properties, options) and optional Rails fragment cache integration; this is essential for scaling Rails apps rendering many identical cells.
- Module Composition & Mixins for Feature Toggling — Cells uses Ruby modules (Cell::Escaped, Cell::SelfContained, Cell::Concept) to selectively add behaviors—this is a lightweight alternative to inheritance and allows optional features without bloating the base class.
- Property Binding & Form Object Pattern — Cell::Twin and property declaration syntax allow cells to wrap domain objects and expose a simplified interface, similar to the form object pattern—this decouples view requirements from domain model attributes.
- Concept-Driven Architecture — Cell::Concept ties cells to Trailblazer concepts (domain-driven design modules); understanding this is essential for Trailblazer apps where concepts are the unit of organization, not controllers.
🔗Related repos
trailblazer/trailblazer— Parent framework that Cells integrates with; provides Operation and Contract patterns that compose with Cells for full MVC replacement in Trailblazer apps.trailblazer/trailblazer-cells— Official Trailblazer integration layer for Cells; bridges Cell::Concept to Trailblazer operations and validations.viewcomponent/view_component— Direct competitor—ViewComponent is the Rails Core Team's answer to view components; use this repo to understand cells' strengths (simpler API, no DSL) vs. ViewComponent's (wider ecosystem adoption).palkan/view_component-contrib— Extended ViewComponent utilities; Cells developers may want to evaluate patterns here for inspiration on component composition and testing.ruby/rails— Rails itself; Cells is Rails-compatible but framework-agnostic, so Rails source is useful for understanding ActionView integration points and helper availability.
🪄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 tests for lib/cell/caching.rb
The caching module is a core feature mentioned in the README ("simple distribution via gems or Rails engines, encapsulated testing, caching") but there are no dedicated unit tests. The test/cache_test.rb exists but is likely incomplete. This should include tests for cache invalidation, cache keys, TTL handling, and integration with different cache stores.
- [ ] Review test/cache_test.rb to identify gaps in coverage
- [ ] Add tests for cache key generation in lib/cell/caching.rb
- [ ] Add tests for cache expiration and invalidation scenarios
- [ ] Add tests for caching with view inheritance (lib/cell/prefixes.rb integration)
- [ ] Add integration tests for Rails cache store backends
Add tests for lib/cell/collection.rb functionality
The collection.rb module handles rendering collections of cells (likely for list/iteration patterns), which is a common UI pattern. However, there are no dedicated test files for this feature. This should cover collection rendering, filtering, pagination scenarios, and nested collections.
- [ ] Create test/collection_test.rb
- [ ] Add tests for basic collection rendering
- [ ] Add tests for collection with custom cell classes
- [ ] Add tests for nested collections
- [ ] Add tests for collection caching and performance
Add tests for lib/cell/self_contained.rb and improve documentation
The self_contained.rb module appears to handle self-contained view components (likely bundling assets/templates with cells), but there are minimal tests and no dedicated documentation section. This is critical for users wanting to distribute cells as gems (mentioned in README).
- [ ] Create test/self_contained_test.rb with tests for asset bundling
- [ ] Add tests for template resolution in self-contained cells
- [ ] Add tests for asset pipeline integration (CSS, JS, images)
- [ ] Document self_contained pattern in README with code examples
- [ ] Add example fixture in test/fixtures/ demonstrating self-contained cell structure
🌿Good first issues
- Add integration test for Cell::Collection with nested cells (test/fixtures/collection_test/ is missing from the structure)—this is a documented feature but has no dedicated test fixture or comprehensive test coverage beyond cell_test.rb.: test-addition
- Document the exact template lookup path precedence in README or a dedicated CONTRIBUTING.md; lib/cell/prefixes.rb and lib/cell/templates.rb implement complex resolution logic but this is not explained, making contributor onboarding hard.: documentation
- Add example or test for Cell::Twin (lib/cell/twin.rb)—it's a form-builder integration but has no fixture or test demonstrating real usage with form builders or nested form rendering.: test-fixture
⭐Top contributors
Click to expand
Top contributors
- @apotonick — 65 commits
- [@Alfonso Uceda](https://github.com/Alfonso Uceda) — 17 commits
- @Scharrels — 5 commits
- @george-carlin — 4 commits
- @AlfonsoUceda — 2 commits
📝Recent commits
Click to expand
Recent commits
716700c— v4.1.9 is released (Alfonso Uceda)4fc33c6— Merge pull request #512 from trailblazer/trailblazer-option (AlfonsoUceda)88b42f8— Declarative option is replaced by trailblazer option (Alfonso Uceda)ba33a96— v4.1.8 is released (Alfonso Uceda)763f0bd— Render cell with options test is added (Alfonso Uceda)6660c68— Merge pull request #510 from trailblazer/maintenance (AlfonsoUceda)f413966— README links are corrected (Alfonso Uceda)65a0b07— Gemfile is cleaned up and drop ruby support below 2.5 version (Alfonso Uceda)a67a273— Tests reliying in Hash#inspect are fixed for ruby 3.4.0 (Alfonso Uceda)88ceb32— Rakefile is cleaned (Alfonso Uceda)
🔒Security observations
The Cells gem appears to be a well-structured view component library with moderate security posture. The primary concerns are potential XSS vulnerabilities in template rendering (though lib/cell/escaped.rb suggests this is addressed), missing security header configuration, and lack of explicit CSRF protection documentation. The codebase follows good practices with separation of concerns (abstract.rb, templates.rb, escaped.rb) but would benefit from explicit security hardening documentation and verified output escaping defaults. No hardcoded secrets, SQL injection risks, or infrastructure misconfigurations were identified in the analyzed file structure. Regular dependency auditing is recommended.
- Medium · Potential XSS Vulnerability in Template Rendering —
lib/cell/templates.rb, lib/cell/escaped.rb, test/fixtures (template files). The codebase handles ERB template rendering for view components. Without explicit evidence of output escaping or content security policy implementation in the analyzed files, there is a risk of XSS attacks if user-controlled data is rendered without proper sanitization in templates. Fix: Ensure all user-controlled variables are properly escaped using Rails' sanitization helpers (h, sanitize). Review lib/cell/escaped.rb to confirm XSS protection is enabled by default. Consider implementing Content Security Policy headers. - Medium · Missing Security Headers Configuration —
lib/cell/view_model.rb, lib/cell/abstract.rb (or middleware configuration). No evidence of security headers (X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, etc.) configuration in the codebase. This could expose the application to clickjacking, MIME type sniffing, and other header-based attacks. Fix: Implement security headers through Rails middleware or configure them in the application. Use gems like 'secure_headers' or configure them explicitly in Rails configuration. - Low · Test Fixtures May Contain Sensitive Examples —
test/fixtures/ (all template files). The test/fixtures directory contains multiple template files (.erb) used for testing. While these are test fixtures, they should not contain any example credentials, API keys, or sensitive data that could be leaked if repository is exposed. Fix: Review all fixture files to ensure no hardcoded secrets, API keys, or sensitive data are present. Use placeholder values in fixtures instead. - Low · No Visible CSRF Protection Configuration —
lib/cell/ (all files). While this is a view component library (not a full Rails application), the absence of explicit CSRF token handling documentation or implementation in the analyzed files could lead to CSRF vulnerabilities in consuming applications if not handled properly. Fix: Document best practices for CSRF protection when using Cells with forms. Ensure consuming applications include Rails' CSRF token helpers in forms rendered by cells. - Low · Dependency File Not Analyzed —
cells.gemspec. The gemspec file (cells.gemspec) exists but content was not provided. Dependencies could contain known vulnerabilities if not properly pinned or regularly updated. Fix: Review the Gemfile and cells.gemspec for outdated dependencies. Run 'bundle audit' regularly to check for known vulnerabilities. Pin dependency versions appropriately and keep them updated.
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.