Skip to main content

Quick Start

This guide will walk you through creating your first vector graphics with React ThorVG Fiber. We’ll cover both software rendering (SwCanvas) and hardware-accelerated rendering (GlCanvas).

Prerequisites

Make sure you have:
  1. Installed react-thorvg-fiber (Installation Guide)
  2. React 19 or later
  3. A bundler configured for WASM files (Vite, Webpack, Next.js, etc.)

Basic Concepts

Before we start, let’s understand the core concepts:
1

Canvas

Choose between SwCanvas (software rendering) or GlCanvas (WebGL rendering). The canvas is your drawing surface.
2

Shape

Shapes define visual appearance (fill color, stroke color, opacity, transforms). Every Shape needs geometry children.
3

Geometry

Geometry components (Rect, Circle, Path) define what to draw. They must be children of a Shape.
The component hierarchy is always: Canvas → Shape → Geometry

Your First Shape

Let’s create a simple blue circle using software rendering:
App.tsx
import { SwCanvas, Shape, Circle } from 'react-thorvg-fiber';

function App() {
  return (
    <SwCanvas width={400} height={400}>
      <Shape fill={[59, 130, 246, 255]}>
        <Circle x={200} y={200} radius={100} />
      </Shape>
    </SwCanvas>
  );
}

export default App;
Colors are defined as RGBA arrays: [red, green, blue, alpha] where each value is 0-255.

Understanding the Code

Let’s break down what each part does:
  1. SwCanvas: Creates a 400×400 software-rendered canvas
    • width and height are in CSS pixels
    • Automatically handles high-DPI displays
  2. Shape: Defines visual properties
    • fill={[59, 130, 246, 255]} sets a blue fill color (RGB: 59, 130, 246)
    • Can also have stroke, opacity, transforms, etc.
  3. Circle: Defines the geometry
    • x={200} y={200} sets the center position
    • radius={100} sets the circle size

Multiple Shapes

You can render multiple shapes by adding more Shape components:
import { SwCanvas, Shape, Rect, Circle } from 'react-thorvg-fiber';

function App() {
  return (
    <SwCanvas width={400} height={400}>
      {/* Blue rectangle */}
      <Shape fill={[59, 130, 246, 255]}>
        <Rect x={50} y={50} width={100} height={100} />
      </Shape>
      
      {/* Orange circle */}
      <Shape fill={[234, 88, 12, 255]}>
        <Circle x={300} y={150} radius={50} />
      </Shape>
      
      {/* Green rounded rectangle */}
      <Shape fill={[34, 197, 94, 255]}>
        <Rect x={200} y={250} width={100} height={100} rx={15} ry={15} />
      </Shape>
    </SwCanvas>
  );
}

Adding Strokes

Shapes can have both fill and stroke:
import { SwCanvas, Shape, Circle } from 'react-thorvg-fiber';

function App() {
  return (
    <SwCanvas width={400} height={400}>
      <Shape 
        fill={[255, 255, 255, 255]}      // White fill
        stroke={[59, 130, 246, 255]}      // Blue stroke
        strokeWidth={8}                   // 8px stroke width
      >
        <Circle x={200} y={200} radius={100} />
      </Shape>
    </SwCanvas>
  );
}

Drawing Paths

For custom shapes, use the Path component with path commands:
import { SwCanvas, Shape, Path, PathCommand } from 'react-thorvg-fiber';

function App() {
  return (
    <SwCanvas width={400} height={400}>
      <Shape 
        stroke={[234, 88, 12, 255]} 
        strokeWidth={8}
      >
        <Path
          commands={[
            PathCommand.MoveTo,   // Start at first point
            PathCommand.LineTo,   // Draw line to second point
          ]}
          points={[
            { x: 100, y: 100 },   // Start point
            { x: 300, y: 300 },   // End point
          ]}
        />
      </Shape>
    </SwCanvas>
  );
}

Using WebGL (GlCanvas)

For better performance with complex scenes, use GlCanvas for hardware-accelerated rendering:
import { GlCanvas, Shape, Circle } from 'react-thorvg-fiber';

function App() {
  return (
    <GlCanvas 
      id="my-canvas"           // Required: unique ID for WebGL context
      width={400} 
      height={400}
    >
      <Shape fill={[59, 130, 246, 255]}>
        <Circle x={200} y={200} radius={100} />
      </Shape>
    </GlCanvas>
  );
}
GlCanvas requires a unique id prop for the WebGL context to bind to the canvas element.

