meteor/agent-skills

migrate-to-meteor-3

Use when migrating a Meteor 2.x application to Meteor 3.x.

View source
Original skill document

Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.

Migrate a Meteor 2.x application to Meteor 3.x

Meteor 3 removed Fibers. Server-side Mongo APIs are async. The module system enforces strict mode. Client reactivity inside async code needs care. Atmosphere packages often need forking or replacement. Approach the migration in phases. Do not flip the framework version flag first.

Recommended strategy

  1. Update the project to the latest 2.x release.
  2. Run the app with WARN_WHEN_USING_OLD_API=true meteor run. The console

logs every sync-API call that needs an async sibling, giving you a to-do list before the framework flip.

  1. Migrate server-side sync Mongo calls to *Async siblings while still

on 2.x. Trace each changed function through every server-side caller: await where the caller consumes the value, forward Promises deliberately, and restructure sync-only boundaries. Stop only at an async-capable framework boundary. See references/async-rewrites.md and references/call-vs-callAsync.md. A community jscodeshift codemod automates the easy cases, but it misses non-standard collection imports (for example, meteor/<publisher>:collections). Review the diff by hand, then audit callback Promise ownership and collection argument shapes.

  1. Audit Atmosphere packages. Find replacements or fork outdated ones;

pin api.versionsFrom(['2.x', '3.0']). See references/package-triage.md. Save .meteor/versions and npm lockfile checkpoints so package-major changes remain distinguishable from Meteor.

  1. Upgrade to Meteor 3.x.
  2. Sweep implicit globals; rewrite to const or export / import.

See references/module-system.md.

  1. Audit Blaze helpers and Tracker.autorun blocks for lost reactivity

after await. See references/client-reactivity.md.

  1. Replace iterators that contain await (forEach, map, filter)

with for...of or Promise.all. See references/js-iterators.md.

  1. Audit publications using internal cursor APIs (_cursorDescription,

manual sub.added) and framework handlers that read invocation this. Both synchronous and async publish handlers may return cursors; keep cursor transforms synchronous and use ordinary functions when Meteor must bind this. When a package patches Meteor.publish with an EnvironmentVariable, scope publish.call at the wrapper's top level, not inside the invoked handler. Verify invocation context before and after await. See references/publications.md and references/other-breaking-changes.md.

  1. For TypeScript projects, install zodern:types and update

tsconfig.json. See references/typescript-migration.md.

  1. For React projects, decide whether to adopt the Suspense-aware

react-meteor-data import. See references/react-migration.md, then use meteor-react for current hook, scaffold, and build guidance.

Symptom router

