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

@swissquote/crafty-preset-vitest

v1.30.2

Published

<table> <tr><th>Compatible Runners</th><td>

Readme

Not tied to any runner

N/A

  • test: Vitest integrates itself with the crafty test command
  • ide: Vitest integrates itself with the crafty ide command

Crafty provides a preset that will run Vitest once crafty test is executed.

It adds safe defaults to be able to run your tests with your configuration, owns the generated Vitest config used by Crafty and your IDE, and provides an extension hook that allows you and other presets to extend its configuration.

Vitest is a Node-based runner. Unless you set another environment, the tests run in a Node environment and not in a real browser.

If you need another environment, you can override it in the vitest(...) hook.

We recommend that you use a separate tool for browser end-to-end tests if you need them.

[TOC]

File name Conventions

Vitest will look for test files with any of the following popular naming conventions:

  • Files with supported extensions in __tests__ folders.
  • Files with .test.<extension> suffix.
  • Files with .spec.<extension> suffix.

By default, Crafty supports js, mjs, and cjs test files. json stays resolvable, but does not take part in test discovery.

The .test.<extension> / .spec.<extension> files (or the __tests__ folders) can be located at any depth under the project root.

We recommend to put the test files (or __tests__ folders) next to the code they are testing so that relative imports appear shorter. For example, if App.test.js and App.js are in the same folder, the test needs to import App from "./App" instead of a long relative path.

Using crafty-preset-babel or crafty-preset-swc will add jsx as a supported test file extension. Using crafty-preset-typescript will add the TypeScript extensions ts, tsx, mts, and cts.

crafty test

Running crafty test will run all tests and exit. But you can use any option provided by Vitest itself.

For example, crafty test --watch will run your tests in watch mode. This mode will run all your tests once and then wait for code or test changes to rerun the concerned tests.

Crafty supports one active test runner. If both Jest and Vitest are configured, crafty test fails with a clear error.

Crafty-specific CLI options

The Vitest preset also provides extra options:

  • --moduleDirectories <dir[,dir...]>: adds directories to module lookup beyond node_modules.
  • --moduleFileExtensions <ext[,ext...]>: adds file extensions to module resolution and test discovery.
  • --reporters <name[,name...]>: configures Vitest reporters. The special values sonar and vitest-sonar-reporter are normalized to Crafty's Sonar reporter defaults. Crafty resolves the reporter from the preset, writes coverage/sonar-report.xml by default, and keeps relative file paths unless you set reportedFilePath: "absolute".

You can pass a comma-separated list or repeat the option.

Writing Tests

To create tests, add it() (or test()) blocks with the name of the test and its code. You may optionally wrap them in describe() blocks for logical grouping but this is neither required nor recommended.

Crafty enables Vitest's test() and expect() globals for you. A basic test could look like this:

import sum from "./sum";

test("sums numbers", () => {
  expect(sum(1, 2)).toEqual(3);
  expect(sum(2, 2)).toEqual(4);
});

All expect() matchers supported by Vitest are documented on the official website.

Focusing and Excluding Tests

Use test.skip() or it.skip() to temporarily exclude a test from being executed. Vitest also provides focused test helpers and CLI filters when you want to run a single test in isolation.

Coverage Reporting

crafty-preset-vitest ships with V8 coverage support out of the box.

Tests run slower with coverage enabled, so we recommend running it separately from your normal watch workflow.

Run crafty test --coverage to include a coverage report. Crafty keeps Vitest coverage output under coverage/ and includes coverage/lcov.info by default so SonarQube and similar tools can ingest it. Unless you override them, Crafty normalizes coverage to use provider v8 and reporter lcov.

If you need to customize Crafty's coverage settings, assign options.test.coverage through the vitest(crafty, options, context) hook.

module.exports = {
  vitest(crafty, options) {
    options.test.coverage = {
      reportsDirectory: "./reports/coverage",
      reporter: ["lcov"],
    };
  },
};

Snapshot Testing

Vitest supports snapshot testing for values, rendered components, and more. Read more about snapshot testing.

Vitest configuration ownership

Crafty owns the Vitest configuration it runs.

  • crafty test computes the Vitest config from Crafty state and ignores official vitest.config.* files.
  • crafty ide writes the IDE-facing vitest.config.mjs file and removes alternative filenames such as vitest.config.js, vitest.config.cjs, vitest.config.mts, vitest.config.ts, and vitest.config.cts.

