Show HN: Render-graph-based 2D graphics framework for the web

7 hours ago 1

A 2D graphics framework for learning and prototyping GPU pipelines.

License Status

Pins and Curves engine is an open-source 2D graphics framework that removes friction from GPU programming while preserving its mental model.

It sits halfway between WebGL and high-level creative coding frameworks, keeping GPU concepts visible (passes, resources, dependencies) whilst automating the tedious setup.

  • For beginners: learn graphics pipelines and GPU resource flow without the boilerplate of raw WebGL
  • For professionals: prototype rapidly, author graphics pipelines in a high-level serializable format

This project is in its very early stages of development. It started as the render engine behind Pins and Curves, a motion design editor. I'd love for it to evolve into a shared open-source effort (likely under a new name). If you'd like to get involved during this formative period, please contact me at [email protected]

Example: Default Triangle

function defaultTriangle(height: number) { const triangle = Vertices( { attributes: { pos: 'vec2', uv: 'vec2', } }, { triangleCount: 1, vertices: () => ([ { pos: [-1,-1], uv: [0,0] }, { pos: [0,height], uv: [0,1] }, { pos: [1,-1], uv: [1,0] } ]), indices: () => ([0, 1, 2,]) }, [height] ); const outputTexture = Texture( { width: 1920, height: 1080, }, [ DrawOp( triangle, () => ` out vec2 v_uv; void main() { gl_Position = vec4(pos,0.,1.); v_uv = uv; } `, () => ` in vec2 v_uv; void main() { outColor = vec4(v_uv, 1.0, 1.0); }` ) ], [] ); return { triangle, outputTexture }; } gfx.update(defaultTriangle(1));

The above code produces the following output (RenderGraph to the left, the actual rendered image to the right): A graph depicting the triangle example

  • RenderGraph API
    Author your GPU pipeline as a function that returns a RenderGraph, a graph consisting of Textures, Vertex-, Instance-, and Uniformbuffers. Draw calls are attached directly to Textures, providing a simple model to work with.

  • Reactive Authoring Model
    The function you write is pure & reactive: Each invokation produces a new RenderGraph. Borrowing ideas from modern front-end frameworks, the engine diffs successive graphs and reevaluates only what's changed.

  • Virtualized Resources
    The backend maps the logical resources to GPU memory, reusing allocations where possible through texture-memory aliasing.

  • Composable Pipelines
    Offer and import partial RenderGraphs as plugins, enabling composable pipelines and reusable effects.

  • Serializable Format
    RenderGraphs can be serialized and streamed, enabling server-side generation or networked composition of pipelines.

  • Multiple Backends (planned)
    Currently, only WebGL2 is supported. I plan to support WebGPU in the future.

Play with some examples here:

screen recording of playground

MIT © 2025 Martin Trifonov

This project draws inspiration from modern render-graph architectures in real-time graphics engines, reimagined for the web. In particular, Yuriy O'Donell's talk "FrameGraph: Extensible Rendering Architecture in Frostbite" was an important inspiration.

Read Entire Article