A Meteor gotcha that catches React developers: inside a publication, the context 'this' gives you — this.userId, this.ready(), this.stop().
Arrow functions have no 'this' of their own, so they silently break access to it. Always use a regular function in a publication.
Still on Meteor 2? 👀
It reached End-of-Life in December 2025, which means no more updates of any kind.
But hey, migrating to Meteor 3 is more approachable than it looks.
This new guide on the blog covers what changed, what breaks, and how to fix it: https://t.co/0GVhVVw0U1
Meteor 3.5-rc.1 is out!
Change Streams on by default, a pluggable DDP transport (uWebSockets), DDP Session Resumption, MongoDB Collation, Node.js 24.15.0, and more.
This is the final checkpoint before 3.5.
Give it a try:
meteor update --release 3.5-rc.1
@meteorjs release 3.5-rc.1 is out 🎊🎉🥳
All the details: Change Streams on by default, the new pluggable DDP transport (uWebSockets), DDP Session Resumption, `accounts-express`, async DDPRateLimiter matchers, MongoDB Collation, the EJSON/DDP performance batch, Node.js 24.15.0, and the full list of fixes, are already covered in the main post here: https://t.co/BaNrCcBTPi
Give it a try:
meteor update --release 3.5-rc.1
This is the final checkpoint before 3.5 official, so the most valuable thing you can do right now is test your apps against `3.5-rc.1` and report anything unusual here in the thread. Your feedback is what gets us to a solid stable release. 🙏
Thanks again to everyone who contributed and tested along the way!
Type safety in a Meteor app starts with your collections. Pass an interface as a generic to Mongo.Collection, and every insert, update, and query gets checked against it.
Insert a document with a missing field or wrong type, and the error shows up in your editor, not in prod.
Meteor's dynamic, reactive nature makes runtime bugs easy to introduce: a publication returning the wrong shape, a method getting a bad argument. TypeScript catches those in your editor, before they hit production.
A full setup guide for 2026: https://t.co/IMxZ3p39bS
Still using Gmail SMTP for transactional emails in your Meteor app?
It works until it doesn't: daily send limits, delays at peak, spam risk, zero visibility into failures.
Meteor 3.x being fully async makes dropping in @resend way cleaner, check it out: https://t.co/Hji2hhceyU
@meteorjs is leveling up, and it's time our community structure reflects the true maturity of the framework. ☄️📈
As the ecosystem continues to grow, relying solely on informal trust and the heroic efforts of a few maintainers just doesn't scale anymore. That’s why we just opened PR #14426, introducing the first official GOVERNANCE.md for MeteorJS.
This isn't about adding bureaucracy, it's about setting us up for the next decade. We are decentralizing technical leadership and creating a clear, professional path for anyone who wants to get deeply involved:
👉 Clear progression paths: Everyone will know exactly how to go from a casual Contributor to a Core Committer, and eventually, to the TSC (Technical Steering Committee).
👉 Domain Expertise: We are defining "owners" for specific areas of the framework (like DDP, Reactivity, Build System) to speed up reviews and distribute the load.
👉 Roadmap Alignment: Helping channel our community's incredible energy into the things that actually drive the framework forward.
We opened this PR as a Draft because I want this to be a collective effort. I’d love to hear your thoughts on this new decentralized governance model.
Do you feel this structure will help you contribute more easily?
Let’s discuss the next chapter of Meteor. Drop your feedback in the PR or here in the replies! 👇
🔗 https://t.co/F1qs5gzkh2
"Works on my machine" in a Meteor app usually comes down to one file: .meteor/release
It pins your Meteor version. If it's not committed, your CI runner installs whatever version it feels like, and your build breaks in ways that look like dark magic.
Commit it. Always.
PSA for every Meteor dev shipping to production: settings.json belongs in .gitignore. Always.
It holds your MONGO_URL, your secrets, your auth keys. If it's in your repo, it's in your Git history forever: even after you delete it.
Use GitHub Secrets and inject at deploy time.
Deploying Meteor apps manually works until it doesn't.
One missed env var, a deploy at the wrong time, or one forgotten step and Production goes down.
Here's how to set up a CI/CD pipeline with GitHub Actions that deploys on every push to main: https://t.co/vSWOectjas
First deploy done. You open the URL and see an error:
503: container still starting up. Wait a minute and refresh.
or
404: app name in deploy ≠ URL you're hitting. Check ROOT_URL and the deploy command.
Two errors, two quick diagnoses.
Migrating a Blaze app to Meteor 3 with Rspack? Your client/main.js becomes the explicit import tree for your entire client.
Forget to import a .html template?
{{> myTemplate}} silently renders nothing.
Forget a .js file?
Its helpers and event handlers simply don't exist. No error.
Every Blaze template, every helpers file, every collections file — has to be imported from your entry point.
// client/main.js
import './main.import.less';
import './views/application/layout.html';
import './views/posts/show.html';
import './views/posts/show.js';
import '../lib/router.js';
// ...every single one
Start with the layout, work outward. When something's missing, Blaze logs Template.X is not defined.
Worst kind of bug when migrating Iron Router to Meteor 3: the kind that produces zero errors.
Iron Router auto-discovers controllers by naming convention. A route called postsShow looks for a global called PostsShowController.
In Meteor 2, top-level assignments were file-scoped globals. It worked.
In Meteor 3, const PostsShowController = ... is module-scoped. Iron Router can't find it.
But the route still renders. Page loads. No console errors. Subscriptions never fire. Database has thousands of docs, Minimongo shows zero.
The fix: stop relying on naming convention. Pass the controller explicitly.
this.route('postsShow', {
path: '/posts/:slug',
controller: PostsShowController,
});
Do this for every route with a controller in Meteor 3.
Subtle Meteor 3 gotcha that can cost you hours:
On the server, always use the Async methods:
- findOneAsync
- updateAsync
- fetchAsync
On the client, keep using sync findOne() inside Blaze helpers and Tracker.autorun.
Why: findOneAsync returns a Promise. Tracker can't track Promises. Your helper stops being reactive.
Symptom: page loads fine on first render, but when new data arrives from a publication, the view never updates. No errors. No warnings. Just silently stale UI.
The sync minimongo methods are deprecated but still functional, and they're the only way to get Tracker reactivity.
Server = always async. Client = sync when you need reactivity.
Migrating a Meteor 2 app to 3.x? Search your codebase for this pattern:
^[A-Z]\w+ =
(capital letter at the start of a line, no const/let/var)
In old Meteor, this created a file-scoped global visible everywhere:
PostsController = RouteController.extend({ ... })
Meteor 3 enforces strict mode. Every one of those becomes ReferenceError: X is not defined at runtime.
The fix is mechanical but has to be deliberate:
- Used only in this file? Add const
- Shared across files? export it, then import where needed
We found ~15 of these in a real production migration. Each one only surfaced when the app crashed on startup. Find them proactively before the runtime does.
This week I’ve updated “flow-router” a core routing library of @meteorjs apps.
Now library ships with Agent SKILLS.md! Simplifying Meteor.js development in the age of AI
#webdev#oss#javascript
Meteor apps behave differently in production.
DDP connections instead of stateless HTTP. Long-lived subscriptions can leak memory. Reactive recomputations that spike CPU out of nowhere. Client and server state that drifts silently.
A new community guide covers how to actually monitor all of this: what to watch at the system, application, and user-impact layers, plus how to set up Monti APM, Sentry, and Uptime Robot in a Meteor project.
Worth reading if you ship Meteor to production 👇
https://t.co/Bw6gxeLf1g