Skip to main content

Vello: GPU-Accelerated 2D Vector Graphics for Python

PyPI version License Python

Vello is a high-performance, GPU compute-centric 2D vector graphics engine for Python, powered by Linebender's Vello and wgpu.

Unlike traditional CPU renderers (like Cairo or CPU Skia) or traditional GPU renderers that rely on tessellation, Vello utilizes modern GPU Compute Shaders to perform sorting, path clipping, and antialiased rasterization in parallel on your graphics card.


✨ Features

  • ⚡ Pure GPU Compute Acceleration: Path flattening, clipping, and rasterization run completely on GPU Compute Shaders.
  • 🎨 Pythonic Canvas API: An intuitive, HTML5 Canvas-like API designed specifically for Python developers.
  • 🚀 Zero-Copy NumPy Integration: Stream rendered frames directly into NumPy (H, W, 4) uint8 arrays without copying memory.
  • ⚡ Vectorized Batch Drawing: Render tens of thousands to millions of circles, rectangles, lines, and complex polygons in a single native GPU dispatch via NumPy arrays.
  • 🔺 Direct Polygon & Polyline Batches: Pass binary NumPy coordinate buffers directly to fill_polygons_batch, stroke_polygons_batch, and draw_polylines_batch with compound path optimization, eliminating SVG string parsing and scene buffer overhead.
  • 🎥 Direct GPU Video Streaming: Stream raw RGBA buffers directly to hardware-accelerated video encoders (NVENC H.264/HEVC or libx264) via vello.VideoWriter and Canvas.save_video(), eliminating OpenCV and PCIe bus bottlenecks.
  • 🌈 Rich Shading & Gradients: Full support for Solid Colors, Linear Gradients, Radial Gradients, Angular / Conical Sweep Gradients, and Image Brushes.
  • 🎬 Built-in Animation & Video Export: Generate smooth animated GIF sequences or hardware-encoded MP4 videos directly.
  • 📐 Vector Shapes & SVG Paths: Native support for Polygons, Polylines, Rectangles, Rounded Rectangles, Circles, Ellipses, Lines, Bézier Curves, and complete SVG path d="..." strings.
  • 🔤 GPU Vector Typography: High-quality TrueType/OpenType font rendering with exact subpixel glyph positioning.
  • 🎭 Compositing & Blend Modes: Full W3C blend modes (Multiply, Screen, Overlay, etc.) and compositing operations.
  • 💡 Gaussian Drop Shadows: Accelerated blurred rounded rectangles for realistic UI drop shadows.
  • 🧵 Non-blocking & Thread-Safe: Releases the Python GIL during GPU execution for multi-threaded performance.
  • 🐧 Linux & Cloud Ready: Fully supports headless Linux servers, Docker containers, and Cloud GPU environments with NVIDIA GPUs (T4, V100, A100, H100, RTX) via Vulkan.

📦 Installation

pip install vello

🚀 Quickstart

1. Basic Drawing & PNG Export

import vello

# Create canvas with background color
canvas = vello.Canvas(800, 600, background="white")

# Fill and stroke shapes with CSS colors, hex, or RGB tuples
canvas.fill_circle(cx=400, cy=300, radius=120, fill="royalblue")
canvas.stroke_circle(cx=400, cy=300, radius=120, stroke="crimson", stroke_width=6.0)

# Draw rounded rectangle with GPU drop shadow
canvas.draw_shadow(x=50, y=50, width=200, height=100, radius=16, blur=20, color="#00000044")
canvas.fill_rounded_rect(x=50, y=50, width=200, height=100, radius=16, fill="#2ecc71")

# Draw an SVG path
canvas.fill_path("M 500 100 L 550 200 L 450 200 Z", fill="gold")

# Save directly to image
canvas.save("output.png")

2. High-Performance NumPy & Video / Game Pipelines

import vello

canvas = vello.Canvas(1920, 1080, background="black")

# Draw vector elements
canvas.fill_circle(960, 540, 200, fill="coral")

# Get a NumPy array with zero-copy buffer mapping (shape: 1080, 1920, 4)
frame = canvas.to_numpy()
print(frame.shape, frame.dtype)  # (1080, 1920, 4) uint8

3. Linear & Radial Gradients

import vello

canvas = vello.Canvas(400, 400, background="black")

