Skip to content

Getting Started

github-actions[bot] edited this page Mar 10, 2026 · 7 revisions

Getting Started

This guide walks you through installing FlexRender, creating your first template, and rendering it using code, dependency injection, or the CLI.

Want to try without installing? Use the browser playground -- edit YAML templates and see results instantly.

Installation

All-in-one (recommended)

The FlexRender meta-package includes all sub-packages:

dotnet add package FlexRender

Linux / Docker users: SkiaSharp requires native libraries. Add the native assets package to avoid DllNotFoundException: libSkiaSharp:

dotnet add package SkiaSharp.NativeAssets.Linux
# For minimal containers without fontconfig/freetype:
dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies
# For HarfBuzz text shaping (Arabic, Hebrew):
dotnet add package HarfBuzzSharp.NativeAssets.Linux

Individual packages

Install only what you need:

Package Description External Dependencies
FlexRender.Core Layout engine, template processing None
FlexRender.Yaml YAML template parser YamlDotNet
FlexRender.Skia.Render SkiaSharp renderer SkiaSharp
FlexRender.Skia Skia backend meta-package (renderer + providers) SkiaSharp
FlexRender.ImageSharp.Render Pure .NET renderer (no native deps) SixLabors.ImageSharp, SixLabors.Fonts, SixLabors.ImageSharp.Drawing
FlexRender.ImageSharp ImageSharp backend meta-package (renderer + providers) SixLabors.ImageSharp, SixLabors.Fonts, SixLabors.ImageSharp.Drawing
FlexRender.Svg.Render SVG output renderer None
FlexRender.Svg SVG backend meta-package (renderer + providers) None
FlexRender.QrCode.Skia.Render QR codes for Skia QRCoder
FlexRender.QrCode.Svg.Render QR codes for SVG QRCoder
FlexRender.QrCode.ImageSharp.Render QR codes for ImageSharp QRCoder
FlexRender.QrCode QR meta-package (all renderers) QRCoder
FlexRender.Barcode.Skia.Render Barcodes for Skia None
FlexRender.Barcode.Svg.Render Barcodes for SVG None
FlexRender.Barcode.ImageSharp.Render Barcodes for ImageSharp None
FlexRender.Barcode Barcode meta-package (all renderers) None
FlexRender.SvgElement.Skia.Render SVG elements for Skia Svg.Skia
FlexRender.SvgElement.Svg.Render SVG elements for SVG output None
FlexRender.SvgElement SvgElement meta-package (all renderers) Svg.Skia
FlexRender.Content.Markdown Markdown content parsing for type: content Markdig
FlexRender.Content.Html HTML content parsing for type: content HtmlAgilityPack
FlexRender.Content.Ndc NDC (ATM receipt) content parsing for type: content (none)
FlexRender.HarfBuzz HarfBuzz text shaping for Arabic/Hebrew SkiaSharp.HarfBuzz
FlexRender.Http HTTP/HTTPS resource loading None
FlexRender.DependencyInjection Microsoft DI integration Microsoft.Extensions.DI
# Example: core + YAML parser + Skia renderer
dotnet add package FlexRender.Core
dotnet add package FlexRender.Yaml
dotnet add package FlexRender.Skia.Render

CLI tool

dotnet tool install -g flexrender-cli

See CLI-Reference for full CLI documentation.

Your First Template

Create a file hello.yaml:

template:
  name: "hello"
  version: 1
  # culture: "ru-RU"          # Optional: culture for number/date formatting

canvas:
  fixed: width
  width: 300
  background: "#ffffff"

layout:
  - type: flex
    padding: 20
    gap: 10
    children:
      - type: text
        content: "Hello, {{name}}!"
        size: 1.5em
        align: center
        color: "#1a1a1a"

      - type: text
        content: "Welcome to FlexRender"
        size: 0.9em
        align: center
        color: "#666666"

Three Rendering Approaches

1. Code (FlexRenderBuilder)

using FlexRender;
using FlexRender.Configuration;
using FlexRender.Yaml;

// Build renderer with Skia backend (full features)
var render = new FlexRenderBuilder()
    .WithBasePath("./templates")
    .WithSkia(skia => skia
        .WithQr()
        .WithBarcode())
    .Build();

// Prepare data
var data = new ObjectValue
{
    ["name"] = "World"
};

// Render to PNG bytes (extension method from FlexRender.Yaml)
byte[] png = await render.RenderFile("hello.yaml", data);
await File.WriteAllBytesAsync("hello.png", png);

Alternative: ImageSharp backend (pure .NET, no native deps):

var render = new FlexRenderBuilder()
    .WithBasePath("./templates")
    .WithImageSharp(imageSharp => imageSharp.WithQr().WithBarcode())
    .Build();

byte[] png = await render.RenderFile("hello.yaml", data);

Note: ImageSharp supports QR codes and barcodes via FlexRender.QrCode.ImageSharp.Render and FlexRender.Barcode.ImageSharp.Render. SVG elements are not supported in ImageSharp.

2. Dependency Injection

// Program.cs -- register IFlexRender as singleton
services.AddFlexRender(builder => builder
    .WithBasePath("/app/templates")
    .WithSkia(skia => skia
        .WithQr()
        .WithBarcode()));

// In your service -- inject IFlexRender
public class GreetingService(IFlexRender render)
{
    public async Task<byte[]> GenerateGreeting(string name)
    {
        var data = new ObjectValue { ["name"] = name };
        return await render.RenderFile("hello.yaml", data);
    }
}

With service provider access for configuration:

services.AddFlexRender((sp, builder) =>
{
    var config = sp.GetRequiredService<IConfiguration>();
    builder
        .WithBasePath(config["FlexRender:BasePath"] ?? "./templates")
        .WithSkia(skia => skia.WithQr().WithBarcode());
});

