velox-sfc
Single-file component (.vx) compiler for the Velox UI framework.
Overview
velox-sfc turns a .vx single-file component — <template>, <script setup>, <script>, <style> — into Rust source: it splits the blocks, parses the template into an AST, resolves component imports, and emits the render function, event dispatcher, v-model setters and scoped CSS that the generated State runs on. It is a pure parser/compiler crate: its only dependencies are pest and pest_derive, so it can run inside a build script without dragging in the rest of the framework. The veloxc CLI drives it, and its own tests — which execute the generated code — are what pull velox-core, velox-dom and velox-renderer in as dev-dependencies.
Features
.vxsplitting —<template>,<script setup>,<script>and<style>blocks via a pest grammar, with caret-style parse errors and non-fatal warnings collected intoSfc::warnings- Template parsing — iterative HTML-ish parser handling nesting, self-closing tags,
:bind,@eventand{{ interpolation }}; warnings returned viaTemplateDiag - Rust codegen — emits
render(), the event dispatcher,v-modelsetters and scoped CSS;RenderMode::State(whatveloxcuses) andResolve(reports unresolvable loop bindings) - Component imports —
ComponentResolverresolves PascalCase tags to their file imports, recursively - Scoped CSS —
<style scoped>rewritten to per-componentdata-v-*selectors - Stub generation —
to_stub_rsand variants for scaffolding a component - Script linting —
lint_scriptwarns aboutCell/RefCellstate that will not trigger a redraw
Installation
No feature flags. Runtime dependencies: pest 2.8 and pest_derive 2.8 only — the crate's normal dependency surface is a pure parser.
Quick start
Compile a minimal component — parse the .vx, then generate the render function:
use ;
let src = r#"<template>
<div>
<button @click="inc">Inc</button>
<span>{{ count }}</span>
</div>
</template>
<script setup>
use std::cell::Cell;
pub struct State { pub count: Cell<i32> }
impl State {
pub fn new() -> Self { Self { count: Cell::new(0) } }
pub fn inc(&self) { self.count.set(self.count.get() + 1); }
}
</script>"#;
let sfc = parse_sfc.expect;
assert!;
assert!;
let template = sfc.template.as_ref.unwrap.content.as_str;
let render_fn = compile_template_to_rs.expect;
// The generated body carries the event wiring and the render functions.
assert!;
assert!;
assert!;
let stub = to_stub_rs;
println!;
Documentation
- API reference: docs.rs/velox-sfc
- Book: Template syntax — the
.vxformat the crate compiles
Workspace crates
Velox is a workspace of six published crates. This crate is marked (this crate).
| Crate | What it provides | Documentation |
|---|---|---|
| velox-core | Reactive primitives: signals, effects, lifecycle hooks | docs.rs |
| velox-dom | VNode types, block + flex layout, positioning, overflow |
docs.rs |
| velox-style | CSS parsing, selectors, cascade; styles applied to VNode |
docs.rs |
| velox-renderer | Rendering backends, event dispatch, hit testing | docs.rs |
| velox-sfc · this crate | Single-file component compiler (pest grammar) → Rust | docs.rs |
| veloxc | The CLI and dev server | docs.rs |
Status
Published on crates.io at 0.1.1.
Working today: .vx parsing, {{ expr }} interpolation, v-if/v-else-if/v-else, and component imports. parse_template_to_ast preserves its historical behaviour of printing warnings to stderr; prefer parse_template, which returns them in a TemplateDiag. The crate is pure-parser at runtime — velox-core, velox-dom and velox-renderer are dev-dependencies used only by the tests that execute generated code.
License
Licensed under MIT OR Apache-2.0.
Copyright © FAHIM AHMED fahimaloy@tutamail.com