# Linear gradient
gradient = vello.LinearGradient(
    start=(0, 0),
    end=(400, 400),
    stops=[
        vello.ColorStop(0.0, vello.Color.from_name("red")),
        vello.ColorStop(0.5, vello.Color.from_name("yellow")),
        vello.ColorStop(1.0, vello.Color.from_name("blue")),
    ]
)
canvas.fill_rect(0, 0, 400, 400, fill=gradient)
canvas.save("gradient.png")

4. Transformations & Layer Blending

import vello

canvas = vello.Canvas(500, 500, background="white")

# Context manager for local coordinate transforms
with canvas.transform(translate=(250, 250), rotate_deg=45):
    canvas.fill_rect(-50, -50, 100, 100, fill="teal")

# Blending and opacity layers
with canvas.layer(alpha=0.8, blend_mode="multiply"):
    canvas.fill_circle(200, 200, 80, fill="cyan")
    canvas.fill_circle(260, 200, 80, fill="magenta")

canvas.save("layers.png")

5. Vector Typography

import vello

canvas = vello.Canvas(600, 200, background="white")

# Load any TrueType or OpenType font
font = vello.Font.from_file("C:/Windows/Fonts/arial.ttf")

# Measure text bounds
width, height = font.measure_text("Vello on GPU", size=36.0)

# Draw vector text
canvas.draw_text("Vello on GPU", x=50, y=100, font=font, size=36.0, color="royalblue")
canvas.save("text.png")

6. Vectorized Batch Drawing (NumPy)

Render tens of thousands of shapes simultaneously without Python loop overhead:

import vello
import numpy as np

canvas = vello.Canvas(1000, 1000, background="black")

# 50,000 random circles [x, y, radius]
n = 50_000
data = np.zeros((n, 3), dtype=np.float32)
data[:, 0] = np.random.uniform(0, 1000, n)
data[:, 1] = np.random.uniform(0, 1000, n)
data[:, 2] = np.random.uniform(1, 5, n)

# Single native GPU call!
canvas.fill_circles_batch(data, fill="#00ffcc88")

# Rectangles batch [x0, y0, x1, y1] and Lines batch [x0, y0, x1, y1]
# Combined into a single compound path to eliminate scene buffer fragmentation:
canvas.fill_rects_batch([[10, 10, 50, 50], [60, 10, 100, 50]], fill="teal")
canvas.draw_lines_batch([[0, 0, 1000, 1000], [0, 1000, 1000, 0]], stroke="gray", stroke_width=1.0)
canvas.save("batch_primitives.png")

7. Complex Polygons & Polyline Batches (Zero-Copy NumPy)

Avoid CPU string formatting and SVG parsing bottlenecks (d="M x y L x y Z") by feeding binary coordinate buffers directly from NumPy. All polygons are automatically merged into a single compound BezPath for maximal GPU encoding efficiency:

import vello
import numpy as np

canvas = vello.Canvas(1000, 1000, background="#111118")

# Draw an arbitrary individual polygon or open polyline:
pts = np.array([[200, 100], [350, 200], [300, 400], [150, 350]], dtype=np.float64)
canvas.fill_polygon(pts, fill="gold")
canvas.stroke_polygon(pts, stroke="white", stroke_width=2.0)

# Batch rendering: List of 2D NumPy polygon arrays (varying vertex counts)
tri = np.array([[50, 50], [90, 50], [70, 90]])
quad = np.array([[120, 50], [160, 50], [170, 90], [110, 80]])
poly = np.array([[200, 50], [240, 60], [250, 90], [220, 110], [190, 80]])

canvas.fill_polygons_batch([tri, quad, poly], fill="cyan")

# Batch rendering: Uniform polygons via 3D array (e.g., 10,000 triangles of shape (10000, 3, 2))
triangles = np.random.uniform(50, 950, size=(10_000, 3, 2))
canvas.fill_polygons_batch(triangles, fill="#ff336644")

# Batch polylines (open paths, contours, GIS tracks):
lines = [np.random.uniform(0, 1000, size=(20, 2)) for _ in range(500)]
canvas.draw_polylines_batch(lines, stroke="lime", stroke_width=1.5)

canvas.save("batch_polygons.png")

8. Direct Hardware-Accelerated Video Streaming (vello.VideoWriter)

