npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@reffy/infinite-canvas

v0.2.4

Published

An infinite canvas designed to be a minimal web component, serving as an image reference board.

Readme

Reffy Infinite Canvas

A TypeScript Web Component (<infinite-canvas>) that provides an infinite, GPU-accelerated canvas for placing and manipulating reference images. Built with Lit + WebGL, the canvas enables selection, context menu, history (undo/redo), and a default persistent storage (IndexedDB + LocalStorage).

  • Web Component: <infinite-canvas> renders a full-screen canvas and starts a render loop.
  • Engine: WebGL-backed renderer with Grid, Img, Rect shapes and z-ordering.
  • Interaction: Selection, flip, align, normalize, pointer/key/context menu managers.
  • Persistence: Auto-save and manual import/export to JSON; deduplicated image storage via hashing.
  • History: Composite commands push for undo/redo across interactions.

Live Demo Site: https://trash-lobster.github.io/reffy-infinite-canvas/

Installation

npm i reffy-infinite-canvas

Project Context

While working on a separate, but related project, I was making a lot of progress leveraging Excalidraw and enjoying the fact that I did not have to think or write my own implementation. However, Excalidraw, despite how fantastic it is, came coupled with a predetermined setup (toolbars and such) and a lot of functions that a pure image reference board would not need.

Thus, I made the challenging decision to try to write my own. Reffy Infinite Canvas aims to expose the APIs, enabling developers to customise their own canvas toolbars.

While not everything is customisable, it does offer more options than Excalidraw, achieving part of the initial goal.

Before you carry on to read the rest of the documentation (found in the documentation directory), I would like to credit that this project was heavily influenced by the following open-sourced projects:

They are both incredible resources and have sped up my own learning and I highly recommend browsing through their materials. I am still learning as I work on this project.

Additionally, I referenced PureRef for a lot of the available functions. In fact, as the project continued development, it became clear that I wanted to create a version of PureRef, but for the web.

Happy learning!

Image transformation

Available image transformations:

  • Flip
  • Normalize (by first selected and average)
  • Align
  • Scale
  • Move
  • Rotate (to be added)

Persistent storage

While there is a default set up for users to pick up and go, you can use the API to connect up a different source to write and read from.

Take a look at the code snippet below for an example set up.

// sample code
const el = document.querySelector('#canvas') as InfiniteCanvasElement;

InfiniteCanvasAPI.forElement(el).then(api => {

    const canvasStorage: CanvasStorage = { /** Add your custom canvas storage in here */ };

    const fileStorage: FileStorage = { /** Add your custom local storage for file here */ };

    el.assignCanvasStorage(canvasStorage);
    el.assignFileStorage(fileStorage);
};

The design for image storage is styled after Excalidraw. This means breaking the canvas data into two parts.

  • FileStorage is how we store the image data. In case of multiple copies of the same image, the storage is made more efficient by relying on hashing the image data as the file id, by which the canvas data uses to get the image data.
  • CanvasStorage is the layout of the canvas. This means camera position, keeping track of the images placed onto the canvas, their positions, and their transformation.

The canvas is reconstructed each time you load the canvas.

When setting up the canvasStorage, you can add the custom canvas storage and add a frequency, measured in ms. The default is 300000 ms (or, 5 minutes).