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

@compare-ui/figma

v0.1.0

Published

Figma resource resolver for design-comparison workflows.

Readme

@compare-ui/figma

Figma resource resolver for design-comparison workflows.

This package adds Figma as a supported image source by registering a resolver with @compare-ui/core.

Installation

pnpm add @compare-ui/figma

If you plan to author shared comparison config directly with core helpers, also install:

pnpm add @compare-ui/core

If you plan to execute comparison runs through the shared runner, also install:

pnpm add @compare-ui/runner

What it exports

Main public APIs:

  • createFigmaImageResourceResolver(...)
  • registerFigmaImageResourceResolver(...)
  • registerFigmaFromEnv(...)

Main public types:

  • FigmaUrlResourceDefinition
  • FigmaNodeResourceDefinition
  • FigmaImageResourceDefinition
  • FigmaCacheOptions
  • FigmaResolverOptions
  • RegisterFigmaFromEnvOptions

Published entrypoint:

  • @compare-ui/figma

That entrypoint is intended to resolve from the published build output, and the workspace verifies it through a tarball smoke test.

Figma resource type

This package adds a Figma-backed resource type to the core resource model.

type CropOffsets = {
  top?: number;
  right?: number;
  bottom?: number;
  left?: number;
};

type FigmaUrlResourceDefinition = {
  url: string;
  crop?: CropOffsets;
};

type FigmaNodeResourceDefinition = {
  fileKey: string;
  nodeId: string;
  format?: 'png';
  scale?: number;
  crop?: CropOffsets;
};

type FigmaImageResourceDefinition = FigmaUrlResourceDefinition | FigmaNodeResourceDefinition;

That allows configs to use either form.

Using a full Figma URL:

reference: {
  type: 'figma',
  url: 'https://figma.com/design/abc123/Example?node-id=2020-1617',
  crop: {
    bottom: 20
  }
}

Using fileKey and nodeId directly:

reference: {
  type: 'figma',
  fileKey: 'abc123',
  nodeId: '2020:1617',
  crop: {
    bottom: 20
  }
}

Choose the form that fits your workflow:

  • use url when you already have a copied Figma link
  • use fileKey and nodeId when those values already exist in your integration flow

The url form is intended for copied Figma design links that include a node-id query parameter.

How the figma type becomes available

This package handles the type registration for you.

When @compare-ui/figma is part of your project, it augments DesignComparisonResourceMap from @compare-ui/core, so TypeScript understands that type: 'figma' is a valid resource.

Conceptually, this package adds a type definition like this:

declare module '@compare-ui/core' {
  interface DesignComparisonResourceMap {
    figma: FigmaImageResourceDefinition;
  }
}

As a consumer of this package, you do not need to write that augmentation yourself.

TypeScript still needs to see the @compare-ui/figma module in your program. If your editor or build does not recognize type: 'figma' yet, add a type-loading import in a setup module that is already included by TypeScript:

import '@compare-ui/figma';

Common places for that import:

  • a shared test setup file
  • a types.ts module already included by the app
  • the same bootstrap module where you register the resolver

That import enables the type augmentation. Resolver registration is still a separate runtime step.

TypeScript setup

Use this two-step model when adding Figma resources:

  1. Make the type augmentation visible to TypeScript.
  2. Register the resolver at runtime.

Example:

import '@compare-ui/figma';
import { registerFigmaFromEnv } from '@compare-ui/figma';

registerFigmaFromEnv();

If the type-loading import is missing from the program, type: 'figma' may still fail to type-check even when the package is installed correctly.

This package owns that type-loading model. Other package docs may mirror the recipe, but they should not redefine it.

Registering the resolver

Register the resolver once during bootstrap.

Example:

import '@compare-ui/figma';
import { registerFigmaFromEnv } from '@compare-ui/figma';

registerFigmaFromEnv();

After registration, any package that uses @compare-ui/core or @compare-ui/runner can resolve type: 'figma' resources.

