4 releases
| 0.0.1-beta.1 | Mar 16, 2026 |
|---|---|
| 0.0.1-alpha.3 | Feb 16, 2026 |
| 0.0.1-alpha.1 | Feb 9, 2026 |
#437 in Programming languages
5MB
119K
SLoC
verter_core
[!WARNING] This project is experimental and under active development. APIs, architecture, and package boundaries may change without notice.
Core Rust library crate that compiles Vue Single File Component (SFC) templates into optimized JavaScript render functions. This is the future heart of the Verter project -- it currently handles template compilation and will progressively take over more responsibilities from the TypeScript packages.
verter_core is a pure Rust library with no FFI dependencies. It is consumed by verter_napi (Node.js native bindings) and verter_wasm (browser WASM bindings).
Architecture
Compilation Pipeline
graph LR
A["Vue SFC<br/>source"] --> B["Tokenizer<br/>(tokenize::byte)"]
B --> C["Syntax Plugin<br/>Pipeline"]
C --> D["OXC Parser<br/>(parse_script)"]
C --> E["CSS Parser<br/>(LightningCSS)"]
C --> F["Analysis<br/>(scope/bindings)"]
D --> G["Vue Codegen<br/>Plugin"]
E --> G
F --> G
G --> H["Output<br/>code + source map"]
Plugin Architecture
The compiler uses a plugin-based pipeline where each stage is a SyntaxPlugin. The builder orchestrates execution in order:
graph TD
subgraph "Syntax Plugin Pipeline"
direction TB
T["Tokenizer"] --> BP["Block Extractor"]
BP --> OXC["OxcParserPlugin<br/>JavaScript/TypeScript parsing"]
BP --> CSS["CssParserPlugin<br/>Scoped styles, CSS modules"]
OXC --> AN["Analysis<br/>Scope & binding tracking"]
AN --> VUE["VueCodegenPlugin<br/>Render function generation"]
end
subgraph "Vue Codegen Internals"
direction TB
VUE --> SC["script.rs<br/>Script block codegen"]
VUE --> TP["template/<br/>Template codegen"]
VUE --> ST["style_plugin.rs<br/>Style processing"]
TP --> EL["element.rs<br/>Element open/close"]
TP --> DIR["directives.rs<br/>v-if, v-for, v-slot, ..."]
TP --> INT["interpolation.rs<br/>{{ expressions }}"]
end
Module Structure
src/
lib.rs Public module exports
builder/
codegen.rs Main pipeline orchestrator, CodegenOptions, CodegenResult
codegen/
vue/
plugin.rs VueCodegenPlugin (main codegen entry)
script.rs Script block codegen, extract_binding_metadata
script_plugin.rs Script transformation plugin
style_plugin.rs Style block processing (scoped CSS, CSS modules)
template_plugin.rs Template compilation plugin
template/
element.rs Element open/close processing
directives.rs Directive compilation (v-if, v-for, v-slot, v-on, v-bind, ...)
interpolation.rs Template interpolation ({{ expr }})
types.rs TemplateCodegenState, BindingMetadata, patch flags
macros/
props.rs defineProps compilation
emits.rs defineEmits compilation
model.rs defineModel compilation
slots.rs defineSlots compilation
expose.rs defineExpose compilation
options.rs defineOptions compilation
types.rs Macro-related types
syntax/
syntax.rs Syntax pipeline runner
plugin.rs SyntaxPlugin trait, SyntaxPluginContext
plugins/
oxc_parser/ JavaScript/TypeScript parsing via OXC
css_parser/ CSS parsing via LightningCSS (scoped styles, modules)
analysis/ Scope analysis, binding tracking
ast_vue/ Vue-specific AST types
block_extractor.rs SFC block extraction
tokenizer/ Lexical analysis (byte-level tokenizer)
cursor/ Position tracking, UTF-8/UTF-16 offset resolution
code_transform/ Source map generation and code transformation
analysis/ Semantic analysis
common/ Shared utilities
utils/ General utilities, OXC helpers
API
generate(input, options, allocator) -> CodegenResult
Main compilation entry point. Compiles a Vue SFC string into JavaScript with source maps.
use oxc_allocator::Allocator;
use verter_core::builder::codegen::{generate, CodegenOptions, CodegenResult};
let allocator = Allocator::new();
let options = CodegenOptions {
filename: Some("App.vue".to_string()),
include_source_content: true,
ssr: false,
is_production: false,
component_id: None,
features: Default::default(),
};
let result: CodegenResult = generate(input, &options, &allocator);
// result.code -- compiled JavaScript
// result.source_map -- source map as JSON string
// result.code_with_source_map -- code with inline base64 source map
generate_for_vite(input, options, allocator) -> ViteCodegenResult
Vite-optimized compilation that returns split blocks for virtual module serving.
use verter_core::builder::codegen::{generate_for_vite, ViteCodegenOptions, ViteCodegenResult};
let result: ViteCodegenResult = generate_for_vite(input, &options, &allocator);
// result.script -- Option<BlockOutput> (component definition)
// result.template -- Option<BlockOutput> (render function)
// result.styles -- Vec<StyleBlock> (processed CSS)
// result.duration_ms -- compilation time
Key Types
| Type | Description |
|---|---|
CodegenOptions |
Compilation configuration (filename, SSR, production, features) |
FeatureFlags |
options_api, props_destructure |
CodegenResult |
Output: code, source_map, code_with_source_map |
ViteCodegenOptions |
Vite-specific options (filename, SSR, production, sourcemap) |
ViteCodegenResult |
Split blocks: script, template, styles, duration_ms |
BlockOutput |
Per-block output: code, source_map, imports, body_start |
TemplateCodegenState |
Internal state for template code generation |
BindingMetadata |
Tracks variable scopes for template expression resolution |
Key Design Patterns
- "Store in open, emit in close" -- Element processing collects data during the opening tag and emits code during the closing tag, enabling proper nesting
- OXC allocator per call -- A fresh
oxc_allocator::Allocatoris created for each compilation. The allocator manages memory for the OXC AST and must not cross FFI boundaries - SHA-256 component IDs -- Component IDs are derived from the filename via SHA-256, using the first 4 bytes (8 hex characters)
- Plugin-based pipeline -- Each compilation stage (
SyntaxPlugin) is composable and independently testable - Import extraction -- Generated code imports are parsed and tracked for Vite virtual module splitting
Development
Build
cargo build --package verter_core
cargo build --package verter_core --release
Examples
cargo run --package verter_core --example codegen
cargo run --package verter_core --example ast
cargo run --package verter_core --example check
cargo run --package verter_core --example expression_validator
Testing
# Run all tests
cargo test --package verter_core --verbose
# Run a specific test
cargo test --package verter_core test_name
# Run with truncated output (useful for large test suites)
cargo test --package verter_core 2>&1 | tail -60
Test Patterns
gen_and_validate()-- All codegen tests MUST validate generated JavaScript syntax via the OXC parser. This ensures the output is syntactically valid.- AST comparison -- End-to-end tests compare output against Vue's official compiler to verify behavioral equivalence.
- TDD workflow -- Write failing tests first, then implement the feature.
Benchmarks
4 benchmark suites are available using Criterion:
| Benchmark | Focus |
|---|---|
bindings_bench |
Binding metadata extraction |
vfor_bench |
v-for directive compilation |
vslot_bench |
v-slot directive compilation |
cargo bench --package verter_core
cargo bench --package verter_core --bench bindings_bench
Dependencies
| Crate | Purpose |
|---|---|
oxc_allocator, oxc_ast, oxc_parser, oxc_span, oxc_diagnostics |
JavaScript/TypeScript parsing (OXC toolchain) |
oxc_sourcemap |
Source map generation |
lightningcss |
CSS parsing, scoped styles, CSS modules |
serde, serde_json, serde_repr |
Serialization for options and results |
bumpalo |
Bump allocator for collections |
rustc-hash |
Fast hashing (FxHashMap/FxHashSet) |
smallvec |
Stack-allocated small vectors |
sha2, hex |
SHA-256 hashing for component IDs |
base64 |
Base64 encoding for inline source maps |
memchr |
Fast byte searching |
License
MIT
Dependencies
~21–28MB
~454K SLoC