blade-parser-rs
April 4, 2026 ยท View on GitHub
A small Rust parser for Laravel Blade templates.
It can lex Blade source into tokens, parse it into an AST, and optionally return recoverable diagnostics for malformed input.
The public AST, tokens, and diagnostics also implement serde::Serialize, which makes it easy to export parser output as JSON.
There is also an optional WASM export for browser-based AST tooling.
What it supports
- HTML fragments
- Blade echoes:
{{ }},{!! !!},{{{ }}} - Blade comments:
{{-- --}} - Blade directives such as
@if,@else, and@endif - PHP blocks
- Blade components, dynamic components, slots, and component attributes
- Source spans with line, column, and byte offsets
serdeserialization for AST nodes, tokens, and diagnostics
Usage
Add the crate to your project, then parse a template:
use blade_parser_rs::{parse, ParseMode};
fn main() {
let template = r#"
<x-alert>
Hello, {{ $name }}
</x-alert>
"#;
let document = parse(template, ParseMode::Default).into_document();
println!("nodes: {}", document.nodes.len());
}
If you want diagnostics as well:
use blade_parser_rs::{parse, ParseMode};
let result = parse("{{ $name ", ParseMode::Tolerant).into_result();
println!("nodes: {}", result.document.nodes.len());
println!("diagnostics: {}", result.diagnostics.len());
JSON output
Because the parser output implements serde::Serialize, you can serialize it directly with serde_json:
use blade_parser_rs::{parse, ParseMode};
let document = parse("<x-alert>{{ $name }}</x-alert>", ParseMode::Default).into_document();
let json = serde_json::to_string_pretty(&document).unwrap();
println!("{json}");
WASM export
Enable the wasm feature when you build for wasm32-unknown-unknown:
cargo build --target wasm32-unknown-unknown --features wasm
The crate exports two wasm-bindgen functions:
parse_to_json(template)returns the default parse output as JSONparse_to_json_with_diagnostics(template)returns tolerant parse output, including diagnostics, as JSON
Example browser-facing usage:
use blade_parser_rs::parse_to_json;
let json = parse_to_json("<x-alert>{{ $name }}</x-alert>")?;
Development
cargo test
cargo bench
src/main.rs is currently an empty placeholder. The main API lives in src/lib.rs.