If you need explicit token wiring or want all resolver options in one place, use:

  • createFigmaImageResourceResolver(...)
  • registerFigmaImageResourceResolver(...)

Resolver options

Example shape:

type FigmaResolverOptions = {
  accessToken: string;
  maxRetries?: number;
  retryDelayMs?: number;
  cache?: boolean | FigmaCacheOptions;
};

type FigmaCacheOptions = {
  /**
   * Defaults to true.
   */
  enabled?: boolean;
  /**
   * Defaults to ".desing-comp-cache" resolved from process.cwd().
   */
  directory?: string;
};

maxRetries and retryDelayMs apply bounded retry behavior to transient failures such as:

  • network resets like ECONNRESET
  • HTTP 429
  • temporary 5xx responses

Auth and validation failures are still treated as immediate errors.

If more options are needed later, they should extend this bootstrap configuration rather than changing story or fixture authoring formats.

Cache

The Figma resolver uses a local file cache by default.

The cache is there to avoid repeated Figma API calls and reduce the chance of hitting rate limits. It stores downloaded rendered PNG bytes under:

.desing-comp-cache/

Default settings are equivalent to:

cache: {
  enabled: true,
  directory: '.desing-comp-cache',
}

The cache directory is resolved from the current working directory, so repeated runs from the same project reuse the same Figma renders.

If cache is omitted, or if cache is provided without directory, the resolver uses .desing-comp-cache.

Cache entries are keyed by the normalized render request:

  • Figma file key
  • normalized node id
  • format
  • scale, when provided

Crop offsets are not part of the cache key because cropping is handled later by @compare-ui/core.

With default options, a second identical Figma resource should be served from .desing-comp-cache without calling the Figma image endpoint again.

For explicit registration, omit cache to keep the default cache on:

import { registerFigmaImageResourceResolver } from '@compare-ui/figma';

registerFigmaImageResourceResolver({
  accessToken: process.env.FIGMA_ACCESS_TOKEN!,
});

registerFigmaFromEnv() also keeps cache on by default.

Disable cache in code

Pass cache: false when creating or registering the resolver:

import { registerFigmaImageResourceResolver } from '@compare-ui/figma';

registerFigmaImageResourceResolver({
  accessToken: process.env.FIGMA_ACCESS_TOKEN!,
  cache: false,
});

The same option is available on createFigmaImageResourceResolver(...) and registerFigmaFromEnv(...).

Use a custom cache directory

import { registerFigmaImageResourceResolver } from '@compare-ui/figma';

registerFigmaImageResourceResolver({
  accessToken: process.env.FIGMA_ACCESS_TOKEN!,
  cache: {
    directory: './.cache/figma-renders',
  },
});

Basic usage

Example:

import { registerFigmaFromEnv } from '@compare-ui/figma';
import { runDesignComparisonCase } from '@compare-ui/runner';

registerFigmaFromEnv();

const result = await runDesignComparisonCase({
  executionCase: {
    name: 'home-screen',
    reference: {
      type: 'figma',
      url: 'https://figma.com/design/abc123/Example?node-id=2020-1617',
      crop: {
        bottom: 20,
      },
    },
    actual: {
      type: 'fs',
      path: './actual.png',
    },
    compare: {
      threshold: 0.1,
      acceptance: {
        maxDiffPercent: 0.5,
      },
    },
  },
  output: {
    outputFolder: './design-tests',
    runId: crypto.randomUUID(),
  },
});

Typical usage

The expected workflow is:

  1. install or include @compare-ui/figma
  2. register the resolver during bootstrap
  3. use type: 'figma' in config with either url or fileKey plus nodeId
  4. run the normal comparison flow through higher-level packages

Notes

  • This package adds Figma support on top of @compare-ui/core.
  • Registration is explicit.
  • registerFigmaFromEnv() is the shortest happy-path runtime bootstrap.
  • Type augmentation is still a separate compile-time concern, so keep import '@compare-ui/figma'; somewhere in the program when TypeScript would not otherwise see the package.
  • The comparison flow still runs through the normal core and runner packages.