open-solid / sugar-twig
Syntactic sugar for Twig templates
Package info
github.com/open-solid/sugar-twig
Type:symfony-bundle
pkg:composer/open-solid/sugar-twig
Requires
- php: >=8.4
- symfony/console: ^8.0
- twig/html-extra: ^2.16|^3.24
Requires (Dev)
- phpunit/phpunit: ^13.0
- tales-from-a-dev/twig-tailwind-extra: ^1.1
This package is auto-updated.
Last update: 2026-04-01 08:13:20 UTC
README
A Symfony bundle that brings JSX-like component syntax to Twig.
Example
Define a component (templates/components/button.html.twig):
<button {{ html_attrs({'class': 'bg-primary text-primary-foreground'}) }}> {%- block content %}{% endblock -%} </button>
Use it:
<Button type="submit" className="h-8 px-2.5">Save</Button>
It compiles to native Twig embed/include calls at load time — zero runtime overhead, no custom tags to learn.
Output:
{% embed 'components/button.html.twig' with {type: 'submit' className: 'h-8 px-2.5'} only %}
{% block content %}Save{% endblock %}
{% endembed %}
Render:
<button type="submit" class="bg-primary text-primary-foreground h-8 px-2.5">Save</button>
Benchmark
The benchmark test at tests/Preprocessor/ComponentPreprocessorBenchmarkTest.php covers four tiers:
| Tier | Time budget | Memory budget | What it tests |
|---|---|---|---|
| no-op | < 5 µs | < 1 KB | Fast-path exit (plain HTML, no components) |
| simple | < 50 µs | < 8 KB | 3 flat self-closing components |
| medium | < 165 µs | < 32 KB | Dialog with compound blocks + nested Field/Input |
| complex | < 750 µs | < 64 KB | Full page: nav, cards, dialog, table (~40 components, 3 nesting levels) |
Each tier runs 1000 iterations for time and 100 for memory, with warmup passes. If a future change introduces a regression (e.g., O(n²) parsing), the complex tier will blow past 750 µs and fail.