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

vitest-package-exports

v1.1.1

Published

A Vitest util to get all exported APIs of a package and prevent unintended breaking changes

Readme

vitest-package-exports

npm version npm downloads bundle JSDocs License

A Vitest util to get all exported APIs of a package and prevent unintended breaking changes.

Install

npm i -D vitest-package-exports

Update your Vitest config:

export default defineConfig({
  test: {
    server: {
      deps: {
        inline: [
          'vitest-package-exports',
        ],
      },
    },
  },
})

Usage

A typical usage is to make a snapshot to freeze the exported APIs of a package:

import { fileURLToPath } from 'node:url'
import { expect, it } from 'vitest'
import { getPackageExportsManifest } from 'vitest-package-exports'

it('exports snapshot', async () => {
  const manifest = await getPackageExportsManifest({
    importMode: 'src', // or 'dist' or 'package'
    cwd: fileURLToPath(import.meta.url),
  })

  expect(manifest.exports)
    .toMatchInlineSnapshot(`
      {
        ".": {
          "getPackageExportsManifest": "function",
        },
      }
    `)
})

Everytime you adding or remove the exported APIs, the snapshot will break and requires explicit review. This would help you to catch unintended breaking changes, or unintentional internal leaks.

For example, if I renamed the getPackageExportsManifest function to getPackageExportsManifestRenamed, the test will fail until I update the snapshot:

Image

You can use js-yaml to format the object:

import { fileURLToPath } from 'node:url'
import yaml from 'js-yaml' // <---
import { expect, it } from 'vitest'
import { getPackageExportsManifest } from 'vitest-package-exports'

it('exports snapshot', async () => {
  const manifest = await getPackageExportsManifest({
    importMode: 'src',
    cwd: fileURLToPath(import.meta.url),
  })

  expect(yaml.dump(manifest.exports)) // <---
    .toMatchInlineSnapshot(`
      .:
        getPackageExportsManifest: function
    `)
})

Monorepo Usage

Since this utility is only a function, you can compose it freely to fit your monorepo structure.

If you want to snapshot all packages in your pnpm monorepo, here is an example we use in VueUse:

import yaml from 'js-yaml'
import { x } from 'tinyexec'
import { describe, expect, it } from 'vitest'
import { getPackageExportsManifest } from 'vitest-package-exports'

describe('exports-snapshot', async () => {
  const packages: { name: string, path: string, private?: boolean }[] = JSON.parse(
    await x('pnpm', ['ls', '--only-projects', '-r', '--json']).then(r => r.stdout),
  )

  for (const pkg of packages) {
    if (pkg.private)
      continue
    it(`${pkg.name}`, async () => {
      const manifest = await getPackageExportsManifest({
        importMode: 'src',
        cwd: pkg.path,
      })
      await expect(yaml.dump(manifest.exports, { sortKeys: (a, b) => a.localeCompare(b) }))
        .toMatchFileSnapshot(`./exports/${pkg.name.split('/').pop()}.yaml`)
    })
  }
})

This will create a file snapshot for each package in the ./exports directory.

How it works

When getPackageExportsManifest is called, it will:

  1. Find the package.json file in the current working directory.
  2. Parse the exports field in the package.json file.
  3. Depend on the importMode, it will resolve the exports to the corresponding import path.
  • package: Import from package name directly, for example import('vitest/config')
  • dist: Import the module from the defined exports entry, for example import('./dist/config.mjs')
  • src: Import the module from the src directory (replace dist with src), for example import('./src/config.ts')
    • This assume your codebase is structure as src -> dist with one-to-one mapping. If you have a custom build process, provide resolveSourcePath option to write your own mapping logic.
  1. For each entry, it will import the module at runtime to get the exports object. Essentially Object.keys(await import(entry)) (so it's better to only use this in sandboxed environments like Vitest)
  2. Return the manifest of the exported APIs.

FAQ

Does this Requires Vitest?

Actually not necessary, this utility does not directly depend on Vitest, but it's designed to work with Vitest. Internally it use dynamic import() to get the exports object, it would work best in Vitest as it will provide proper resolution of the import path, while also supporting your alias config if any.

I named this under vitest- to give a clear expection. Feel free to use it in other context or even plain Node.js, but no guarantee from our side. Please do your own research.

Sponsors

License

MIT License © Anthony Fu