agentleFS
meteormeteor/agent-skills/skills/migrate-to-meteor-3/SKILL.md

migrate-to-meteor-3

Skill10 starsChanged 3 months agoMITView on GitHub

Use when migrating a Meteor 2.x application to Meteor 3.x. Triggers on callAsync, *Async Mongo, removed Fibers, implicit-global ReferenceError, lost Blaze reactivity, a publish function returning a Promise, a scheduler dropping a Promise, a read API receiving update modifiers, async allow/deny, an Iron Router controller not running, "Method stub took too long", Atmosphere resolution, Express 5 WebApp handlers, lost async context, rawCollection callbacks, TypeScript declaration failures during upgrades, useTracker, and useSubscribe. Use this skill when the user asks about upgrading Meteor, async caller propagation, iterators with await, or replacing and forking packages. Standalone declarations and type-checking belong to meteor-typescript.

1 other project uses a version of this, 1 of them edited.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

11 rules. About 0 are common, 2 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Update the project to the latest 2.x release.

    line 37
  2. Very specific:

    Run the app with WARN_WHEN_USING_OLD_API=true meteor run.

    line 38
  3. Very specific:

    Do not run meteor update --release=3 first.

    line 116
  4. Very specific:

    Do not global-replace findOne with findOneAsync.

    line 118
  5. Distinctive:

    Do not mechanically rewrite client Minimongo calls to async.

    line 120
  6. Very specific:

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

    line 124
  7. Very specific:

    Do not mix await and .then() in the same function.

    line 126
  8. Very specific:

    Do not assume implicit globals work.

    line 127
  9. Very specific:

    Do not invent async replacements.

    line 129
  10. Very specific:

    Do not use an arrow as a method or publication handler when it reads framework-bound this.

    line 131
  11. Very specific:

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

    line 134

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

For 3.6-beta.3 or 3.6-rc.0, prepare retained local data under the previous release before updating.

  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.
  3. 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.
  4. 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.
  5. Upgrade to the selected Meteor 3.x release.
  6. Sweep implicit globals; rewrite to const or export / import. See references/module-system.md.
  7. Audit Blaze helpers and Tracker.autorun blocks for lost reactivity after await. See references/client-reactivity.md.
  8. Replace iterators that contain await (forEach, map, filter) with for...of or Promise.all. See references/js-iterators.md.
  9. 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.
  10. For TypeScript projects, inspect the target release and existing declaration provider. Keep working @types/meteor or zodern:types setups. Meteor 3.6-beta.1 adds explicit native opt-in through meteor types; earlier releases retain the legacy workflow. See references/typescript-migration.md, then use meteor-typescript for provider changes and checking.
  11. 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.

For requested case studies, read references/community-case-studies.md; use the symptom router for fixes.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.