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
  • serde serialization 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 JSON
  • parse_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.