diff --git a/package.json b/package.json
index c329a7d3..4ef94b17 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,51 @@
   "name": "@testing-library/jest-dom",
   "version": "0.0.0-semantically-released",
   "description": "Custom jest matchers to test the state of the DOM",
-  "main": "dist/index.js",
+  "main": "dist/cjs/index.js",
+  "module": "dist/esm/index.js",
+  "exports": {
+    ".": {
+      "require": {
+        "types": "./types/index.d.ts",
+        "default": "./dist/index.js"
+      },
+      "import": {
+        "types": "./types/index.d.ts",
+        "default": "./dist/index.mjs"
+      }
+    },
+    "./jest-globals": {
+      "require": {
+        "types": "./types/jest-globals.d.ts",
+        "default": "./dist/jest-globals.js"
+      },
+      "import": {
+        "types": "./types/jest-globals.d.ts",
+        "default": "./dist/jest-globals.mjs"
+      }
+    },
+    "./matchers": {
+      "require": {
+        "types": "./types/matchers.d.ts",
+        "default": "./dist/matchers.js"
+      },
+      "import": {
+        "types": "./types/matchers.d.ts",
+        "default": "./dist/matchers.mjs"
+      }
+    },
+    "./vitest": {
+      "require": {
+        "types": "./types/vitest.d.ts",
+        "default": "./dist/vitest.js"
+      },
+      "import": {
+        "types": "./types/vitest.d.ts",
+        "default": "./dist/vitest.mjs"
+      }
+    },
+    "./package.json": "./package.json"
+  },
   "types": "types/index.d.ts",
   "engines": {
     "node": ">=14",
@@ -10,7 +54,7 @@
     "yarn": ">=1"
   },
   "scripts": {
-    "build": "kcd-scripts build",
+    "build": "rollup -c",
     "format": "kcd-scripts format",
     "lint": "kcd-scripts lint",
     "setup": "npm install && npm run validate -s",
@@ -36,10 +80,10 @@
   "author": "Ernesto Garcia <gnapse@gmail.com> (http://gnapse.github.io)",
   "license": "MIT",
   "dependencies": {
+    "@adobe/css-tools": "^4.0.1",
     "@babel/runtime": "^7.9.2",
     "aria-query": "^5.0.0",
     "chalk": "^3.0.0",
-    "@adobe/css-tools": "^4.0.1",
     "css.escape": "^1.5.1",
     "dom-accessibility-api": "^0.5.6",
     "lodash": "^4.17.15",
@@ -47,14 +91,17 @@
   },
   "devDependencies": {
     "@jest/globals": "^29.6.2",
+    "@rollup/plugin-commonjs": "^25.0.4",
     "expect": "^29.6.2",
     "jest-environment-jsdom-sixteen": "^1.0.3",
     "jest-watch-select-projects": "^2.0.0",
     "jsdom": "^16.2.1",
     "kcd-scripts": "^14.0.0",
     "pretty-format": "^25.1.0",
-    "vitest": "^0.34.1",
-    "typescript": "^5.1.6"
+    "rollup": "^3.28.1",
+    "rollup-plugin-delete": "^2.0.0",
+    "typescript": "^5.1.6",
+    "vitest": "^0.34.1"
   },
   "peerDependencies": {
     "@jest/globals": ">= 28",
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 00000000..80afe641
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,32 @@
+const del = require('rollup-plugin-delete')
+const commonjs = require('@rollup/plugin-commonjs')
+
+const entries = [
+  './src/index.js',
+  './src/jest-globals.js',
+  './src/matchers.js',
+  './src/vitest.js',
+]
+
+module.exports = [
+  {
+    input: entries,
+    output: [
+      {
+        dir: 'dist',
+        entryFileNames: '[name].mjs',
+        chunkFileNames: '[name]-[hash].mjs',
+        format: 'esm',
+      },
+      {
+        dir: 'dist',
+        entryFileNames: '[name].js',
+        chunkFileNames: '[name]-[hash].js',
+        format: 'cjs',
+      },
+    ],
+    external: id =>
+      !id.startsWith('\0') && !id.startsWith('.') && !id.startsWith('/'),
+    plugins: [del({targets: 'dist/*'}), commonjs()],
+  },
+]
diff --git a/src/jest-globals.js b/src/jest-globals.js
new file mode 100644
index 00000000..e23def7d
--- /dev/null
+++ b/src/jest-globals.js
@@ -0,0 +1,6 @@
+/* istanbul ignore file */
+
+import globals from '@jest/globals'
+import * as extensions from './matchers'
+
+globals.expect.extend(extensions)
diff --git a/src/to-have-form-values.js b/src/to-have-form-values.js
index c3fddcc0..fe8c890a 100644
--- a/src/to-have-form-values.js
+++ b/src/to-have-form-values.js
@@ -1,5 +1,5 @@
-import isEqualWith from 'lodash/isEqualWith'
-import uniq from 'lodash/uniq'
+import isEqualWith from 'lodash/isEqualWith.js'
+import uniq from 'lodash/uniq.js'
 import escape from 'css.escape'
 import {
   checkHtmlElement,
diff --git a/src/to-have-value.js b/src/to-have-value.js
index 0b24e165..da79e416 100644
--- a/src/to-have-value.js
+++ b/src/to-have-value.js
@@ -1,4 +1,4 @@
-import isEqualWith from 'lodash/isEqualWith'
+import isEqualWith from 'lodash/isEqualWith.js'
 import {
   checkHtmlElement,
   compareArraysAsSet,
diff --git a/src/utils.js b/src/utils.js
index 2b45be02..903f24c0 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,5 +1,5 @@
 import redent from 'redent'
-import isEqual from 'lodash/isEqual'
+import isEqual from 'lodash/isEqual.js'
 import {parse} from '@adobe/css-tools'
 
 class GenericTypeError extends Error {
diff --git a/src/vitest.js b/src/vitest.js
new file mode 100644
index 00000000..a6b56cef
--- /dev/null
+++ b/src/vitest.js
@@ -0,0 +1,6 @@
+/* istanbul ignore file */
+
+import {expect} from 'vitest'
+import * as extensions from './matchers'
+
+expect.extend(extensions)