facet
Facet
A Crystal-based template compilation system for building interactive component-based UIs.
[!CAUTION] FACET IS IN VERY EARLY DEVELOPMENT AND PRODUCTION USE IS NOT RECOMMENDED!
Quick Start
TODO
How It Works
Create build.cr to build the website:
require "facet"
input_dir = File.dirname(__FILE__)
output_dir = File.join(input_dir, "dist")
Facet.compile_static(input_dir, output_dir)
The crystal run build.cr command:
- Parses
.hcrfiles (Facet Component Resources) using the built-in parser - Extracts inline
<style>blocks and combines them into one CSS file - Extracts binding declarations from
<?cr ... ?>blocks (e.g.,${'#selector'}.onclick = handler()) - Compiles bindings to browser-ready JavaScript with event listeners and fetch handlers
- Hashes CSS and JS content using MD5 (first 8 chars) for cache-busting
- Generates complete output:
index.html— Complete HTML document with asset referencesstyles-<hash>.css— All CSS combined (from<style>blocks)index-<hash>.js— Compiled JavaScript with event handlers and RPC calls
Output Example
dist/
├── index.html # Main HTML file
├── styles-85b40ed1.css # CSS bundle (content-hashed)
└── index-34ef9096.js # JavaScript bundle (content-hashed)
The HTML automatically references the hashed assets:
<link rel="stylesheet" href="styles-85b40ed1.css">
<script src="index-34ef9096.js"></script>
HCR File Format
HCR files combine event binding declarations and HTML:
<?cr
${'#login-btn'}.onclick = login(${'#email'}, ${'#password'})
${'#logout-btn'}.onclick = logout()
?>
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; color: #333; }
</style>
</head>
<body>
<input id="email" type="email">
<input id="password" type="password">
<button id="login-btn">Login</button>
<button id="logout-btn">Logout</button>
</body>
</html>
Components:
<?cr ... ?>— Event binding declarations (optional):- Syntax:
${'#selector'}.on{event} = handler(${'#param1'}, ...) - Gets compiled to JavaScript event listeners with RPC calls
- Syntax:
<style>...</style>— CSS (extracted intostyles-<hash>.css)- Rest of the file — HTML (becomes part of
index.html)
Generated JavaScript (from <?cr ?> bindings):
- Creates addEventListener for each binding
- Extracts input values from selectors
- Sends POST request to
/_facet/{handler} - Handles redirect and HTML update responses
Repository
facet
Owner
Statistic
- 1
- 0
- 0
- 0
- 0
- about 8 hours ago
- May 5, 2026
License
Links
Synced at
Tue, 05 May 2026 04:26:53 GMT
Languages