@msw/data models your fixtures with the same schema validator your app uses
Data querying library for testing JavaScript applications.
At a glance
- What is it?
- The @msw/data library from the Mock Service Worker project lets you define collections of records in a test and query them with an ORM inspired syntax, and it does that on top of Standard Schema rather than a validation dialect of its own. It can stand alone or sit under Mock Service Worker so that the network layer and the data layer are mocked from the same model, and it ships extensions for cross-tab synchronisation and persistence.
- Who is it for?
- @msw/data fits a team whose tests need to query data rather than assert on a static object, and that already validates with Zod, ArkType, Valibot or yup, because the same schema objects describe the fixtures. It is the wrong choice for a suite that only needs a couple of literal objects, where a plain const is faster to read and to maintain.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 24 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A fixture that you can query instead of assert on
The library exists to help developers model and query data when testing and developing their applications. The stated use is creating schema based fixtures and querying them with a familiar ORM inspired syntax, and it can be used standalone or in conjunction with Mock Service Worker for a mocking experience across both the network and the data layers.
That second half of the sentence is the interesting part. A typical test fixture is a literal object, and asserting on a literal object is fine until the application starts making queries. Once the code under test asks for a filtered list, joins a relation or paginates, a literal object stops being a useful fixture and the test starts reaching into the implementation.
@msw/data moves the fixture up a level. A collection holds records, the collection answers queries, and a test can assert on the result of a query rather than on the shape of the data. The homepage for the project is mswjs.io/ecosystem/data, and it sits in the Mock Service Worker ecosystem, which is where the connection to network mocking comes from.
The package is MIT licensed with the licence file at the repository root, the author is Artem Zakharchenko, the version in the manifest is 1.1.8, and the last push was on 2026-09-30. The listed releases are v1.1.8 on 2026-08-30, v1.1.7 on 2026-07-09 and v1.1.6 on 2026-05-15.
Standard Schema keeps your Zod objects usable as fixtures
The first feature listed is the one that decides whether the library fits your project, and it is a choice about what not to build.
The library relies on Standard Schema instead of inventing a proprietary modeling syntax you have to learn. Any Standard Schema compliant object modeling library can describe your data, and the README names Zod, ArkType, Valibot, yup and many others. The specification itself lives at standardschema.dev, and the runtime dependency on the spec package is the only piece of it that appears in the dependency list.
The reason this matters is that a test fixture and a production payload usually need the same shape. If the application validates a request body with a Zod schema, then the fixture in the test should be that schema's output, not a hand written approximation of it that drifts. With Standard Schema as the common interface, the schema object is the single source of truth for both, and the library does not need to know which validation library you chose.
The features list also claims full runtime and type safety, which is the other half of the deal. The type information comes from the same schema objects, so a collection of records typed with Zod is typed in your editor as well as at runtime, and the TypeScript types are part of the published package rather than something bolted on.
Query syntax borrowed from Prisma, relations borrowed from Drizzle
The library is explicit about its influences, which is a good sign for a project that sits between other tools. The querying syntax is inspired by Prisma, and the support for relations, for database like behaviours, is inspired by Drizzle.
The querying side gives you something that reads like a database query over an in-memory collection, which is what makes the fixtures useful for tests that filter, sort or page. The relations side is the part that makes the model behave like a database rather than like an array of objects, and it is what you need when a test asserts that a post has an author, or that deleting a user removes the records that point at it.
The documentation splits those two concerns into separate pages, the Querying page and the Relations page, with an API reference for the collection, and the getting started page is where the collection and the schema are introduced.
What is notable is what is not in the list. There is no database, no server and no network access. The library is a data structure with a query interface, and that is what makes it fast to use in a test and what makes it usable in a browser test where spinning up a backend would be absurd.
Extensions cover the two things a pure collection cannot do
The extensions feature, including custom extensions, is listed for things like cross-tab collection synchronisation or record persistence, and the package exports make those two concrete.
"exports": {
".": "./build/index.mjs",
"./extensions": "./build/extensions/index.mjs",
"./extensions/sync": "./build/extensions/sync.mjs",
"./extensions/persist": "./build/extensions/persist.mjs"
}The sync extension is for cross-tab synchronisation, which matters in a browser test where the same fixture may be queried from more than one tab or worker, and where a collection created in one context has to be visible in another. The persist extension is for record persistence, which is what you want when a test needs state to survive a page reload, or to seed a storage layer the application reads from.
Both are separate entry points rather than built in behaviour, and that is the right shape. Synchronisation and persistence are both opt-in costs, in complexity and in behaviour, and a team that only needs a queryable fixture should not pay for either. The extensions directory at the root of the repository holds the implementations, and the documentation has a page for extensions in general.
The dependency list includes mutative, outvariant and rettime alongside es-toolkit and the Standard Schema spec package.
The test suite runs in Node and in a real browser
The build and test configuration in package.json is a good description of how the project is maintained, and it is a small, modern setup.
"scripts": {
"dev": "tsdown -w",
"test": "pnpm test:node && pnpm test:browser",
"test:node": "vitest",
"test:browser": "playwright test",
"lint": "publint",
"build": "tsdown",
"release": "release publish"
}The test command runs both suites, and the split is meaningful. vitest covers the Node environment and Playwright covers the browser, and a library whose headline feature is that it can be used alongside a service worker in a browser needs to be tested in a browser, not only in Node with a DOM shim.
The lint step is publint, which checks that the published package's entry points and exports are correct, and that is a real risk area for a package with the export map shown above, where a wrong path only fails for the consumer. The build is tsdown, with a watch mode for development, and the release script is driven by @ossjs/release through release.config.json.
The development dependencies also tell you what the maintainers consider the supported surface: zod at 4.x is in the list, which makes sense given that Standard Schema compliance is the core promise, and there is a .node-version file, which pins the Node version the project develops against.
The alternative is a plain object, and the difference shows up when the test queries
There is a completely reasonable alternative to this library, and it is what most teams do first: write the fixture as a literal object and assert on its fields. The difference in approach only becomes visible when the code under test starts behaving like a database.
A literal fixture is a snapshot of one record. @msw/data is a collection with a query interface, relations and an optional persistence layer, so a test can ask for the filtered, sorted, paginated result of a query against several records with relationships between them, and the fixture is defined by the same schema the application uses. The cost is a dependency, a schema, and a slightly less obvious way of reading the test than an inline object.
The other alternative is to run a real database in the test, an in-memory instance or a container. That gives you real constraints and real query semantics, and it costs a process to start, a schema to migrate, and a test suite that is slower and flakier for reasons that have nothing to do with the code under test. @msw/data sits between the two: it has a query interface without the operational weight of a database.
Where it does not fit is a suite that needs a handful of literals. If your test needs a user object with two fields, a plain constant is clearer, and a library that asks you to declare a collection and a schema is over-engineering for that.
The repository also keeps a MIGRATING.md and a decisions/ directory, which is where a project of this size records the reasons behind its API choices, and both are worth reading before you upgrade or before you propose a change.
Editorial conclusion
@msw/data fits a team whose tests need to query data rather than assert on a static object, and that already validates with Zod, ArkType, Valibot or yup, because the same schema objects describe the fixtures. It is the wrong choice for a suite that only needs a couple of literal objects, where a plain const is faster to read and to maintain. Verify first which Standard Schema implementation you use and that it is supported, and read MIGRATING.md and the decisions/ directory before upgrading, since the library is still on the 1.1 line.
Frequently asked questions
What is @msw/data and what is it for?
It is a data querying library for testing JavaScript applications. It helps you model and query data, acting as a convenient way of creating schema based fixtures and querying them with a familiar ORM inspired syntax, either standalone or together with Mock Service Worker for mocking both the network and the data layers.
Which schema libraries can I use with @msw/data?
Any Standard Schema compliant object modeling library, because the library relies on Standard Schema rather than a proprietary modeling syntax. The README names Zod, ArkType, Valibot, yup and many others, and the dependency on the Standard Schema spec package is the only part of that specification in the runtime dependencies.
What do the extensions in @msw/data do?
The package exports them separately, with ./extensions/sync for cross-tab collection synchronisation and ./extensions/persist for record persistence, plus a general ./extensions entry point. Custom extensions are supported, and the root extensions directory holds the implementations.
How are @msw/data releases tested?
The test script runs both a Node suite with vitest and a browser suite with playwright test, because the library is designed to work in a browser alongside a service worker. The lint step is publint, which checks the published package entry points.
Is @msw/data still being worked on?
Yes. The version in package.json is 1.1.8, the listed releases are v1.1.8 from 2026-08-30, v1.1.7 from 2026-07-09 and v1.1.6 from 2026-05-15, and the last push to the repository was on 2026-09-30. The licence is MIT.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mswjs-data)Was this useful?