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

@qualflare/vitest

v0.4.2

Published

Native Vitest reporter for Qualflare — captures status, per-attempt retry history, flakiness, assertion diffs, nested steps and metadata.

Readme

@qualflare/vitest

npm version CI Qualflare License: Apache-2.0

A native Vitest reporter for Qualflare — captures test results directly from your vitest run: status, per-attempt retry history and flakiness, assertion diffs, nested steps, and author-facing metadata (labels, links, tags, priority, custom attachments).

Without it, Vitest results reach Qualflare through the Jest-compatible JSON file, which carries pass/fail and duration and nothing else — no retries, no flakiness, no attachments, no metadata.

The reporter itself makes no network calls. It writes a report directory, and qualflare-cli uploads it — which is what lets any number of sharded CI jobs merge into a single Launch.

Install

npm install --save-dev @qualflare/vitest

Requires vitest >=3.0.0 (installed separately as a peer dependency) and Node >=18 (Vitest 4 itself requires Node >=20). You also need @qualflare/cli v0.1.24 or newer. v0.1.18 was the first release that recognised vitest as a framework (an older CLI silently labels your suites generic), and v0.1.24 is the first that reads localImagePath — image attachments are now written into outputDir rather than base64-inlined into the report, and a CLI that ignores the field leaves an attachment with neither content nor a storage key, which the server records from its name alone as an undownloadable placeholder.

The peer range is deliberately open-ended rather than capped at a known-good version, so a new Vitest release never hard-blocks npm install for you. 3.0, 3.2 and 4.x are exercised in CI against a real vitest run; newer versions are untested but not refused — please open an issue if one misbehaves.

Vitest 2 and earlier are not supported: the reporter is built on the Reported Tasks API (onTestCaseResult, onTestRunEnd, TestCase), which does not exist before 3.0.

Quickstart

// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { qualflareReporter } from '@qualflare/vitest';

export default defineConfig({
  test: {
    reporters: [['default'], qualflareReporter({ environment: 'staging' })],
  },
});

qualflareReporter() is a typed helper. Vitest types a custom reporter's options as Record<string, unknown>, so the hand-written tuple form silently accepts typos — but it works too, if you prefer it:

reporters: [['default'], ['@qualflare/vitest/reporter', { environment: 'staging' }]],

Then run your tests and upload the results — two steps, and no token needed for the first:

# 1. Run. Writes ./qualflare-results. Zero network calls.
npx vitest run

# 2. Upload. `qf login <identifier> <token>` stores the credential once.
qf <your-project-identifier> collect ./qualflare-results

Sharded CI

Point every shard at the same outputDir and collect once at the end. Each process writes its own uniquely-named file, so shards never overwrite each other, and qf collect merges every file in the directory into a single Launch:

# in each parallel job — all writing to the same directory
npx vitest run --shard="$SHARD_INDEX/$SHARD_TOTAL"

# once, after all shards finish (e.g. with the directory restored from CI artifacts)
qf <your-project-identifier> collect ./qualflare-results

Nothing needs configuring for this: Vitest hands reporters its own --shard value, so each case is stamped with the shard that ran it automatically. (Vitest's shard index is 1-based — --shard=1/3 is the first shard — and Qualflare's is 0-based; the conversion is handled for you.)

Enriching your tests

import { expect, test } from 'vitest';
import { qualflare } from '@qualflare/vitest';

test('a user can check out', async () => {
  qualflare.label('epic', 'Billing');
  qualflare.link('https://tracker.example/QF-42', { type: 'issue', name: 'QF-42' });
  qualflare.tag('smoke');
  qualflare.priority('high');

  await qualflare.step('add an item to the cart', () => {
    qualflare.parameter('sku', 'BOOK-1');
    expect(cart.items).toHaveLength(1);
  });

  expect(cart.total).toBe('10.00');
});

Metadata travels on task.meta, the channel Vitest serialises from the test worker back to the reporter, so these calls are ordinary synchronous function calls with nothing to await and no promise that can reject into your run. Full reference in docs/METADATA-API.md.

Vitest has no test.step() of its own, so qualflare.step() is the only way to get step structure into a report. Steps nest, and timing is exact — real elapsed time around the awaited body.

Configuration

Every option has an environment-variable override, and everything has a sensible default — see docs/CONFIGURATION.md. There is no token option: this reporter makes no requests, so it has no credential.

One option is worth calling out because it fails late: environment is matched against the environment's uid (slug), not its display name, so Staging in the UI is staging here. A wrong value cannot fail at test time — the reporter makes no requests — so the run succeeds and collect 404s afterwards. See the note in the configuration docs.

Test reports

This reporter is tested with itself. e2e/ is a Vitest suite covering this package's own behaviour — the metadata API, nested steps, image attachments and per-attempt retry history — run by this reporter and uploaded to Qualflare on every merge to main. The results below are that suite's, reported through the code this README documents:

Qualflare

Every case there is meant to pass, so a red run is a real regression rather than a fixture that fails on purpose. Deliberately-failing cases live in test/integration/, which is never uploaded.

Known limitations

  • Image attachments go out of band. A screenshot handed to qualflare.attachment() or carried by a Vitest annotation is written into outputDir and referenced by name, not base64-inlined, so it no longer competes for the report body or the run's attachment budget. Only png/jpeg/gif can take that route — those are what the upload endpoint accepts — and everything else still inlines.
  • Per-attempt history is reconstructed, not read, and needs @qualflare/cli v0.1.23+. Vitest exposes no per-attempt array, so Case.attempts is rebuilt from its accumulated error list. Per-attempt durations are unavailable, and a test using expect.soft() reports no attempt history at all. On a CLI older than v0.1.23 the history is written to the report and then discarded before it reaches the server — see docs/LIMITATIONS.md.
  • Browser-mode screenshots and traces are not attached. They reach a reporter through TestCase.artifacts(), which is experimental and 4.x-only, so it is deliberately not read until it stabilises.

Full details in docs/LIMITATIONS.md.

Development

npm run typecheck        # tsc --noEmit
npm run lint             # eslint .
npm run build            # tsup -> dist/ (ESM + CJS + d.ts)
npm test                 # unit tests
npm run test:integration # spawns a REAL `vitest run` against test/integration/fixtures/

The integration suite loads the reporter from the built dist/, not src/, so it exercises the real package exports map — run npm run build first.

License

Apache-2.0