Before you buy Frontmatter Solo, you might have one question:
Will it actually work with my project?
That’s a fair question. Solo works with a constrained subset of Astro — literal props only, one layout per page, global CSS, static images. If your project uses client:* islands, scoped CSS, or dynamic expressions in props, Solo won’t accept it.
Before solo-check, the only way to get the exact Solo answer was to buy Solo and run solo:validate. That’s backwards.
Introducing solo-check
@withfrontmatter/solo-check is a free, open-source CLI validator. It runs the exact same validation rules as Solo — without generating anything, without requiring a purchase.
npx @withfrontmatter/solo-check
That’s it. It scans your project from the current directory and reports every incompatible pattern with the same error codes Solo uses. It also includes an AI workflow guide via --help-ai when you want help fixing a project faster.
What it checks
solo-check applies the full Solo contract:
- E201 — Non-literal props.
<Hero headline={page.title} />fails.<Hero headline="Hello" />passes. - E203 — Runtime Astro features.
client:*directives are not allowed. - E210 — Nested layouts. One layout per page, no layout composing another layout.
- E230 — Scoped CSS. Component
<style>blocks are not supported — move CSS to a global stylesheet. - E240 — Markdown pages. Solo v1 only processes
.astropages. - E250 —
import.meta.glob. Build-time glob imports are out of scope. - E251 —
Astro.url.pathname. Runtime URL state is not allowed. - E252 — Arbitrary frontmatter computation. No sorting, filtering, or assembling data in page frontmatter.
- E271 — Unsupported components. Some patterns are recognized but not yet supported in v1.
Framework components (React, Vue, Svelte) trigger warnings, not errors — they’re skipped with placeholders.
What it outputs
✓ src/pages/index.astro — OK
✓ src/layouts/Base.astro — OK
E201 src/pages/contact.astro:13 Non-literal props used in component Hero.
Fix: Use only string, number, boolean, or null props in Solo v1.
E230 src/components/Hero.astro:6 Scoped CSS is not supported.
Fix: Move CSS to a global stylesheet.
──────────────────────────────────────────
2 errors · 0 warnings
Tip: use the AI workflow to fix these errors automatically.
npx @withfrontmatter/solo-check --help-ai
──────────────────────────────────────────
Exit code 0 means your project is ready for Solo. Exit code 1 means there are errors to fix first.
Options
npx @withfrontmatter/solo-check --root ./my-project # specify root
npx @withfrontmatter/solo-check --strict # warnings become errors
npx @withfrontmatter/solo-check --json # machine-readable output
npx @withfrontmatter/solo-check --help-ai # show the AI workflow guide
The --json flag outputs a structured object useful for CI integration:
{
"ok": false,
"exitCode": 1,
"diagnostics": [
{
"code": "E201",
"severity": "error",
"file": "src/pages/index.astro",
"line": 13,
"message": "Non-literal props used in component Hero.",
"fix": "Use only string, number, boolean, or null props in Solo v1."
}
]
}
The workflow
The intended sequence is:
- Run
npx @withfrontmatter/solo-checkon your project - Fix any reported errors
- If needed, open the packaged AI workflow with
npx @withfrontmatter/solo-check --help-ai - Re-run until exit 0
- Buy Solo and download the CLI package or desktop app
- Run
frontmatter solo:build --adapter twig(or--adapter php)
If solo-check exits 0, solo:validate will pass with the same result. The contracts are identical — no divergence.
Starting from the Starter
If you’re starting a new project rather than validating an existing one, the simplest path is to start from the FM Solo Starter — a reference Astro project built to the Solo contract. It passes solo-check out of the box.
Why this is open-source
solo-check is built on @withfrontmatter/core and @withfrontmatter/solo-rules — the same validation layer Solo uses internally. Keeping it open-source means:
- the contract is auditable
- you can run it in CI without buying a license
- the community can contribute rule improvements
- there’s no information asymmetry between the validator and the generator
Solo generates. solo-check validates. The contract is the same.
Get it
npx @withfrontmatter/solo-check
Source: github.com/withfrontmatter/solo-check
If you find an incompatibility between solo-check and Solo itself — same project, different result — that’s a bug. Please open an issue.