Hello Meteor community,
I’m excited to announce the v1.0.0 release of typed:model - a Meteor package that brings automatic runtime validation and full TypeScript type safety to your MongoDB collections using Zod schemas.
Some of you may already know about this package from me talking about it in discord, but for those of you that haven’t here is the run down with a lot of new stuff for the folks in the know already.
About typed:model
typed:model is a lightweight wrapper around Mongo.Collection that provides:
- Full TypeScript type inference for queries, inserts, and updates
- Automatic Zod schema validation on all operations
- Zero boilerplate - auto-populated timestamps, user tracking, and IDs
- Smart updates - MongoDB operators with schema validation
- Field projections - return types automatically narrow based on selection
- Protected fields - denyUntrusted() helper prevents client side privilege escalation
- Isomorphic database - allows client operations in a safe way. As MDG and God intended.

Quick Example
import { Model, CustomTypes, SchemaHelpers } from 'meteor/typed:model';
import { z } from 'zod';
const { nonEmptyString } = CustomTypes;
const { withCommon } = SchemaHelpers;
// Define your schema
const TaskSchema = withCommon(z.object({
title: nonEmptyString,
completed: z.boolean().default(false),
priority: z.number().int().min(1).max(5).default(3),
}));
// Create a Model
export const TaskModel = new Model({
name: 'tasks',
schema: TaskSchema,
});
// Use it with full type safety!
const taskId = await TaskModel.insertAsync({
title: 'Learn typed:model',
completed: false,
// createdAt, updatedAt, createdBy, updatedBy auto-populated!
});
const task = await TaskModel.findOneAsync(taskId);
console.log(task.title); // TypeScript knows all fields!
Key Features
- Automatic Runtime Validation
All operations are validated against your Zod schema:
// ✅ Valid - passes validation
await TaskModel.insertAsync({
title: 'Valid task',
completed: false,
});
// ❌ Invalid - throws ZodError
await TaskModel.insertAsync({
title: '', // nonEmptyString fails
completed: 'not a boolean', // wrong type
});
- Security Built-In: Protected Fields
Prevent client side field updates with the denyUntrusted() helper:
const UserSchema = z.object({
username: nonEmptyString,
email: nonEmptyString,
// These fields are automatically protected from ALL client modifications
isAdmin: denyUntrusted(z.boolean().default(false)),
role: denyUntrusted(z.enum(['user', 'moderator', 'admin']).default('user')),
});
const UserModel = new Model({ name: 'users', schema: UserSchema });
// CLIENT: This will be denied
await UserModel.insertAsync({
username: 'hacker',
email: 'hacker@example.com',
isAdmin: true, // Blocked! Cannot set protected field from client
});
// SERVER: Server can set protected fields
await UserModel.insertAsync({
username: 'admin',
email: 'admin@example.com',
isAdmin: true, // Allowed on server
});
Schema helpers (withCommon, withTimestamps, withUsers) automatically protect their
fields too!
- MongoDB Operators with Validation
All update operators are validated:
await TaskModel.updateAsync(taskId, {
$set: { title: 'Updated Title' },
$inc: { priority: 1 },
$push: { tags: 'urgent' },
});
- Smart Type Inference
Field projections automatically narrow return types:
const titleOnly = await TaskModel.findOneAsync(
{ _id: taskId },
{ fields: { title: 1 } }
);
// titleOnly has type: { _id: string, title: string }
Installation
meteor add typed:model
meteor npm install zod
Documentation
Comprehensive docs are available:
- meteor-typed-model/docs/API.md at main · copleykj/meteor-typed-model · GitHub - Complete Model class API
- meteor-typed-model/docs/CUSTOM_TYPES.md at main · copleykj/meteor-typed-model · GitHub - All built-in types with examples
- meteor-typed-model/docs/SCHEMA_HELPERS.md at main · copleykj/meteor-typed-model · GitHub - Composition patterns
- meteor-typed-model/docs/TYPE_SYSTEM.md at main · copleykj/meteor-typed-model · GitHub - TypeScript type inference
- https://github.com/copleykj/meteor-typed-model/blob/main/docs/BEST_PRACTICES.md - Security, performance, patterns
Why Zod?
- Modern TypeScript-first validation library
- Composable schemas - easy to extend and reuse
- Great error messages - detailed validation feedback
- Active development - large ecosystem and community
GitHub Repository
GitHub - copleykj/meteor-typed-model: Create typed and validated models for you MeteorJS app
Try It Out!
I’d love to hear your feedback! Please try it in your projects and let me know:
- What features you’d like to see
- Any bugs or issues you encounter
Contributions are very welcome! The package has comprehensive test coverage (116 tests) and detailed documentation.
Attribution
The basis of this package is code extracted from the GitHub - deathandmayhem/jolly-roger: Dead men tell no tales! project created by Evan Broder, adapted and packaged for use in any project.
Looking forward to hearing your thoughts!