# Collection2 puts a schema between the Meteor client and MongoDB

> Collection2 extends Mongo.Collection with a schema so that every insert and update is validated and cleaned, from client code as well as server code. The current 5.x line requires Meteor 3.1.2 or newer and only supports the async mutation methods, and the package validates with SimpleSchema, Zod or AJV style JSON schemas depending on what you attach.

**Meteor-Community-Packages/meteor-collection2** — A Meteor package that extends Mongo.Collection to provide support for specifying a schema and then validating against that schema when inserting and updating.

- Repository: https://github.com/Meteor-Community-Packages/meteor-collection2
- Website: https://packosphere.com/aldeed/collection2
- Stars: 1,016 · Forks: 111
- Language: JavaScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/meteor-community-packages-meteor-collection2

## A schema on the collection, not beside it

Collection2 is a Meteor package that allows you to attach a schema to a Mongo.Collection, and it automatically validates against that schema when inserting and updating, from client or server code.

The mechanism is an extension of the collection rather than a wrapper around it. You create a normal collection, the kind you would write in a file that runs on both client and server.

```js
const Books = new Mongo.Collection('books');
```

Then you attach a schema to it, and from that point the collection's insert and update paths validate and clean the document against the schema before it reaches MongoDB. The schema is the same object on the client and the server, so the validation a user sees in the browser is the validation the server enforces, which is the property that makes the feature worth having.

The project is part of the Meteor Community Packages organisation, the licence recorded for the repository is MIT, the primary language is JavaScript, and the last push was on 2026-10-08. The release history is on a 5.x line, with v5.0.0 on 2026-08-31, v4.2.2 on 2026-08-12 and v4.2.1 on 2026-07-26, so the 5.x line is recent and the 4.x line was still being patched in the same summer.

## Why allow and deny rules are not enough

The Why Use Collection2 section makes the case in a way that is worth reading closely, because it is a distinction people learn the hard way.

While adding allow and deny rules ensures that only authorized users can edit a document from the client, adding a schema ensures that only acceptable properties and values can be set within that document from the client. Thus, client side inserts and updates can be allowed without compromising security or data integrity.

That is the whole argument for schemas in a Meteor application. A deny rule is a permission, and a permission answers who may write. A schema answers what may be written, and without it a permitted client can set a field to a negative count, a date in the year 3000, or a status value your server code has never heard of. The two checks are orthogonal, and only one of them is usually present.

The second reason is reactivity. Schema validation for all inserts and updates is reactive, allowing you to easily display customizable validation error messages to the user without any event handling. The validation result comes back as part of the failed insert, and the UI can render it directly rather than listening for a separate event and correlating it.

The third reason is speed and security together. Validation is automatic on both the client and the server, so you do not have to write it twice and you do not have to trust the client copy.

There is also an ecosystem reason. The aldeed:autoform package can take your collection's schema and automatically create HTML5 forms based on it, providing automatic database operations, method calls, validation and interface reactivity, so a schema becomes a form generator as well as a guard.

## Three validator backends and four install paths

The package can validate with aldeed:simple-schema, with Zod, or with AJV style JSON schemas, and the version you install decides which of those you can use and how you install the rest.

For the 5.x line, Collection2 5 requires Meteor 3.1.2 or newer, SimpleSchema 3 and Zod 4. Installing with SimpleSchema means adding both packages.

```bash
meteor add aldeed:collection2 aldeed:simple-schema@3
```

With Zod, the validation library goes in through npm.

```bash
meteor add aldeed:collection2
meteor npm install zod@4
```

For 4.2 and later, collection2 detects the schema type you attach, so you add the validation package you plan to use, whether that is aldeed:simple-schema, zod or ajv.

```bash
meteor add aldeed:collection2
meteor npm install ajv
```

The 4.0 and 4.1 line shipped with a pinned aldeed:simple-schema at 1.13.1, so there is no separate install step there, and the 3.x line expects simpl-schema at 1.12.3 installed through npm with the save flag.

The detection behaviour in 4.2 is the change that makes the multi backend support practical, because before it the package had to be told which validator it was talking to. Now the schema object tells it.

One thing to be aware of is that the repository's package.json is not the artefact you install. It is named meteor-collection2, its version field reads 1.0.0, its licence field says ISC while the repository licence is MIT, and its test script is a placeholder that exits with an error. The Meteor package, the one with the version line in the releases, is the one that matters.

## Version 5 dropped the synchronous mutation methods

The single most consequential thing in the 5.x release is stated in the installation section, and it is easy to read past.

Collection2 5 requires Meteor 3.1.2+. It only supports async Mongo mutation methods: insert, update, and upsert throw, so use insertAsync, updateAsync, and upsertAsync with SimpleSchema 3 because cleaning and validation may be asynchronous.

So the synchronous methods are not deprecated, they throw. A Meteor codebase that grew up calling insert and update synchronously, which is a lot of Meteor code, breaks at runtime rather than at build time, and the reason is given: cleaning and validation may be asynchronous.