If you need to change Vitest behavior, use the vitest(crafty, options, context) hook rather than maintaining a separate vitest.config.* file.

Extending the configuration

Each preset and crafty.config.js can define the vitest(crafty, options, context) function to override Vitest's configuration.

const path = require("node:path");
const MODULES = path.join(__dirname, "..", "node_modules");

module.exports = {
  /**
   * Represents the extension point for Vitest configuration
   * @param {Crafty} crafty - The instance of Crafty.
   * @param {Object} options - The Vitest configuration object
   * @param {Object} context - Crafty helpers for resolution and runtime plugins
   */
  vitest(crafty, options, context) {
    context.moduleDirectories.push(MODULES);
    context.moduleFileExtensions.push("ts");

    options.test.setupFiles = options.test.setupFiles || [];
    options.test.setupFiles.push(require.resolve("./testSetup"));
    options.test.environment = "jsdom";
  },
};

Because Crafty computes the configuration before starting Vitest, options must stay serializable.

Reporter callbacks such as vitest-sonar-reporter's onWritePath option are not supported through this hook. For Sonar path control, use reportedFilePath: "absolute" or reportedFilePath: "relative" on the Sonar reporter config.

Use context.moduleDirectories and context.moduleFileExtensions to extend module resolution and test discovery.

Migrating an existing vitest.config.*

When you migrate from a raw Vitest configuration, move repo-specific Vitest settings into the vitest(crafty, options, context) hook.

Common fields that still need to be re-expressed manually are:

  • resolve.alias
  • test.include
  • test.exclude
  • test.testTimeout
  • test.hookTimeout
  • test.pool
  • test.reporters

Crafty always adds its own default discovery globs for supported extensions. If your repository contains fixtures, sample apps, or embedded workspaces, use options.test.exclude to narrow discovery as needed. A common pattern is to exclude paths such as fixtures/**, examples/**, or samples/**.

If you replace options.test.reporters, you own the full reporter list for that package. Add sonar explicitly when you still want the default Sonar XML report alongside a custom reporter such as verbose.

The full list of available configuration options is available on the official website.

Runtime Vite plugins

If you need a Vite plugin at runtime, register it through context.runtimePlugins instead of attaching a plugin object directly to options.plugins.

module.exports = {
  vitest(crafty, options, context) {
    context.runtimePlugins.push({
      pluginPath: require.resolve("./vitest-plugin"),
      options: {
        mode: "test",
      },
    });
  },
};

The module at pluginPath must export a function that receives options and returns a Vite plugin. If you attach non-serializable values directly to options, Crafty rejects them with a clear error.

crafty ide

Running crafty ide generates a package-local vitest.config.mjs file for IDE discovery.

In a monorepo, run crafty ide from each package directory that has its own crafty.config.js and uses @swissquote/crafty-preset-vitest.

Crafty does not modify .vscode/settings.json for Vitest. The generated vitest.config.mjs is intended to be discovered by the official Vitest IDE integration.

Read more about Vitest IDE integration.

SonarQube Integration

Most of the time, at Swissquote, we use SonarQube to check our code quality. More often than not, we add a reporter to create a SonarQube test report.

crafty-preset-vitest comes out of the box with a sonar report that is written to coverage/sonar-report.xml.

Consumers do not need to add vitest-sonar-reporter directly unless they import it themselves. Crafty resolves the reporter from the preset.

This report is automatically added when no reporters are configured after the Crafty hooks have run. The sonar alias, and the raw vitest-sonar-reporter name, are normalized to that default output path with relative file paths by default. This keeps the XML portable across local runs and multi-platform CI.

When coverage is enabled through crafty test --coverage, Crafty also keeps Vitest coverage artifacts under coverage/ and includes coverage/lcov.info by default.

If your Sonar setup requires absolute file paths, set reportedFilePath: "absolute" on the Sonar reporter config.

You can decide to change this configuration by overriding options.test.reporters

module.exports = {
  /**
   * Represents the extension point for Vitest configuration
   * @param {Crafty} crafty - The instance of Crafty.
   * @param {Object} options - The Vitest configuration object
   */
  vitest(crafty, options) {
    options.test.reporters = [
      "verbose",
      ["sonar", { reportedFilePath: "absolute" }],
    ];
  },
};