Setting Up WASM Files

In a real application with a bundler like Vite, you need to configure the WASM file location:
import { useCallback } from 'react';
import { SwCanvas, Shape, Circle } from 'react-thorvg-fiber';
// @ts-expect-error - WASM import
import wasmUrl from 'react-thorvg-fiber/thorvg-sw.wasm';

function App() {
  const locateFile = useCallback(() => wasmUrl, []);
  
  return (
    <SwCanvas 
      width={400} 
      height={400}
      locateFile={locateFile}
    >
      <Shape fill={[59, 130, 246, 255]}>
        <Circle x={200} y={200} radius={100} />
      </Shape>
    </SwCanvas>
  );
}

Complete Working Example

Here’s a complete example that works with Vite:
App.tsx
import { useCallback } from 'react';
import { SwCanvas, Shape, Rect, Circle } from 'react-thorvg-fiber';
// @ts-expect-error - WASM import
import wasmUrl from 'react-thorvg-fiber/thorvg-sw.wasm';

function App() {
  const locateFile = useCallback(() => wasmUrl, []);
  
  return (
    <div style={{ padding: '20px' }}>
      <h1>My First Vector Graphic</h1>
      <SwCanvas 
        width={400} 
        height={400}
        locateFile={locateFile}
        style={{ border: '1px solid #ccc' }}
      >
        {/* Blue square */}
        <Shape fill={[59, 130, 246, 255]}>
          <Rect x={50} y={50} width={100} height={100} />
        </Shape>
        
        {/* Orange circle with stroke */}
        <Shape 
          fill={[234, 88, 12, 255]}
          stroke={[255, 255, 255, 255]}
          strokeWidth={4}
        >
          <Circle x={300} y={100} radius={50} />
        </Shape>
        
        {/* Green rounded rectangle */}
        <Shape fill={[34, 197, 94, 255]}>
          <Rect x={150} y={250} width={100} height={100} rx={20} ry={20} />
        </Shape>
      </SwCanvas>
    </div>
  );
}

export default App;

High-DPI Support

For crisp rendering on high-DPI displays (Retina, 4K, etc.), use the devicePixelRatio prop:
<SwCanvas 
  width={400} 
  height={400}
  devicePixelRatio={window.devicePixelRatio}  // Automatic
  // or
  devicePixelRatio={2}  // Manual 2x scaling
>
  {/* shapes */}
</SwCanvas>
The canvas will automatically use window.devicePixelRatio if not specified.

SwCanvas vs GlCanvas

Choose the right canvas for your use case:
FeatureSwCanvasGlCanvas
RenderingCPU (Canvas 2D)GPU (WebGL)
PerformanceGood for simple scenesBetter for complex scenes
CompatibilityAll modern browsersRequires WebGL support
SetupSimplerRequires unique id prop
Use CaseSmall to medium graphicsLarge, complex animations
Start with SwCanvas for simplicity. Switch to GlCanvas if you notice performance issues with complex scenes.

Common Patterns

Reusable Shape Component

interface CircleShapeProps {
  x: number;
  y: number;
  radius: number;
  color: [number, number, number, number];
}

function CircleShape({ x, y, radius, color }: CircleShapeProps) {
  return (
    <Shape fill={color}>
      <Circle x={x} y={y} radius={radius} />
    </Shape>
  );
}

// Usage
<SwCanvas width={400} height={400}>
  <CircleShape x={100} y={100} radius={50} color={[59, 130, 246, 255]} />
  <CircleShape x={300} y={100} radius={50} color={[234, 88, 12, 255]} />
</SwCanvas>

Dynamic Content

function App() {
  const [radius, setRadius] = useState(50);
  
  return (
    <div>
      <input 
        type="range" 
        min="10" 
        max="150" 
        value={radius}
        onChange={(e) => setRadius(Number(e.target.value))}
      />
      <SwCanvas width={400} height={400}>
        <Shape fill={[59, 130, 246, 255]}>
          <Circle x={200} y={200} radius={radius} />
        </Shape>
      </SwCanvas>
    </div>
  );
}

Next Steps

Now that you’ve created your first graphics, explore more:

Canvas Types

Learn about SwCanvas and GlCanvas properties

Shapes Guide

Master fills, strokes, and transformations

Geometry Components

Explore Rect, Circle, and Path components

Examples

See more complex examples and patterns

Build docs developers (and LLMs) love