Skip to content
CAI
Software that uses CAICheck a score

edgurgel/solid

70.8

Strong · 18 September 2026

4.8k

lines of production code

Elixir

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

Solid is a Liquid template engine implementation for Elixir that parses and renders dynamic content using variables, control flow, and iteration. It provides a comprehensive set of standard filters and tags, supporting strict parsing modes and detailed error handling for robust template evaluation. The system is designed to be a drop-in replacement for Ruby's Liquid, ensuring compatibility through extensive integration testing against the reference implementation.

How it got here

2016 — Nimble Parsec rewrite

7 changes.

The Solid template engine underwent a complete rewrite, replacing the legacy Neotoma-based PEG parser with Nimble Parsec to improve performance and error handling. This major overhaul introduced a new public API with strict parsing modes, detailed error reporting, and comprehensive test coverage. The update also modernized the project's dependency stack and build tooling to support Elixir 1.17.

2021–2025 — Solid Liquid engine implementation and testing

5 changes.

This period focused on the initial implementation of the Solid Liquid template engine, introducing core tags for control flow, iteration, and variable handling. Extensive test infrastructure was built to validate parsing, lexing, and rendering logic against a reference Ruby implementation. The work ensured robust coverage of edge cases, whitespace handling, and filter behavior through comprehensive unit and integration tests.

Features

Initial implementation of Liquid template tags

This release adds the core set of Liquid template tags to the \lib/solid/tags\ directory, enabling users to use variables, control flow, and iteration in their templates. The included tags are \assign\, \break\, \capture\, \case\, \comment\, \continue\, \counter\, \cycle\, \echo\, \for\, \if\/\unless\, \inline\_comment\, \raw\, \render\, and \tablerow\. This provides the foundational syntax support for building dynamic content with the Solid Liquid engine.

lib/solid/tags · high confidence

Removals

Removal of PEG compilation Mix task

The \tasks/compile.peg.exs\ file, which provided the \Mix.Tasks.Compile.Peg\ task for compiling Erlang Parsing Expression Grammars via Neotoma, has been deleted. This change removes the build-time capability to automatically compile \.peg\ source files into Erlang modules, meaning any PEG-based grammar compilation must now be handled by a different mechanism or is no longer supported.

tasks · high confidence

Removed legacy PEG parser implementation

The previous PEG-based parser implementation (solid\_parser.peg) has been removed from the source code. This change eliminates the old parsing logic, which is now replaced by the new parser implementation introduced in the same commit set.

src · high confidence

Behavioural changes

Major API overhaul with strict parsing and new error handling

The library has been rewritten to use Nimble Parsec, introducing a strict parsing mode that diverges from the original Liquid specification by supporting filters inside conditional tags (if/elsif/unless) via the new \filters\_in\_conditional\_tags\ option. The public API has changed significantly: \parse/1\ is now \parse/2\ returning \{:ok, template} \| {:error, TemplateError.t()}\, and \render/2\ is now \render/3\ accepting a \Template\ struct, a context map, and options like \strict\_variables\, \strict\_filters\, and \custom\_filters\. New error types (\RenderError\, \ParserError\, \TemplateError\) provide detailed feedback on parsing and rendering issues, and a new caching interface (\Solid.Caching.NoCache\) is included.

lib · high confidence

Solid Liquid template engine rewritten with Nimble Parsec

The Solid library has been completely rewritten to use Nimble Parsec, replacing the previous parser implementation. This change introduces a new set of internal modules for tokenizing and parsing Liquid templates, including Solid.Lexer, Solid.Parser, Solid.BinaryCondition, and Solid.ConditionExpression, alongside new data structures like Solid.AccessLiteral and Solid.AccessVariable. The rewrite also brings a comprehensive suite of standard filters (Solid.StandardFilter), tag implementations (Solid.Tag), and context management (Solid.Context), fundamentally changing how templates are processed and evaluated.

lib/solid · high confidence

Solid template engine rewritten with Nimble Parsec and new API

The parsing engine has been completely rewritten using Nimble Parsec, replacing the previous neotoma-based parser. This introduces breaking changes: custom tags must now implement the \Solid.Tag\ behaviour and use \Solid.Parser\/\Solid.Lexer\ instead of the old API. \Solid.parse/2\ now returns more detailed errors and attempts to parse the entire file rather than stopping at the first error. \Solid.render/3\ now returns a \{:ok, result, errors}\ tuple by default, supporting strict rendering modes (\strict\_variables\, \strict\_filters\) that raise or return errors for missing variables/filters. Performance improvements include lazy range materialization for \for\/\tablerow\ loops to prevent memory exhaustion, and optimized parsing by matching raw bytes. Bug fixes address \!=\/\\<\>\ comparisons with \blank\/\empty\, identifier parsing issues, and custom filter loading.

(repo-wide) · high confidence

Test coverage

Added comprehensive test suite for Solid Liquid template engine; Added test support infrastructure for Liquid template integration testing; Added unit tests for Solid template tags; Expanded integration test coverage for Liquid template engine; Expanded test suite for Solid parser and renderer.

Dependencies

Major dependency overhaul and Elixir 1.17 support

The project has been updated to require Elixir \~\> 1.17 and replaced the legacy parser toolchain (neotoma/peg) with modern dependencies including decimal (\~\> 3.0), date\_time\_parser (\~\> 1.2), and nimble\_parsec. Development tooling has also been refreshed, upgrading ex\_doc to 0.40.3, adding dialyxir for static analysis, and introducing jason and mix\_test\_watch for testing and watch modes.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 71.

Lenses

  • Code Health 96
  • Architecture 100
  • Maturity 58
  • Readiness 67
  • Security 99

Changes since last survey

  • 300 commits — 216 feature/other, 84 fixes

By area

  • (root) — 94 commits
  • lib/solid — 93 commits
  • test/cases — 44 commits
  • (repo) — 33 commits
  • test/solid — 17 commits
  • .github/workflows — 8 commits
  • test/integration — 6 commits
  • test/context_test.exs — 2 commits
  • lib/solid.ex — 1 commit
  • test/argument_test.exs — 1 commit
  • test/expression_test.exs — 1 commit

Notable commits

  • fix: Docs and typespecs fixes
  • fix: Fix Argument parsing to allow for multiple |
  • fix: Fix CI
  • fix: Fix CI workflow
  • fix: Fix Context access on "size"
  • fix: Fix Filter.plus when string are passed
  • fix: Fix StandardFilter.round
  • fix: Fix StandardFilter.slice
  • fix: Fix build status badge (#66)
  • fix: Fix capture block not rendering a variable to a binary (#79)
  • fix: Fix comment block check for solid syntax (#89)
  • fix: Fix comment tag parsing
  • fix: Fix compilation warnings
  • fix: Fix custom tag test
  • fix: Fix empty rendering
  • fix: Fix first filter on range
  • fix: Fix first filter with map
  • fix: Fix for iteration var scope
  • fix: Fix increment bug by changing input variable scope.
  • fix: Fix list rendering
  • …and 280 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

edgurgel/solid was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 18 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit f44cddcaceccd19e1c40c13e976a623b3ef3e3e2 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-5d04157a340d.