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/runner

v0.1.0

Published

Execution helpers for design-comparison runs.

Downloads

119

Readme

@compare-ui/runner

Execution helpers for design-comparison runs.

This package takes a comparison case, runs it through @compare-ui/core, writes the produced artifacts and report, and returns a structured result that can be used by tests, Storybook, or CLI commands.

It is the shared execution and persistence layer. Browser and Storybook readiness remain adapter concerns, while image preprocessing remains owned by @compare-ui/core.

Installation

pnpm add @compare-ui/runner @compare-ui/core

@compare-ui/core should be installed in the consuming app because @compare-ui/runner is designed to use the app's shared core instance.

What it exports

Main functions:

  • runDesignComparisonCase(...)
  • createFailureMessage(...)

Main types:

  • DesignComparisonExecutionCase
  • DesignComparisonOutputConfig
  • DesignComparisonRunResult

Published entrypoint:

  • @compare-ui/runner

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

Execution case

The runner works with one execution case at a time.

Example shape:

import type {
  ArtifactInstruction,
  CompareConfig,
  CropOffsets,
  ImageResource,
  ImageSize,
  ReportingConfig,
} from '@compare-ui/core';

type ViewportSize = ImageSize;

type DesignComparisonExecutionCase<TArgs = never> = {
  name: string;
  viewport?: ViewportSize;
  reference: ImageResource;
  actual: ImageResource;
  compare?: CompareConfig;
  artifacts?: ArtifactInstruction[];
  reporting?: ReportingConfig;
  args?: Partial<TArgs>;
};

Typical inputs:

  • name
  • reference image resource
  • actual image resource
  • compare config
  • artifact config
  • reporting config

The runner uses @compare-ui/core to prepare the input resources before comparison.

That means workflows can still rely on core-owned image preparation behavior such as:

  • crop handling
  • explicit size normalization
  • explicit background flattening

The image-processing rules themselves belong to @compare-ui/core. The runner's job is to execute the case, persist outputs, and shape the final run result.

Output config

The runner also needs an output location for the run.

type DesignComparisonOutputConfig = {
  outputFolder: string;
  runId: string;
};

Outputs are written to:

{outputFolder}/{name}/{runId}/{viewportX}x{viewportY}/

Typical contents:

  • reference.png
  • actual.png
  • diff.png
  • generated review artifacts such as overlay.png or grid-row.png
  • comparison-report.json

Run result

runDesignComparisonCase(...) returns a structured result.

import type { AcceptanceResult, ComparisonMetrics, CropOffsets, ImageSize } from '@compare-ui/core';

type SourceReport = {
  originalSize: ImageSize;
  crop: Required<CropOffsets>;
  finalSize: ImageSize;
};

type DesignComparisonRunResult = {
  name: string;
  status: 'passed' | 'failed' | 'error';
  metrics?: ComparisonMetrics;
  acceptance?: AcceptanceResult;
  artifactPaths: string[];
  errors: string[];
  reportPath: string;
  sources: {
    reference: SourceReport;
    actual: SourceReport;
  };
};

This makes it easy to:

  • print artifact paths in a CLI
  • fail a Playwright test with useful output
  • inspect a JSON report later

Basic example

import { gridRowArtifact, overlayArtifact } from '@compare-ui/core';
import { createFailureMessage, runDesignComparisonCase } from '@compare-ui/runner';

const result = await runDesignComparisonCase({
  executionCase: {
    name: 'example-screen',
    viewport: { x: 320, y: 640 },
    reference: {
      type: 'fs',
      path: './tests/fixtures/example-screen-reference-padded.png',
      crop: {
        bottom: 20,
      },
    },
    actual: {
      type: 'buffer',
      buffer: screenshotBuffer,
    },
    compare: {
      threshold: 0.1,
      includeAntiAliasedPixels: false,
      writeDiffArtifact: true,
      acceptance: {
        maxDiffPercent: 0.5,
      },
    },
    artifacts: [
      overlayArtifact(),
      gridRowArtifact({
        items: ['overlay', 'actual', 'reference'],
        size: 16,
        lineWidth: 2,
      }),
    ],
    reporting: {
      writeJsonReport: true,
      printArtifactPaths: true,
    },
  },
  output: {
    outputFolder: './design-tests',
    runId: crypto.randomUUID(),
  },
});

if (result.status !== 'passed') {
  throw new Error(createFailureMessage({ result }));
}

Minimal compare-only example

If you only need a compare run plus the persisted report and default compare artifacts, you can omit extra artifact instructions.

import { createFailureMessage, runDesignComparisonCase } from '@compare-ui/runner';

const result = await runDesignComparisonCase({
  executionCase: {
    name: 'example-screen',
    reference: {
      type: 'fs',
      path: './tests/fixtures/example-screen-reference.png',
    },
    actual: {
      type: 'buffer',
      buffer: screenshotBuffer,
    },
    compare: {
      threshold: 0.1,
      writeDiffArtifact: true,
      acceptance: {
        maxDiffPercent: 0.5,
      },
    },
  },
  output: {
    outputFolder: './design-tests',
    runId: crypto.randomUUID(),
  },
});

if (result.status !== 'passed') {
  throw new Error(createFailureMessage({ result }));
}

Failure messages

createFailureMessage(...) formats a run result into a readable message.

The message is intended to include:

  • run name
  • viewport
  • metric summary
  • report path
  • artifact paths
  • any collected errors

This is useful for:

  • Playwright test failures
  • Storybook-driven checks
  • CLI output

Effective viewport

The runner uses the prepared reference image size for the final output segment.

Example:

const executionCase = {
  name: 'home-screen',
  viewport: { x: 320, y: 640 },
  reference: {
    type: 'fs',
    path: './tests/fixtures/home-screen-reference.png',
    crop: {
      bottom: 20,
    },
  },
  actual: {
    type: 'buffer',
    buffer: screenshotBuffer,
  },
};

If the reference image is cropped from 320x640 to 320x620, the run output is written under the 320x620 viewport segment.

Typical usage

The runner is intended to be used by higher-level packages that already know how to produce the actual screenshot:

  • CLI commands that compare two existing images
  • Playwright component-test fixtures
  • Storybook-based screenshot tests

It is the package that turns a single comparison case into:

  • generated PNG artifacts
  • a persisted JSON report
  • a structured run result

When a workflow needs size normalization or transparent-background alignment, use the core-owned preprocessing model and then execute the prepared case through the runner.