Meteor 3
A collection of reusable Agent Skills for AI-powered development tools.
npx -y skills add lindoelio/my-agent-skills --skill meteor-3Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use this skill whenever building, modifying, planning, scaffolding, testing, or debugging Meteor 3.x applications (Meteor 3.0 through 3.5+). Triggers on requests involving Meteor, Meteor.js, DDP, Minimongo, Atmosphere packages, `meteor create`, Blaze, Tracker, `Meteor.methods`, `Meteor.publish`, `Mongo.Collection`, `Meteor.callAsync`, `findOneAsync`, `insertAsync`, `updateAsync`, or any Meteor 3.x API. Also use when the user mentions Galaxy, MUP, Cordova with Meteor, or is migrating from Meteor 2.x (Fibers) to 3.x (async/await). Covers full-stack reactive architecture, collections/methods/publications, accounts, routing, security, testing, deployment, mobile, and package authoring. Provides scaffold scripts for fast, token-efficient agentic coding. Do NOT use for non-Meteor Node.js apps or Meteor 1.x/2.x projects that have not begun async migration.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
19.2 KB, as published. Nobody here has run it
Meteor 3 Developer Skill
Meteor 3 is a full-stack JavaScript platform built on Node 22-24.15, Express 5, and MongoDB driver 6.x. The defining change from Meteor 2 is the removal of Fibers: all server-side APIs that were synchronous are now async and return Promises. This skill targets Meteor 3.5+ and assumes async-first patterns throughout. New apps use the modern build stack (Rspack + SWC) by default.
Gotchas (read these first)
-
Server collections are async-only.
findOne,insert,update,remove,fetch,count,forEach,map,observe,observeChangesall throw on the server. Use the*Asyncvariants:findOneAsync,insertAsync,updateAsync,removeAsync,fetchAsync,countAsync,forEachAsync,mapAsync,observeAsync,observeChangesAsync. On the client, sync methods still work for reactivity — only use*Asyncon the client when sharing isomorphic code. -
Meteor.call→Meteor.callAsync. On the client, useawait Meteor.callAsync('name', ...args)for any method with an async stub.Meteor.callstill works for sync-stub methods but logs a warning otherwise. On the server,Meteor.callis gone — useMeteor.callAsyncor call the function directly. -
Meteor.user()is async on the server. Useawait Meteor.userAsync(). On the client,Meteor.user()is still synchronous and reactive. -
Meteor.wrapAsyncis removed. Convert callback APIs withutil.promisifyor wrap innew Promise(...). -
HTTP.callis deprecated. Useimport { fetch } from 'meteor/fetch'(WHATWG fetch). -
Email.sendis removed. Useawait Email.sendAsync({...}). -
Assets.getText/Assets.getBinaryare removed. Useawait Assets.getTextAsync(path)/await Assets.getBinaryAsync(path). -
WebApp.connectHandlers→WebApp.handlers. Express 5 replaced Connect.WebApp.rawConnectHandlers→WebApp.rawHandlers.WebApp.connectApp→WebApp.expressApp. -
Accounts.setPassword→Accounts.setPasswordAsync.Accounts.addEmail→Accounts.addEmailAsync. Many accounts methods are now async — seereferences/async-api-map.md. -
Tracker + async gotcha. In
Tracker.autorun(async fn), code after the firstawaitloses reactivity. Wrap reactive reads inTracker.withComputation(computation, () => ...)to restore it. Thereact-meteor-datauseTrackerhook handles this internally. -
bindEnvironmentis still needed for callbacks from external libraries (Express middleware,setTimeout, etc.) to preserve Meteor context. UseMeteor.bindEnvironment(fn). -
Top-level await is enabled on the server by default. Enable on client with
METEOR_ENABLE_CLIENT_TOP_LEVEL_AWAIT=true(breaksclient/compatibilityand HMR — test carefully). -
MongoDB change streams are the default reactivity mechanism in 3.5. Requires MongoDB 6+ with replica set. Falls back to oplog/polling automatically. Revert via settings:
"packages": { "mongo": { "reactivity": ["oplog", "polling"] } }. -
DDP session resumption changes
onConnectionbehavior (3.5). Clients resume withindisconnectGracePeriod(default 15s) without triggeringonConnectionagain. UseDDP.onReconnecton the client and heartbeat-based presence tracking instead ofonConnectioncounting. Seereferences/performance.md. -
Rspack is the default bundler for new apps (3.4+). New apps use the modern build stack (Rspack + SWC) by default. Existing apps enable it with
meteor add rspackand"modern": trueinpackage.json. Rspack requires entry points inmeteor.mainModuleand does not support nested imports. Seereferences/build-stack.md.
Quick Start
Create a new app and run it:
meteor create myapp # React + MongoDB (default)
meteor create myapp --blaze # Blaze + MongoDB
meteor create myapp --vue # Vue 3 + Rspack
meteor create myapp --svelte # Svelte + Rspack
meteor create myapp --solid # Solid + Rspack
meteor create myapp --typescript # React + TypeScript
meteor create myapp --tailwind # React + Tailwind CSS
meteor create myapp --apollo # React + Apollo GraphQL
cd myapp
meteor npm install
meteor # runs on http://localhost:3000
Create a full imports-based structure (recommended for real apps):
meteor create myapp --full
Scaffold a CRUD module in an existing project:
meteor generate tasks # collection + methods + publications + index
meteor generate tasks --path=server/admin # custom path
Scaffold Scripts (token-efficient code generation)
This skill bundles scripts that generate consistent, idiomatic Meteor 3 code. Always prefer these scripts over hand-writing boilerplate — they produce correct async patterns, naming conventions, and file structure without burning LLM tokens on repetitive code.
When to use meteor generate vs skill scripts:
meteor generate <name>(built-in CLI): Use for basic CRUD modules. Produces idiomatic Meteor 3 async code (exported async functions +Meteor.methodswrapper). Fastest, no script dependency.scaffold-module.sh: Use when you need--with-schema(simpl-schema),--with-tests, or a custom--path.scaffold-method.sh/scaffold-publication.sh: Use to add individual methods/publications to existing modules.scaffold-react-component.sh/scaffold-blaze-template.sh: Use for UI components (not covered bymeteor generate).scaffold-migration.sh/scaffold-settings.sh: Use for migrations and settings (not covered bymeteor generate).
Run scripts from the project root (where .meteor/ lives).
scripts/scaffold-module.sh — Generate a complete API module
Generates a collection, methods, publications, schema, tests, and index file for a domain entity in imports/api/:
bash scripts/scaffold-module.sh <entity-name> [--typescript] [--with-schema] [--with-tests]
# Example:
bash scripts/scaffold-module.sh tasks --typescript --with-schema --with-tests
# Creates: imports/api/tasks/{collection.ts, methods.ts, publications.ts, schema.ts, tasks.tests.ts, index.ts}
scripts/scaffold-method.sh — Generate a single method
bash scripts/scaffold-method.sh <entity> <action> [--typescript]
# Example:
bash scripts/scaffold-method.sh tasks insert --typescript
# Appends an async insert method to imports/api/tasks/methods.ts
scripts/scaffold-publication.sh — Generate a publication
bash scripts/scaffold-publication.sh <entity> <publication-name> [--typescript]
# Example:
bash scripts/scaffold-publication.sh tasks tasks.byOwner --typescript
scripts/scaffold-react-component.sh — Generate a React + Meteor data component
bash scripts/scaffold-react-component.sh <ComponentName> [--typescript]
# Example:
bash scripts/scaffold-react-component.sh TaskList --typescript
# Creates: imports/ui/components/TaskList.tsx with useTracker + useSubscribe
scripts/scaffold-blaze-template.sh — Generate a Blaze template (html + js)
bash scripts/scaffold-blaze-template.sh <template_name>
# Example:
bash scripts/scaffold-blaze-template.sh task_item
# Creates: imports/ui/tasks/task_item.html and task_item.js
scripts/scaffold-migration.sh — Generate a migration file
bash scripts/scaffold-migration.sh <version> <description>
# Example:
bash scripts/scaffold-migration.sh 2 add-index-to-tasks
# Creates: imports/api/migrations/2_add-index-to-tasks.js
scripts/scaffold-settings.sh — Generate settings.json files
bash scripts/scaffold-settings.sh
# Creates: settings/development.json, settings/production.json with Meteor 3 defaults
scripts/check-async.sh — Scan for old sync APIs (migration helper)
bash scripts/check-async.sh
# Scans server/ and imports/ for sync collection methods, Meteor.call, etc.
# Outputs a report of lines that need migration to *Async variants
Reference Files (must read before coding)
Before writing any code for a task, you MUST read the corresponding reference file. These files contain detailed API signatures, edge cases, and security patterns that are not repeated in this main skill file. Skipping them will produce incorrect or insecure code.
| Task | You must read |
|---|---|
| Async API mapping (v2 → v3), migration patterns | references/async-api-map.md |
| Collections, schemas, indexes, denormalization, collation | references/collections.md |
Methods, validation, rate limiting, jam:method | references/methods.md |
| Publications, subscriptions, low-level publish, strategies | references/publications.md |
| Accounts, OAuth, 2FA, email templates, roles, HttpOnly cookies | references/accounts.md |
React integration (useTracker, useSubscribe, suspense) | references/react-integration.md |
| Blaze integration (async helpers, templates) | references/blaze-integration.md |
| Routing (Flow Router, server routes, dynamic imports) | references/routing.md |
Security checklist, allow/deny, rate limiting, CSP, accounts-express | references/security.md |
| Testing (Mocha, factories, Cypress, CI) | references/testing.md |
Deployment (Galaxy, MUP, Docker, meteor build, PWA) | references/deployment.md |
| Modern build stack (Rspack, SWC, CSS, aliases, PWA) | references/build-stack.md |
| Performance (change streams, DDP transport, compression, monitoring) | references/performance.md |
| Community packages (jam:method, meteor-rpc, cluster, transactions) | references/community-packages.md |
| Mobile / Cordova (config, plugins, HCP, build) | references/mobile-cordova.md |
| Package authoring (Atmosphere, npm, build plugins) | references/packages.md |
| Environment variables and settings | references/environment.md |
| CLI commands reference | references/cli-reference.md |
Project Structure (Meteor 3 recommended)
myapp/
├── .meteor/
├── client/
│ ├── main.html # <head>, <body> with #app
│ └── main.js # eager entry: import '/imports/startup/client'
├── server/
│ └── main.js # eager entry: import '/imports/startup/server'
├── imports/
│ ├── startup/
│ │ ├── client/
│ │ │ ├── index.js
│ │ │ ├── routes.js
│ │ │ └── useraccounts-configuration.js
│ │ └── server/
│ │ ├── index.js
│ │ ├── fixtures.js
│ │ └── register-api.js
│ ├── api/
│ │ └── tasks/
│ │ ├── collection.ts
│ │ ├── schema.ts
│ │ ├── methods.ts
│ │ ├── publications.ts
│ │ ├── tasks.tests.ts
│ │ └── index.ts
│ └── ui/
│ ├── components/
│ ├── layouts/
│ └── pages/
├── public/ # static assets served as-is
├── private/ # server-only assets (Assets.getTextAsync)
├── settings/
│ ├── development.json
│ └── production.json
├── mobile-config.js # Cordova config (if mobile)
├── package.json
└── tsconfig.json # if TypeScript
Key rules:
client/andserver/are eager entry points — keep them thin (one import line).- Everything else goes in
imports/(lazily loaded, tree-shakeable). - Set
meteor.mainModuleinpackage.jsonfor explicit entry points:
{
"meteor": {
"mainModule": {
"client": "client/main.js",
"server": "server/main.js"
}
}
}
Core Async Patterns (Meteor 3)
Collection CRUD
// Server — always use *Async
const doc = await MyCollection.findOneAsync({ _id: '123' });
const id = await MyCollection.insertAsync({ name: 'foo', createdAt: new Date() });
await MyCollection.updateAsync(id, { $set: { name: 'bar' } });
await MyCollection.removeAsync(id);
const docs = await MyCollection.find({ active: true }).fetchAsync();
const count = await MyCollection.find({}).countAsync();
await MyCollection.createIndexAsync({ email: 1 }, { unique: true });
// Client — sync still works (for reactivity), *Async for isomorphic code
const doc = MyCollection.findOne('123'); // reactive, sync on client
const docs = MyCollection.find({}).fetch(); // reactive cursor fetch
Methods (RPC)
// imports/api/tasks/methods.ts
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import { TasksCollection } from './collection';
Meteor.methods({
async 'tasks.insert'({ text, userId }) {
check(text, String);
check(userId, String);
if (!this.userId) throw new Meteor.Error('not-authorized');
return TasksCollection.insertAsync({
text,
owner: this.userId,
createdAt: new Date(),
});
},
async 'tasks.toggleComplete'({ taskId }) {
check(taskId, String);
const task = await TasksCollection.findOneAsync(taskId);
if (!task) throw new Meteor.Error('not-found');
if (task.owner !== this.userId) throw new Meteor.Error('not-authorized');
return TasksCollection.updateAsync(taskId, { $set: { completed: !task.completed } });
},
});
// Client call
const result = await Meteor.callAsync('tasks.insert', { text: 'My task', userId: Meteor.userId() });
Publications
// imports/api/tasks/publications.ts
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import { TasksCollection } from './collection';
Meteor.publish('tasks.byOwner', async function () {
if (!this.userId) return this.ready();
return TasksCollection.find(
{ owner: this.userId },
{ projection: { text: 1, completed: 1, createdAt: 1 } }
);
});
React with Meteor data
import { useTracker, useSubscribe } from 'meteor/react-meteor-data';
import { TasksCollection } from '/imports/api/tasks/collection';
function TaskList() {
const isLoading = useSubscribe('tasks.byOwner');
const tasks = useTracker(() =>
TasksCollection.find({}, { sort: { createdAt: -1 } }).fetch()
);
if (isLoading()) return <Loading />;
return tasks.map(t => <TaskItem key={t._id} task={t} />);
}
Express middleware (WebApp)
import { WebApp } from 'meteor/webapp';
import { Meteor } from 'meteor/meteor';
WebApp.handlers.use('/api/health', Meteor.bindEnvironment(async (req, res) => {
const user = await Meteor.userAsync();
res.json({ status: 'ok', user: user?.username });
}));
Key Packages (Meteor 3.5)
| Package | Purpose |
|---|---|
meteor-base | Core bundle (autoupdate, hot-code-push, etc.) |
mongo | MongoDB collections + change streams |
rspack | Rspack bundler integration (default for new apps in 3.4+) |
accounts-password | Password auth (Argon2 support since 3.0) |
accounts-express | Authenticated REST endpoints via Accounts.auth() middleware (3.5) |
accounts-google/facebook/github | OAuth providers |
react-meteor-data | useTracker, useSubscribe, useFind hooks |
ecmascript | Babel ES2015+ transpilation |
typescript | TypeScript support |
hot-module-replacement | HMR for React/Blaze/Svelte/Vue |
fetch | WHATWG fetch() polyfill (replaces http) |
email | Email.sendAsync() via Nodemailer |
check | Argument validation |
ddp-rate-limiter | Rate limit methods/subscriptions (async matchers in 3.5) |
ostrio:flow-router-extra | Client routing (recommended) |
jam:method | Boilerplate-free methods with schema + rate limiting |
grubba-rpc | Type-safe RPC with Zod schemas and client/server type inference |
aldeed:collection2 | Schema-validated collections (v4 bundles simple-schema) |
meteortesting:mocha | Test runner |
percolate:migrations | Database migrations |
cultofcoders:redis-oplog | Redis-based reactivity (scales better than oplog) |
When the user asks to build a Meteor feature
- Check if a scaffold script covers it — run the script first, then customize.
- Always use async server-side —
*Asynccollection methods,Meteor.callAsync,await Meteor.userAsync(). - Validate inputs —
check()orsimpl-schemain every method and publication. - Use
this.userId— never pass userId from the client. - Restrict publication fields — always set
projection(orfields). - Check if Rspack is configured — new apps use Rspack by default; existing apps may need
meteor add rspackand"modern": trueinpackage.json. - Read the relevant reference file for detailed API signatures and edge cases.
- Run
meteor lintto catch issues after changes. - Test with
meteor test --driver-package meteortesting:mocha.
Meteor 3.5 Highlights
- Modern Build Stack: Rspack bundler integration (3.4+) + SWC transpiler (3.3+) — 4x faster builds, 8x smaller bundles. New apps use this by default. See
references/build-stack.md. - MongoDB Change Streams as default reactivity (MongoDB 6+ required). Major resource savings, works on serverless/Atlas Shared tiers. See
references/performance.md. - DDP Session Resumption: clients resume within
disconnectGracePeriod(default 15s) after reconnect.onConnectionis NOT called on resume — useDDP.onReconnectand heartbeat-based presence. - Pluggable DDP Transport:
DDP_TRANSPORT=uwsfor lower latency,DISABLE_SOCKJS=trueto drop SockJS entirely. accounts-express: authenticated REST endpoints viaAccounts.auth()middleware.- Async DDPRateLimiter rules: matchers can be async (fetch from DB to gate by role/tier).
- MongoDB Collation: case-insensitive queries via
{ collation: { locale, strength } }on both client and server. - Argon2 password hashing (3.0+):
Accounts.config({ argon2Enabled: true }). Meteor.loginWithPasswordAsync/Meteor.loginWithTokenAsync/Meteor.logoutAllClientsAsync.- Collection Extensions in core (3.4):
Mongo.Collection.addExtension,addPrototypeMethod,addStaticMethod. Meteor.deferDev/Meteor.deferProd(3.4): defer non-critical setup per environment.- HttpOnly cookies for accounts (3.3):
Accounts.config({ useHttpOnlyCookies: true }). - Service Worker / PWA support (3.4.1): Workbox integration via Rspack.
- Node.js 24.15, Express 5, MongoDB driver 6.x.