When rendering high-resolution videos (1080p / 4K at 60 FPS), traditional approaches force you to read uncompressed frames across the PCIe bus into host RAM with canvas.to_numpy() and re-encode with OpenCV.

Vello provides a direct streaming pipeline that pipes raw GPU RGBA bytes straight into hardware-accelerated encoders (NVIDIA NVENC H.264/HEVC with automatic fallback to libx264):

import vello

WIDTH, HEIGHT, FPS = 1920, 1080, 60

# Option A: Pythonic context manager streaming directly to NVENC / FFmpeg:
with vello.VideoWriter("render.mp4", WIDTH, HEIGHT, fps=FPS, codec="auto") as video:
    for i in range(240):  # 4 seconds at 60 FPS
        canvas = vello.Canvas(WIDTH, HEIGHT, background="#0a0a14")
        canvas.fill_circle(960 + (i - 120) * 4, 540, 80, fill="deepskyblue")
        video.write(canvas)  # Direct GPU-to-pipe stream!

# Option B: Batch export an iterable of pre-rendered Canvases:
frames = [vello.Canvas(800, 600, background="black").fill_circle(100 + i * 5, 300, 40, fill="red") for i in range(60)]
vello.Canvas.save_video(frames, "output.mp4", fps=30)

9. Animation & GIF Export

import vello
import numpy as np

frames = []
for i in range(30):
    c = vello.Canvas(300, 300, background="black")
    angle = (i / 30.0) * 360.0
    with c.transform(translate=(150, 150), rotate_deg=angle):
        c.fill_rect(-40, -40, 80, 80, fill="cyan")
    frames.append(c)

# Save smooth animated GIF
vello.Canvas.save_animation(frames, "spin.gif", fps=30)

10. Headless Linux & Cloud GPU Setup (enable_vulkan_gpu)

In cloud container environments or headless Linux servers, NVIDIA drivers may not have Vulkan configured out of the box (defaulting to CPU software rendering).

Vello includes an automatic, one-line setup utility that detects your NVIDIA GPU and configures Vulkan acceleration automatically:

import vello

# Run once in your cloud notebook or script to enable 100% GPU acceleration:
vello.enable_vulkan_gpu()

# Verify active GPU hardware & physical limits:
gpu = vello.get_gpu_info()
print("Active GPU:", gpu["name"])           # e.g., 'Tesla T4' or 'RTX 4090'
print("Backend:", gpu["backend"])         # 'Vulkan'
print("Device Type:", gpu["device_type"]) # 'DiscreteGpu'
print("Max Buffer Binding:", gpu["max_storage_buffer_binding_size_mb"], "MB")

11. Millions of Vectors & GPU Buffer Scaling (gpu_buffer)

Vello automatically discovers and prioritizes your Discrete GPU (e.g. NVIDIA Tesla T4, RTX 3090/4090, AMD Radeon) over any integrated or software fallback adapters, maximizing the available hardware storage limits.

Furthermore, Vello features hardware-safe buffer clamping: it dynamically verifies your GPU's physical max_storage_buffer_binding_size so allocations never exceed your card's hardware capabilities.

By default, Vello allocates an ultra-safe 128 MB GPU bump allocator profile, ensuring smooth operation on low-power devices and integrated graphics.

When working with massive datasets (e.g. rendering 1,000,000+ vector shapes in 4K) on high-memory GPUs (such as an NVIDIA Tesla T4 with 16GB VRAM, RTX 3090/4090, or A100/H100), you can unlock large buffer capacities:

Per-Canvas Configuration:

import vello

# Allocate a high-capacity GPU bump buffer profile:
canvas = vello.Canvas(3840, 2160, background="#050510", gpu_buffer="2GB")

# Available profiles: "128MB" (default), "256MB", "512MB", "1GB", "2GB", "4GB"

Global Configuration (e.g. at the top of a Notebook):

import vello

# Check active buffer profile
print(vello.get_gpu_buffer())  # '128MB'

# Set high-capacity profile for all canvases
vello.set_gpu_buffer("2GB")

1,000,000 Vector Circles in 4K:

import vello
import numpy as np

WIDTH, HEIGHT = 3840, 2160
N = 1_000_000

# 1. Initialize canvas with 4GB buffer
canvas = vello.Canvas(WIDTH, HEIGHT, background="#050510", gpu_buffer="4GB")

