TL;DR: I’ve started a proof‑of‑concept tool (wreiske/meteor-upgrade-to-3
) to automate parts of the migration from Meteor 2.x to Meteor 3. It’s in early alpha: it will overwrite files, may break things, and absolutely requires you to back up or work on a throwaway branch. I’m looking for community knowledge from people who have already succeeded with Meteor 3 migrations—especially around package replacements, async refactors, and edge cases—so we can shape this into a robust community (and maybe one day “official”) migration utility.
Why This Exists
Meteor 3 is a big architectural step:
- Full move to native async/await (Fibers gone)
- Runtime & platform updates (Node 20+)
- Modern module boundaries and stricter ESM patterns
- Many long‑lived packages now deprecated, renamed, or replaced by community forks
- Subtle behavioral shifts (e.g., publication async handling, method return timing, environment variable expectations)
Manually migrating a production‑aged codebase can be repetitive and error‑prone. This project aims to encode known patterns, package mappings, and safe-ish code transformations so teams can focus on the nuanced logic while the tool handles the mechanical changes.
What It Does Today (Alpha State)
Right now the tool is intentionally minimal but growing. It focuses on identifying and (optionally) transforming common Meteor 2.x constructs that need attention in Meteor 3. It is not a one-click migration—think of it as a structured assistant.
Highlights
Codemods for Meteor 3 async APIs
findOne → await findOneAsync
insert / update / upsert / remove → await *Async
- Cursors:
count / fetch / forEach / map → *Async
Meteor.call → await Meteor.callAsync
Meteor.user() → await Meteor.userAsync()
alanning:roles → meteor/roles
with async API- Generic
cb(err, res)
→await
viaMeteor.promisify
(where helpful)
Scope-aware: adds
async
to the nearest function, or uses.then/.catch
if you preferFormatting: optional Prettier + ESLint
--fix
passDry runs and HTML reports of every change
Git guardrails: initializes a repo if missing, branches, and commits after each stage
Plugin architecture: write your own codemods with Babel/jscodeshift or TypeScript (ts-morph)
Opinionated, configurable: choose await vs then/catch, include/exclude globs, top-level await policy, and more
Internally, the architecture is designed so new “rules” can be dropped in: each rule declares detection patterns, optional transformations, and a severity level.
SAFETY FIRST (PLEASE READ)
This is a destructive tool in its current form.
- DO NOT run on your only copy of a production repo.
- Commit or stash all changes first.
- Recommended workflow:
git clone <your-repo> your-repo-m3-test
cd your-repo-m3-test
git checkout -b meteor3-migration-attempt
# (ensure clean tree)
# run the tool here
- If something goes wrong:
git diff
,git restore
, or just reclone. - The “git branch + commit” step should happen, but do not rely on it as your only safety net yet.
How to Try It
# From inside your Meteor 2.x project clone (on a new branch!) Try a dry run first!
npx meteor-upgrade-to-3 --dry
# Apply transforms and review a report
npx meteor-upgrade-to-3 --write --report
# Common setup: format, lint, and commit
npx meteor-upgrade-to-3 --write --format --lint-fix --commit
Where I Need Community Help Most
Please comment with successful migration experiences, especially:
- Package replacements:
- Roles/permissions packages (exact current best successor?)
- File upload ecosystems
- Email / accounts addons
- OAuth service packages now replaced by maintained forks
- Async gotchas:
- Edge cases in publications returning cursors vs. async data sources
- Method latency compensation differences
- Build / packaging:
- Any custom
package.js
patterns that broke and how you fixed them
- Any custom
- Testing migrations:
- Mocha / Jest / Tinytest experiences under Meteor 3
- SSR / dynamic import differences
- Mongo migration caveats (if any structural changes surfaced)
- Performance traps (e.g., unawaited promises now causing race conditions)
- Desired output formats for CI audits (JSON schema suggestions)
Proposed Shared Package Mapping File
I’d like to maintain a central JSON/YAML like:
{
"alanning:roles": {
"status": "deprecated",
"suggest": ["community:roles-modern"],
"notes": "Needs verification; adjust to real maintained package."
},
"aldeed:collection2": {
"status": "legacy",
"suggest": ["simpl-schema", "npm:collection2-core? (validate)"],
"notes": "Schema validation path may need manual refactor."
}
}
Contributors can PR updates with:
- status: deprecated | replaced | broken | ok
- suggest: array of alternatives (Atmosphere / NPM)
- notes: migration guidance
Roadmap (Tentative)
Phase | Goal |
---|---|
Alpha (now) | Basic rule scaffolding, minimal transforms, gather community data |
Alpha+ | Expand rule set, stabilize package mapping format |
Beta | Reliable dry-run planner, safer Git integration, richer reporting |
RC | Widespread package coverage, docs, test fixtures from real apps |
1.0 | Candidate for “blessed” community migration utility |
Contribution Guide (Short Form)
- Fork the repo:
https://github.com/wreiske/meteor-upgrade-to-3
- Create a feature branch.
- Add or enhance a rule (follow existing rule module pattern).
- Add test fixtures (before/after examples).
- Update docs / mapping file if applicable.
- Open a PR with:
- Problem description
- What rule does
- Edge cases considered
- Any limitations
Also welcome:
- Issues describing real-world migration pitfalls
- Sample sanitized snippets (with permission) demonstrating transforms
- Suggestions for CLI UX
Potential FAQ
Q: Will this finish my migration for me?
No. It accelerates mechanical steps and highlights hotspots.
Q: Can I trust it on a production repo?
Only if you have full backups and a clean branch. Treat results as a starting point.
Q: Does it run inside Meteor or outside?
It’s an external helper—intended to operate on the filesystem & source tree.
Q: Will it remove packages automatically?
Planned: it will propose changes first; destructive removal will likely require a flag.
Q: Does it modify database code or data?
No, it only touches source files (and even that needs caution).
Call to Action
If you’ve:
- Completed (or partially attempted) a Meteor 3 migration
- Found obscure async pitfalls
- Identified reliable package replacements
- Built internal scripts you can generalize
…please jump in. Even a short comment like “packageX
→ packageY
worked for us” is valuable.
Let’s pool the community’s migration knowledge so teams don’t repeat the same fire drills—and maybe evolve this into a recognized standard tool.
Links
- GitHub Repo: GitHub - wreiske/meteor-upgrade-to-3
I’d love feedback on:
- Must‑have transformations for early adoption
- Your preferred dry-run report format
- Any migration blockers you hit that this tool could detect early
Drop thoughts below. Thanks in advance to everyone willing to share hard-won experience! If you have an idea, even if you don’t have time to implement it, please open an issue for it anyway!
-Will