Skip to content

Benchmark Results

Performance comparison of STX framework components against popular competitors in the ecosystem.

System: Apple M3 Pro (~3.8 GHz) Runtime: Bun v1.3.1 (arm64-darwin) Date: January 2025 Benchmark Tools: Mitata v1.0.34 (templating), TinyBench v5.0.1 (parsing/sanitization)


Executive Summary

Template Engine Performance

  • Pug: Fastest for simple templates (pre-compiled, 92ns)
  • Handlebars: Fastest for complex templates (3.85µs)
  • @stacksjs/stx: Laravel Blade syntax with comprehensive directives (26.83µs simple, 167.41µs complex)
  • Trade-off: Rich features vs. raw speed

Framework Performance

  • STX: 0.57ms geometric mean
  • 44.1% faster than VanillaJS overall
  • Winner in 8 of 9 operations
  • Industry-leading optimization

Markdown Parsing

  • 2.89x faster than markdown-it on small documents
  • 1.96x faster on medium documents
  • 1.45x faster on large documents

HTML Sanitization

  • Fastest in all categories
  • 77.93x faster than DOMPurify
  • 1.70-1.99x faster than other competitors

YAML Parsing

  • 1.5-2.7x faster than js-yaml
  • Native Bun implementation

Template Engine Performance

Simple Template Rendering

EngineAvg Time/IterationRelative to Fastest
Pug92.12 nsBaseline (fastest)
Nunjucks398.25 ns4.3x slower
Handlebars783.46 ns8.5x slower
EJS991.16 ns10.8x slower
Liquid8.79 µs95x slower
@stacksjs/stx26.83 µs291x slower

Test: Simple template with variables, single conditional, basic HTML structure.

Complex Template Rendering

EngineAvg Time/IterationRelative to Fastest
Handlebars3.85 µsBaseline (fastest)
EJS7.48 µs1.9x slower
@stacksjs/stx167.41 µs43.5x slower

Test: Complex template with nested loops, multiple conditionals, array iteration, nested data structures (e-commerce product listing with user info, navigation, products, testimonials).

Analysis

Pre-compiled Engines Excel:

  • Pug (92ns) and Handlebars (783ns-3.85µs) dominate with aggressive pre-compilation
  • EJS maintains good performance with simple pre-compilation
  • These engines sacrifice runtime flexibility for speed

STX's Feature-Rich Approach:

  • Laravel Blade syntax compatibility
  • Comprehensive directive system: @foreach, @if, @include, @component, @extends, @section, @push, @stack, @csrf, @method, @auth, @env, @isset, @empty, etc.
  • Runtime flexibility with dynamic includes and components
  • Server-side rendering optimization on Bun
  • Template caching (enabled in production)
  • Streaming SSR support

Performance in Context:

  • Simple template: 26.83µs = 0.027 milliseconds
  • Complex template: 167.41µs = 0.167 milliseconds
  • For 60 FPS (16.67ms budget), you can render ~99 complex templates per frame
  • Excellent for real-world web applications

When to Choose:

Choose pre-compiled engines (Pug, Handlebars, EJS) when:

  • Rendering millions of simple templates per second
  • Every microsecond counts
  • Pre-compilation fits your workflow
  • Minimal syntax requirements

Choose STX when:

  • Building Bun-powered server-side applications
  • Need Laravel Blade syntax familiarity
  • Want comprehensive directive system
  • Development velocity matters
  • Need runtime flexibility (dynamic includes, components)
  • 0.1-0.2ms render time is acceptable

Framework Performance

Benchmark: Industry-standard js-framework-benchmark comparing STX against Vue, React, Svelte, Solid, and VanillaJS.

Results

  • STX: 0.57ms geometric mean
  • VanillaJS: 1.02ms geometric mean
  • Performance: 44.1% faster than VanillaJS
  • Wins: Faster than VanillaJS in 8 of 9 operations

Key Optimizations

  1. WeakMap for ID Management: Fast element tracking
  2. Template Cloning Strategy: Efficient DOM updates
  3. innerHTML Hybrid Approach: Optimal rendering path
  4. Optimized RNG: Fast randomization

See packages/benchmarks/js-framework-benchmark/OPTIMIZATION_HISTORY.md for the complete optimization journey.


Markdown Parsing Performance

Results by Document Size

Benchmark@stacksjs/markdownmarkdown-itmarkedshowdown
Small (< 1KB)324B ops/sec112B ops/sec26B ops/sec14B ops/sec
Medium (~3KB)34.7B ops/sec17.7B ops/sec2.8B ops/sec2.8B ops/sec
Large (~50KB)1.81B ops/sec1.25B ops/sec16M ops/sec135M ops/sec

Performance vs markdown-it

  • Small documents: 2.89x faster
  • Medium documents: 1.96x faster
  • Large documents: 1.45x faster

Architecture

  • Flat token stream: Minimal memory allocation
  • Position-based parsing: No string slicing overhead
  • Optimized string handling: Bun-native performance
  • Consistent performance: Scales well across all document sizes

Features

  • GitHub Flavored Markdown (GFM)
  • Tables, task lists, strikethrough
  • Header ID generation
  • Syntax highlighting support
  • Frontmatter parsing (YAML, TOML, JSON)
  • Bun-native implementation

HTML Sanitization Performance

Safe HTML (no XSS)

Libraryops/secRelative Performance
@stacksjs/sanitizer180.2B ops/secFastest
xss105.8B ops/sec1.70x slower
sanitize-html99.5B ops/sec1.81x slower
DOMPurify2.3B ops/sec77.93x slower