SymptomReference
TypeError: Collection.findOne is not a functionreferences/async-rewrites.md
Method returns undefined or returns a Promisereferences/async-rewrites.md
Downstream caller receives or reads from a Promisereferences/async-rewrites.md
Cron, hook, timer, or event callback drops a Promisereferences/async-rewrites.md
Read method receives $set, $push, or another modifierreferences/async-rewrites.md
allow / deny validator needs an async database readreferences/async-rewrites.md
Meteor.call callback never firesreferences/call-vs-callAsync.md
ReferenceError: X is not defined at startupreferences/module-system.md
Template renders, no data, Minimongo emptyreferences/module-system.md
Iron Router controller silently does not runreferences/module-system.md
{{> partial}} renders nothing in Blazereferences/module-system.md
Page renders but live data never updatesreferences/client-reactivity.md
Blaze helper returns a Promisereferences/client-reactivity.md
Cursor transform errors with "returned a Promise"references/publications.md
sub.added writes never reach the clientreferences/publications.md
Method or publication loses this.userIdreferences/publications.md
Atmosphere package fails to resolve or buildreferences/package-triage.md
forEach/map/filter with await skips itemsreferences/js-iterators.md
Middleware on WebApp.connectHandlers not firingreferences/webapp-express.md
Route uses an unnamed wildcard after Meteor 3.1references/webapp-express.md
rawCollection callback never firesreferences/other-breaking-changes.md
Patched publication loses Meteor.userId() or async contextreferences/other-breaking-changes.md
meteor reset did not wipe the local Mongoreferences/other-breaking-changes.md
Method stub (X) took too long console warningreferences/call-vs-callAsync.md
"Cannot enlarge memory array" during meteor updatereferences/other-breaking-changes.md
External callback lost this.userId or env varsreferences/other-breaking-changes.md
Monkey-patched Meteor.publish never runsreferences/other-breaking-changes.md
meteor/* imports resolve to any in TypeScriptreferences/typescript-migration.md
useTracker or useSubscribe not re-runningreferences/react-migration.md

Anti-patterns

  • Do not run meteor update --release=3 first. Async-convert and

package-triage on 2.x first.

  • Do not global-replace findOne with findOneAsync. Many callers need

rewriting, not just await.

  • Do not mechanically rewrite client Minimongo calls to async. Both APIs work

on the client. Prefer sync calls in naturally synchronous Blaze and Tracker code; use async calls in shared or already-async flows. Wrap reactive reads after an await with Tracker.withComputation.

  • Do not rely on Iron Router controller naming-convention lookup. Pass

controller: explicitly on every route.

  • Do not mix await and .then() in the same function. Pick one.
  • Do not assume implicit globals work. Every top-level identifier in 3.x

must be const, let, or export-ed.

  • Do not invent async replacements. Meteor.userId() remains synchronous

inside methods and publications; there is no Meteor.userIdAsync().

  • Do not use an arrow as a method or publication handler when it reads

framework-bound this. An arrow ignores the invocation context Meteor supplies.

  • Do not rewrite api.addFiles or api.export only because the app moved to

Meteor 3. They remain supported for Atmosphere packages.

See also

  • Async: async-rewrites.md, call-vs-callAsync.md, async-cheatsheet.md,

js-iterators.md, removed-functions.md.

  • Runtime: module-system.md, client-reactivity.md, publications.md,

webapp-express.md, other-breaking-changes.md.

  • Project: package-triage.md, typescript-migration.md,

react-migration.md, eval-cases.md.

  • Current Meteor React integration after the upgrade: meteor-react.

Further reading (optional)

Real-world migration write-ups for context, not for fixing specific issues. The symptom router above is sufficient on its own. Open references/community-case-studies.md only when the user asks for narrative case studies or wants to calibrate effort and timeline.

from this repository

More skills

All skills
meteor
Community

meteor-community-packages

Use when choosing, evaluating, adopting, configuring, or debugging a package from Meteor's documented community catalog, or moving from a community package to a promoted core package such as roles. Triggers on community package recommendations, Atmosphere vs npm selection, Packosphere maintenance checks, jam: helpers, Meteor.publish.once, Meteor.publish.stream, meteor-rpc, Wormhole, cluster, mail-preview, meteor add --search, or adopting a Git-hosted Atmosphere package. Use this skill when the user asks which maintained package fits or how its documented integration works. Route Meteor 2-to-3 package failures to migrate-to-meteor-3 and underlying core API design to its owning skill.

installs
1
GitHub stars
9
Updated
Sep 11
meteor
Community

meteor-debugging

Use when diagnosing an unexplained failure in a Meteor 3 application before the failing layer or fix is known. Triggers on server crashes, client-only errors, stuck subscriptions, DDP or WebSocket disconnects, Minimongo/server data mismatches, hanging or flaky tests, slow builds, --inspect, console.log, .only, Playwright traces, or requests to debug a Meteor app. Use this skill when evidence must distinguish Meteor tool, server, client, data, test, browser, mobile, or production boundaries. For test setup and authoring use meteor-testing; after confirming a domain cause, hand the repair to the owning skill.

installs
1
GitHub stars
9
Updated
Sep 11
meteor
Community

meteor-deployment

Use when deploying a Meteor 3 application. Triggers on meteor build, meteor deploy, Galaxy Push to Deploy, Galaxy Mode, Repository Mode, DEPLOYHOSTNAME, Docker, Kubernetes, settings.json, METEORSETTINGS, MONGOURL, MONGOOPLOGURL, ROOTURL, PORT, HTTPFORWARDEDCOUNT, NODEOPTIONS, health checks, pre-deploy commands, hot code push, --architecture os.linux.x8664, --server-only, or a deployed Node.js version mismatch. Use this skill when the user asks about shipping the app, asks about production config, or asks about containerizing. For Cordova Android/iOS artifacts, signing, and native HCP compatibility use meteor-native; this skill owns the backend deployment.

installs
1
GitHub stars
9
Updated
Sep 11
meteor
Community

meteor-methods

Use when authoring or debugging Meteor methods (Meteor.methods, Meteor.call, Meteor.callAsync). Triggers on argument validation with check(), optimistic UI stubs, latency compensation, Meteor.Error handling, and DDPRateLimiter. Use this skill when the user asks about server-side mutation, asks about rate limiting RPC, or asks about wrapping a method with auth checks.

installs
1
GitHub stars
9
Updated
Sep 11