[ALPHA / PoC] meteor-upgrade-to-3 – An Automated Assistant for Migrating Meteor 2.x Apps to Meteor 3 (Call for Community Collaboration)

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

  • :repeat: 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 via Meteor.promisify (where helpful)
  • :brain: Scope-aware: adds async to the nearest function, or uses .then/.catch if you prefer
  • :broom: Formatting: optional Prettier + ESLint --fix pass
  • :test_tube: Dry runs and HTML reports of every change
  • :ring_buoy: Git guardrails: initializes a repo if missing, branches, and commits after each stage
  • :jigsaw: Plugin architecture: write your own codemods with Babel/jscodeshift or TypeScript (ts-morph)
  • :compass: 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:

  1. Package replacements:
    • Roles/permissions packages (exact current best successor?)
    • File upload ecosystems
    • Email / accounts addons
    • OAuth service packages now replaced by maintained forks
  2. Async gotchas:
    • Edge cases in publications returning cursors vs. async data sources
    • Method latency compensation differences
  3. Build / packaging:
    • Any custom package.js patterns that broke and how you fixed them
  4. Testing migrations:
    • Mocha / Jest / Tinytest experiences under Meteor 3
  5. SSR / dynamic import differences
  6. Mongo migration caveats (if any structural changes surfaced)
  7. Performance traps (e.g., unawaited promises now causing race conditions)
  8. Desired output formats for CI audits (JSON schema suggestions)

Proposed Shared Package Mapping File

In progress: [WIP] Implement a shared package mapping file for package migration status and suggestions by Copilot · Pull Request #23 · wreiske/meteor-upgrade-to-3 · GitHub

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)

  1. Fork the repo: https://github.com/wreiske/meteor-upgrade-to-3
  2. Create a feature branch.
  3. Add or enhance a rule (follow existing rule module pattern).
  4. Add test fixtures (before/after examples).
  5. Update docs / mapping file if applicable.
  6. 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 “packageXpackageY 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


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

6 Likes