Dangerous HTML (with XSS attempts)

Libraryops/secRelative Performance
@stacksjs/sanitizer173.3B ops/secFastest
sanitize-html87.1B ops/sec1.99x slower
xss78.9B ops/sec2.20x slower
DOMPurify1.1B ops/sec164.96x slower

Large HTML (~15KB, 100 articles)

Libraryops/secRelative Performance
@stacksjs/sanitizer2.1B ops/secFastest
sanitize-html1.1B ops/sec1.87x slower
xss1.1B ops/sec1.95x slower
DOMPurify59M ops/sec35.86x slower

Features

  • XSS protection
  • Configurable allowed tags and attributes
  • Multiple security presets (strict, basic, markdown, relaxed)
  • URL scheme validation
  • Data URI support
  • DOMPurify-compatible API
  • Bun-optimized performance

YAML Parsing Performance

Standard YAML (~1KB)

Libraryops/secRelative Performance
@stacksjs/markdown (Bun)94.7B ops/secBaseline
js-yaml62.5B ops/sec1.52x slower

Large YAML (500 objects, ~20KB)

Libraryops/secRelative Performance
@stacksjs/markdown (Bun)887.8M ops/secBaseline
js-yaml566.3M ops/sec1.57x slower

YAML Stringify (500 objects)

Libraryops/secRelative Performance
@stacksjs/markdown (Bun)945.9M ops/secBaseline
js-yaml349.6M ops/sec2.71x slower

Benefits

  • Native Bun YAML implementation
  • 1.5-2.7x faster than js-yaml
  • Excellent for configuration files
  • Built-in frontmatter support

Frontmatter Parsing Performance

Standard Frontmatter (15 fields)

Libraryops/secRelative Performance
gray-matter2,188.3B ops/secFastest
@stacksjs/markdown217.5B ops/sec10.06x slower

Large Frontmatter (100+ fields)

Libraryops/secRelative Performance
gray-matter1,295.6B ops/secFastest
@stacksjs/markdown10.8B ops/sec119.48x slower

Notes

  • gray-matter is highly optimized for frontmatter-specific parsing
  • @stacksjs/markdown still processes 217 billion operations per second
  • For most use cases, this is more than sufficient
  • Trade-off: Unified API (markdown + frontmatter + YAML) vs. specialized performance

Running Benchmarks

bash
# All benchmarks
cd packages/benchmarks
bun run bench:all

# Individual benchmarks
bun run bench:templating    # Template engine comparison (Mitata)
bun run bench:markdown      # Markdown parsing
bun run bench:frontmatter   # Frontmatter parsing
bun run bench:yaml          # YAML parsing
bun run bench:sanitizer     # HTML sanitization
bun run bench:js-framework  # JS framework comparison

Benchmark Methodology

Tools

  • Mitata v1.0.34: Template engine benchmarks with statistical analysis
  • TinyBench v5.0.1: Parsing and sanitization benchmarks

Environment

  • CPU: Apple M3 Pro (~3.8 GHz)
  • Runtime: Bun v1.3.1 (arm64-darwin)
  • Duration: 1000ms per benchmark
  • Warmup: Automatic for Mitata, disabled for TinyBench (cold start)
  • Iterations: Multiple (determined by framework)

Test Data

All benchmarks use realistic test data:

  • Templates: Real-world HTML structures with variables, loops, conditionals
  • Markdown: Actual documents from small (< 1KB) to large (50KB+)
  • HTML: Safe and dangerous HTML with XSS attempts
  • YAML: Configuration-style data structures

Key Takeaways

Strengths

  1. Framework Performance: 44.1% faster than VanillaJS - industry-leading
  2. HTML Sanitization: Fastest in all categories, up to 77x faster
  3. Markdown Parsing: 1.4-2.9x faster than markdown-it
  4. YAML Parsing: 1.5-2.7x faster than js-yaml
  5. Template Engine: Feature-rich with excellent real-world performance

Trade-offs

  1. Template Rendering: Slower than pre-compiled alternatives

    • Rich directive processing adds overhead
    • Still excellent for real-world apps (sub-millisecond)
    • Enable caching and streaming for optimal performance
  2. Frontmatter Parsing: gray-matter is highly specialized

    • Still fast enough for most use cases (217B ops/sec)
    • Trade-off: unified API vs. specialized performance

Recommendations

Use STX when:

  • Building Bun-powered applications
  • Need Laravel Blade syntax familiarity
  • Want comprehensive features and directives
  • Sub-millisecond performance is acceptable
  • Development velocity matters

Use pre-compiled engines when:

  • Every microsecond counts
  • Rendering millions of templates per second
  • Pre-compilation fits your workflow
  • Minimal feature requirements

Conclusion

STX provides a comprehensive, high-performance solution for building modern web applications on Bun:

  • Template Engine: Laravel Blade syntax with rich directives - excellent for SSR
  • Framework: 44% faster than VanillaJS - industry-leading
  • Markdown/Sanitization: Fastest in class - up to 77x better
  • Developer Experience: Familiar syntax, powerful features

While raw template rendering is slower than pre-compiled alternatives, STX delivers the best balance of features, performance, and developer experience for Bun-powered applications.

Performance Philosophy: We prioritize real-world application performance over synthetic microbenchmarks. The goal is fast, maintainable, and enjoyable development with excellent end-user experience.


Next Steps

Released under the MIT License.