Skip to main content
HTVG is a static compiler that converts JSON element trees to pure SVG with correct multiline text layout and flexbox support. This guide will get you from zero to working SVG output in just a few minutes.
1

Install HTVG

Choose your preferred environment:
npm install htvg
2

Initialize (JavaScript only)

If you’re using JavaScript, you need to initialize the WASM module before compilation:
import { init, compileDocument } from 'htvg';

// Auto-fetches the .wasm file
await init();
Rust users can skip this step - no initialization required!
3

Create your first SVG

Let’s create a simple “Hello World” document:
import { init, compileDocument } from 'htvg';

await init();

const result = compileDocument({
  meta: { width: 400 },
  content: {
    type: "flex",
    style: {
      width: 400,
      padding: 32,
      backgroundColor: "#ffffff",
      flexDirection: "column",
      gap: 12
    },
    children: [
      {
        type: "text",
        content: "Hello, HTVG!",
        style: {
          fontSize: 32,
          fontWeight: "bold",
          color: "#1a1a1a"
        }
      },
      {
        type: "text",
        content: "This is a self-contained document rendered to SVG.",
        style: {
          fontSize: 16,
          color: "#666666"
        }
      }
    ]
  }
});

console.log(result.svg);     // SVG string
console.log(result.width);   // 400
console.log(result.height);  // auto-computed
4

Build something more complex

Let’s create a card component with borders, rounded corners, and nested layouts:
{
  "meta": {
    "width": 360
  },
  "content": {
    "type": "flex",
    "style": {
      "width": 360,
      "padding": 24,
      "backgroundColor": "#f8f9fa",
      "flexDirection": "column",
      "gap": 16
    },
    "children": [
      {
        "type": "flex",
        "style": {
          "backgroundColor": "#ffffff",
          "borderRadius": 12,
          "borderWidth": 1,
          "borderColor": "#e0e0e0",
          "padding": 20,
          "flexDirection": "column",
          "gap": 8
        },
        "children": [
          {
            "type": "text",
            "content": "Card Title",
            "style": {
              "fontSize": 20,
              "fontWeight": 700,
              "color": "#1a1a1a"
            }
          },
          {
            "type": "text",
            "content": "This is a card component with a border, rounded corners, and some padding. It demonstrates nested flex containers.",
            "style": {
              "fontSize": 14,
              "color": "#555555",
              "lineHeight": 1.5
            }
          },
          {
            "type": "flex",
            "style": {
              "flexDirection": "row",
              "gap": 8,
              "padding": "12 0 0 0"
            },
            "children": [
              {
                "type": "box",
                "style": {
                  "width": 80,
                  "height": 32,
                  "backgroundColor": "#2563eb",
                  "borderRadius": 6
                }
              },
              {
                "type": "box",
                "style": {
                  "width": 80,
                  "height": 32,
                  "backgroundColor": "#e2e8f0",
                  "borderRadius": 6
                }
              }
            ]
          }
        ]
      }
    ]
  }
}
This example demonstrates:
  • Nested flex containers
  • Border and border-radius styling
  • Multi-value padding ("padding": "12 0 0 0")
  • Row and column layouts
  • Proper text wrapping with lineHeight
5

Use the two compilation modes

HTVG provides two ways to compile your documents:
Best for: Self-contained documents with metadata
const result = compileDocument({
  meta: { 
    width: 600,
    fonts: [
      { family: "Inter", url: "https://fonts.gstatic.com/..." }
    ]
  },
  content: {
    type: "text",
    content: "Hello",
    style: { fontSize: 32, fontFamily: "Inter" }
  }
});

Next Steps

Element Types

Learn about all available element types: box, flex, text, and image

Style Properties

Explore layout, flex, visual, and typography properties

API Reference

Complete API documentation for JavaScript and Rust

Examples

Browse real-world examples and templates

Common Patterns

Creating badges

{
  "type": "flex",
  "style": {
    "backgroundColor": "#22c55e",
    "borderRadius": 16,
    "padding": "6 14"
  },
  "children": [
    {
      "type": "text",
      "content": "Success",
      "style": { "fontSize": 13, "fontWeight": 600, "color": "#ffffff" }
    }
  ]
}

Responsive width

Use percentage strings for fluid layouts:
{
  "type": "box",
  "style": {
    "width": "100%",
    "padding": 20
  }
}

Custom fonts

const result = compileDocument({
  meta: {
    width: 400,
    fonts: [
      { family: "Geist", url: "https://example.com/geist.woff2" }
    ]
  },
  content: {
    type: "text",
    content: "Custom font text",
    style: { fontFamily: "Geist", fontSize: 18 }
  }
});
The height is automatically computed based on content unless explicitly specified in meta.height.

Build docs developers (and LLMs) love