3. CLI

# Render template to PNG
flexrender render hello.yaml -d data.json -o hello.png

# Watch mode -- auto re-render on file changes
flexrender watch hello.yaml -d data.json -o preview.png

Renderer Configuration

FlexRender supports three rendering backends. Choose based on your deployment environment and requirements.

Skia Backend

Native rendering via SkiaSharp. Best quality, widest feature set.

var render = new FlexRenderBuilder()
    .WithMarkdown()      // Markdown content parsing
    .WithHtml()          // HTML content parsing
    .WithNdc()           // NDC ATM receipt parsing
    .WithSkia(skia => skia
        .WithQr()        // QR code support
        .WithBarcode()   // Barcode support
        .WithSvgElement()) // Inline SVG elements
    .Build();
  • Formats: PNG, JPEG, BMP, Raw
  • Requires: SkiaSharp.NativeAssets.Linux on Linux/Docker
  • Optional: .WithHarfBuzz() for Arabic/Hebrew text shaping, .WithMarkdown() / .WithHtml() / .WithNdc() for content parsing
  • Best for: Desktop apps, servers with native library support

ImageSharp Backend

Pure .NET rendering — zero native dependencies.

var render = new FlexRenderBuilder()
    .WithImageSharp(imageSharp => imageSharp
        .WithQr()        // QR code support
        .WithBarcode())  // Barcode support
    .Build();
  • Formats: PNG, JPEG, BMP, Raw
  • No native dependencies — pure managed .NET
  • Best for: Containers, serverless, ARM platforms, environments where SkiaSharp is unavailable
  • Limitations: No SVG element support, no HarfBuzz text shaping

SVG Backend

Vector SVG output with optional raster fallback.

// SVG-only (vector output, no native dependencies)
var render = new FlexRenderBuilder()
    .WithSvg(svg => svg
        .WithQrSvg()           // Vector QR codes
        .WithBarcodeSvg()      // Vector barcodes
        .WithSvgElementSvg())  // Inline SVG elements
    .Build();
// SVG + Skia raster fallback (also supports PNG/JPEG)
var render = new FlexRenderBuilder()
    .WithSvg(svg => svg
        .WithQrSvg()
        .WithBarcodeSvg()
        .WithSkia(skia => skia
            .WithQr()
            .WithBarcode()))
    .Build();
  • SVG output: Scalable vector graphics, smallest file size
  • SVG-native providers: QR codes and barcodes rendered as <path> elements
  • Optional raster backend: Add .WithSkia() for PNG/JPEG output alongside SVG
  • Best for: Web, print, documents where vector graphics are preferred

Renderer Comparison

See the showcase-capabilities template for a side-by-side comparison of all three backends rendering the same template. Pre-rendered outputs:

Output Formats

FlexRender supports four output formats, each with per-call options:

Format Extension Description Options
PNG .png Lossless compression, transparency CompressionLevel (0-100)
JPEG .jpg Lossy compression, smaller files Quality (1-100)
BMP .bmp Uncompressed bitmap, 6 color modes ColorMode
Raw .raw Raw BGRA pixel data (4 bytes/pixel) --

Format-specific rendering

Use the new format-specific methods for full control over encoding options:

// Default PNG
byte[] png = await render.RenderToPng(template, data);

// JPEG with custom quality
byte[] jpeg = await render.RenderToJpeg(template, data,
    new JpegOptions { Quality = 75 });

// BMP monochrome for thermal printer
byte[] bmp = await render.RenderToBmp(template, data,
    new BmpOptions { ColorMode = BmpColorMode.Monochrome1 },
    new RenderOptions { Antialiasing = false });

// Raw BGRA pixel data
byte[] raw = await render.RenderToRaw(template, data);

// With culture-specific formatting (e.g., Russian number/date formatting)
byte[] localized = await render.RenderToPng(template, data,
    renderOptions: new RenderOptions { Culture = new CultureInfo("ru-RU") });

Convenience extension methods from FlexRender.Yaml:

byte[] png = await render.RenderFileToPng("template.yaml", data);
byte[] jpeg = await render.RenderFileToJpeg("template.yaml", data,
    new JpegOptions { Quality = 85 });

See Render-Options for detailed format and rendering options.

Legacy format parameter (still works)

byte[] png = await render.RenderFile("template.yaml", data, ImageFormat.Png);
byte[] jpeg = await render.RenderFile("template.yaml", data, ImageFormat.Jpeg);

Template Caching

For high-throughput scenarios, parse templates once and render many times:

// Parse once (at startup)
var parser = new TemplateParser();
_templates["receipt"] = await parser.ParseFileAsync("receipt.yaml");

// Render many times (per request)
byte[] png = await render.Render(_templates["receipt"], data);

Template caching works because type: each and type: if elements are expanded at render time, not parse time. The same parsed template can be rendered with different data.

Sandboxed Mode

For environments where file system access should be restricted:

var render = new FlexRenderBuilder()
    .WithoutDefaultLoaders()                      // Remove file and base64 loaders
    .WithEmbeddedLoader(typeof(Program).Assembly)  // Only embedded resources
    .WithSkia()
    .Build();

Claude Code Integration

Install the FlexRender plugin to get AI-assisted template authoring, live preview, and CLI management:

# Add the marketplace (one-time)
claude plugin marketplace add https://github.com/RoboNET/FlexRender-Marketplace

# Install the plugin
claude plugin install flexrender@FlexRender-Marketplace

The plugin provides three skills:

  • template -- create, edit, debug YAML templates with live watch preview
  • template-csharp -- C# AST integration, NuGet package selection, builder API
  • content-formats -- Markdown, HTML, and NDC content parser reference

The CLI (flexrender) is automatically installed on first session start.

Next Steps

Clone this wiki locally