# 2. Generate 1,000,000 vector circles
data = np.zeros((N, 3), dtype=np.float32, order='C')
data[:, 0] = np.random.uniform(50, WIDTH - 50, N)
data[:, 1] = np.random.uniform(50, HEIGHT - 50, N)
data[:, 2] = np.random.uniform(2.0, 5.0, N)

# 3. Render all 1,000,000 shapes directly on GPU
canvas.fill_circles_batch(data, fill="#00ffcc")
canvas.save("galaxy_1m_4k.png")

📊 Performance

Vello parallelizes vector rendering on GPU compute shaders:

  • Instant scene builds: Adding thousands of vector commands takes just a few milliseconds.
  • Fast GPU rendering: 1080p full frame renders take ~5-10 ms on standard GPUs (~120-200 FPS).
  • GIL-free execution: Multi-threaded Python applications run concurrently without blocking.

📜 License

Licensed under either of:

at your option.

Metadata

Release files for vello 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vello 0.1.5
File Size Uploaded
vello-0.1.5.tar.gz 32.7 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for vello 0.1.5
File
vello-0.1.5-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
vello-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-64 Details
vello-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details
vello-0.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.17+ x86-64 Details
vello-0.1.5-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
vello-0.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.17+ x86-64 Details

Total release size: 63.0 MB

Release files / vello-0.1.5.tar.gz

Download URL vello-0.1.5.tar.gz
Size 32.7 MB
Tags Source
SHA-256 checksum
How to use checksums
a23de449af3aeadb781f6f5de5be242d7d3bf2cd5100ca2bd1a63588ec7a3afd
BLAKE2b-256 checksum
How to use checksums
dbfef4b062d905ae3b1754835f14140d696f8a413634d0908c78bed0d772ecfb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / vello-0.1.5-cp313-cp313-win_amd64.whl

Download URL vello-0.1.5-cp313-cp313-win_amd64.whl
Size 7.8 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
1fee3775bf988ca5c40cbde4b6568a17ed0923a552198915d5c927c2397da2b1
BLAKE2b-256 checksum
How to use checksums
c7278c1c4283a6d4de5eb25ee8c700a3fc1113725731029857c99fca6cb4b96a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / vello-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL vello-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.7 MB
Tags CPython 3.13 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
8d89bc83e3e2dc5a60322f32919b58c51154c2754ca9535c7fdd71df09037c05
BLAKE2b-256 checksum
How to use checksums
022eccab2f5d5d02cefd346e573b3db6afa02fefc9c08324f0c84536122edb49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / vello-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL vello-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.7 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
acac8e091b4865573c3da5f66a4d8c5a3df3771430df056885abcd5a13b41357
BLAKE2b-256 checksum
How to use checksums
0f50c32b348fd448dd1448587e646e4d310ceb147c562127797df7b6b2885566
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / vello-0.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL vello-0.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.7 MB
Tags CPython 3.11 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
6a9e8b1606fb02c8909119c5d11820f379e58408173550ff797a85122299b842
BLAKE2b-256 checksum
How to use checksums
6fffd19d7f2f5705b70cbf0799b940e52fa4c0808eb66f4fdff8b7c22ae428a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / vello-0.1.5-cp310-cp310-win_amd64.whl

Download URL vello-0.1.5-cp310-cp310-win_amd64.whl
Size 7.8 MB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
448ad77b85a9793e2c87e63f70e4e865ba7795b18ca4b6570418dc59f9e99d36
BLAKE2b-256 checksum
How to use checksums
8ad7a2c072bfe4e27f4270c6637dfe594b64d79c5fa072a8089f08e7d534e4a2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / vello-0.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL vello-0.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.7 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
438ee38112b8cb2c6eed0a369e050381700e5968213e78283d7ded0eb66ce4ca
BLAKE2b-256 checksum
How to use checksums
d5df017eacbf427cafdef36c593666ab8b7d46aa1a78ca2baf3e7190e532789e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release history Release notifications | RSS feed

0.1.7

7 release files

0.1.6

7 release files

This release

0.1.5 This release

7 release files

0.1.4

7 release files

0.1.3

7 release files

0.1.2

7 release files

0.1.1

7 release files

0.1.0

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page