That reason is worth understanding, because it explains why the 5.x line cannot simply keep the old methods. SimpleSchema 3 and Zod 4 both allow validation that is asynchronous, and a synchronous insert cannot wait for an asynchronous validator. The decision follows from the validator choice rather than from a preference.

## Static and dynamic imports, and what the choice buys

There are two ways to load the package, and the documentation frames the choice as one about your history and one about bundle size.

If you come from a previous version and want to keep things as they were, the static import is the option you should choose.

```js
import 'meteor/aldeed:collection2/static';
```

The dynamic import helps to cut down on bundle size, but it requires you to manually load the package for things to work.

```js
import 'meteor/aldeed:collection2/dynamic';

await Collection2.load();
```

The difference in practice is that the static version installs itself as a side effect of the import, so attaching a schema to a collection works as soon as the module is in the graph. The dynamic version gives you a function to call, which means the loading is explicit and can happen at the point where you need it.

That matters for a package that patches Mongo.Collection. The static import pulls the whole thing into every bundle that touches it, and Meteor's bundler is famously good at making a small dependency end up in every client bundle. The dynamic version is the escape hatch for an application that has a large client bundle and does not want this in it.

The static import is the safe default for a new application, and the dynamic one is the answer for a bundle size problem.

## Attaching schemas, and the options that shape the behaviour

The attachSchema options are where the behaviour of the package becomes specific, and the documentation covers two of them in detail.

A schema can be attached to a normal collection, and multiple schemas can be attached to the same collection, which is the pattern for a collection that has different shapes for different users. There is also a section on attaching a schema to Meteor.users, which is the special case everybody needs and nobody enjoys.

The transform option changes what happens to a document that does not match the schema. The replace option is the counterpart, and the two together decide whether a bad document is repaired or rejected.

The rest of the surface is about who validates, and it is extensive. There is validating without inserting or updating, so you can check a document before you commit it. There is inserting or updating without validating, so a migration can write fields the schema does not know about. And there is inserting or updating without cleaning, with separate switches for skipping the removal of properties that are not in the schema, skipping the conversion of values to match what the schema expects, skipping the removal of empty strings, and skipping the generation of automatic values. You can also pick or omit from the attached schema, and you can insert or update bypassing Collection2 entirely.

The reason so many escape hatches exist is the same reason the package exists. A schema is a constraint, and a constraint that cannot be temporarily relaxed is a constraint that gets worked around by turning the package off.

## Conclusion

Adopt Collection2 when your Meteor application accepts writes from the client and you need those writes checked against a schema, because allow and deny rules stop unauthorised edits but do not stop a client setting a field to an impossible value. Do not adopt it on a Meteor version below 3.1.2 if you want the 5.x line, and check the async change first, because 5.x only supports insertAsync, updateAsync and upsertAsync and the synchronous methods throw. Verify first which validation backend your schema is written in, because the package detects the type of the attached schema and the install step differs for each.

## FAQ

### What does Collection2 do for a Meteor application?

It lets you attach a schema to a Mongo.Collection and automatically validates and cleans every insert and update against that schema, from client code as well as server code, so that only acceptable properties and values can be set from the client.

### Which validation libraries does Collection2 support?

It can validate with aldeed:simple-schema, with Zod, or with AJV style JSON schemas. From version 4.2 collection2 detects the type of the schema you attach, so you install whichever validation package you intend to use.

### Why did Collection2 5 break synchronous inserts?

Collection2 5 requires Meteor 3.1.2 or newer and only supports the async mutation methods, because cleaning and validation may be asynchronous with SimpleSchema 3 and Zod 4. The synchronous insert, update and upsert methods throw, so you must use insertAsync, updateAsync and upsertAsync.

### How do I load Collection2 in my application?

With a static import of meteor/aldeed:collection2/static, which is the option to choose if you want things to work as they did in a previous version. The dynamic import of meteor/aldeed:collection2/dynamic reduces bundle size but requires you to call await Collection2.load() yourself.

### Can I write documents that do not match the schema?

Yes. The documentation describes validating without inserting or updating, inserting or updating without validating, and inserting or updating without cleaning, with separate options to skip removing properties not in the schema, to skip converting values, to skip removing empty strings and to skip generating automatic values, plus the option to bypass Collection2 entirely.

### Why use a schema when Meteor already has allow and deny rules?

Allow and deny rules ensure that only authorized users can edit a document from the client, but a schema ensures that only acceptable properties and values can be set within it. That way client side inserts and updates can be allowed without compromising security or data integrity.

## Sources

- [License: MIT](https://github.com/Meteor-Community-Packages/meteor-collection2/blob/master/LICENSE)
- [Meteor-Community-Packages/meteor-collection2 on GitHub](https://github.com/Meteor-Community-Packages/meteor-collection2)
- [Project website](https://packosphere.com/aldeed/collection2)
- [README](https://github.com/Meteor-Community-Packages/meteor-collection2/blob/master/README.md)
- [Releases](https://github.com/Meteor-Community-Packages/meteor-collection2/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/meteor-community-packages-meteor-collection2
