What building blocks should Meteor ship out of the box?

I’ve been thinking about this a lot lately and wanted to get a discussion going.

When someone picks up Rails, Laravel, or even newer frameworks like Wasp or RedwoodJS, there’s a set of things they just expect to work without reaching for third-party packages. These are the “app building blocks” — the stuff that every real application needs, but that nobody wants to build from scratch. The less time you spend on plumbing, the more time you spend on the thing that makes your app different.

Meteor has always had some of these covered really well. Real-time data? Best in class, still. Accounts? Incredibly easy to get started. Methods/RPC? Simple and effective. But there are gaps, and when a developer is evaluating frameworks for a new project, gaps become reasons to pick something else.

I want to put together a list of what I think those building blocks are and where Meteor stands today, and I’d love to hear what you think is missing or what needs attention.

The checklist

Here’s my take on what a modern full-stack JavaScript framework should provide:

Meteor has strong answers for:

  • Accounts & authenticationaccounts-base, accounts-password, OAuth providers. This has been a Meteor strength since day one. Login, logout, enrollment, password reset — it just works.

  • RPC / methodsMeteor.methods and Meteor.call. Simple, validated, works on client and server. The new async API is a nice improvement.

  • Real-time data — Publications, subscriptions, oplog tailing (ChangeStreams soon? :eyes:). Still the thing that makes people’s eyes light up in demos. Nobody else does this as seamlessly.

  • Database — MongoDB integration is deep and well-tested. Collections, schemas via community packages, good query API.

  • Build system — Isobuild handles a lot. Code splitting, dynamic imports, isomorphic code. It’s opinionated but it works.

  • Authorization / permissions — The roles package has been integrated into core, giving Meteor a built-in answer for role-based access control. Assign roles, check permissions, scope them to groups — it’s the kind of thing that used to require a community package and now ships with the framework.

  • Testing — Tinytest for packages, integration with Mocha/Jest for apps. Could be better documented but the pieces are there.

Meteor has partial or outdated answers for:

  • Background jobs — There’s no built-in solution today. You either use percolate:synced-cron (unmaintained), msavin:sjobs (limited), or roll your own with setInterval. Every Rails app has Active Job. Every Laravel app has Queues. This is table stakes.

  • Emailemail package exists and sends mail. But modern apps need templating, queuing, bounce handling, and deliverability tooling. Right now you’re on your own for anything beyond Email.send(). That said, there’s good community energy here — @dupontbertrand recently proposed a built-in mail preview UI for dev mode, which is exactly the kind of DX improvement that makes a framework feel polished. Rails has this with Action Mailer previews, and it’s one of those small things that saves real time during development.

  • HTTP API layer — Meteor’s webapp package is built on Express 5, so the foundation for HTTP routes is already there. But there’s no structured convention for building REST endpoints alongside your DDP methods — no route generation, no serialization layer, no API versioning. If you need a public API or webhook endpoints, you can wire it up through WebApp.connectHandlers, but you’re doing all the scaffolding yourself.

  • Validation / schemascheck exists for runtime argument validation, but there’s no integrated schema layer for data models. Most people reach for simpl-schema or zod, but there’s no convention, so every app does it differently.

  • Rate limitingddp-rate-limiter exists but it’s DDP-only and pretty basic. No general-purpose rate limiting for HTTP routes, API endpoints, or anything outside of DDP. A production app needs rate limiting across the board.

Meteor doesn’t address today:

  • File uploads & storage — No built-in answer. Community packages like ostrio:files fill the gap but it’s not first-party. Rails has Active Storage. Laravel has filesystem disks. Uploading and storing files (S3, GridFS, local disk) is something nearly every app needs and developers shouldn’t have to evaluate five community packages to get it.

  • Caching — No built-in caching layer. For an app that talks to external APIs or does expensive computations, you’re building your own cache or using Redis directly. Rails gives you Rails.cache with pluggable backends out of the box.

  • Logging & observability — No structured logging, no standard event hooks, no built-in error tracking, no request tracing. You’re wiring up Winston or Pino yourself and figuring out how to correlate logs across methods, publications, and jobs. A framework should give you standardized lifecycle hooks that observability tools can plug into. On the bright side, @italojs has OpenTelemetry support on the roadmap for Meteor — that would be huge. OTel is the industry standard and having native instrumentation would mean Meteor apps plug into Datadog, Grafana, Honeycomb, etc. out of the box.

  • Admin panel / backoffice — Rails has ActiveAdmin, Laravel has Nova/Filament. A way to browse and manage your data without building a whole UI. Meteor has nothing here. Even a basic auto-generated CRUD interface for your collections would save significant time for internal tools and early-stage products.

  • Internationalization (i18n) — No built-in i18n. Community options exist (universe:i18n, tap:i18n) but nothing standardized. For any app that serves users outside a single locale, this ends up being a foundational concern that touches every layer of the stack.

  • Push notifications — Google FCM, Apple APNS — every mobile-facing app needs these eventually. No framework handles this particularly well, but having a first-party package with a unified API for both platforms would remove a lot of boilerplate that every team ends up writing.

  • Search — Full-text search across collections. MongoDB has $text and Atlas Search, but there’s no Meteor-level abstraction. Not every app needs this, but the ones that do really need it.

Some of this is already in progress

I’ve been working on closing a few of these gaps and have PRs open against Meteor core:

  • mongo-schema: native MongoDB schema validation — A new core package that brings schema validation using MongoDB’s native $jsonSchema. Same attachSchema() API that simpl-schema users are familiar with, but backed by database-level enforcement. No more choosing between five community schema packages.

  • thread-context: worker thread bridge for Meteor APIs — A primitive that lets worker_threads transparently access Collections, Methods, and Settings over a MessageChannel. This is the foundation that makes CPU-heavy work possible without giving up Meteor’s runtime context.

  • jobs: first-class job queue system — Built on top of thread-context. MongoDB-backed job queue with scheduling, cron, retries, deduplication, cancellation, cluster concurrency, leader election, monitoring publications, and optional worker-thread offloading. No Redis, no external services.

On the observability side, I’ve been building SkySignal — a monitoring and observability platform designed for Meteor apps, with the kind of standardized event hooks and lifecycle tracing that the framework should integrate with natively.

These are a start, but they don’t cover everything on the list. That’s part of why I’m posting this — I want to know what the community thinks the priorities should be.

What would move the needle?

I think the honest answer is: Meteor doesn’t need to do everything. No framework does. But there’s a minimum set of building blocks that, if missing, will cost you developers during evaluation. A developer comparing frameworks is looking at checklists, and “reach for a community package” is not the same as “it’s built in.”

If I had to rank the remaining gaps by impact:

  1. File uploads & storage — too common a need to not have a first-party answer
  2. Better email — templating and queuing at minimum
  3. Push notifications — FCM/APNS with a unified API
  4. Rate limiting — beyond just DDP, across the whole app
  5. Caching — performance is a feature, and caching is how you get there
  6. i18n — foundational for any app with international users
  7. Admin panel — massive time saver for internal tools and early development
3 Likes

Looks like a great list. I would add Streams to the list, along with Capacitor and Electron

I’m seeing an explosion of new stuff for Meteor, super exciting, but for sure driven by agentic coding. I’m hoping quality/maintainability remains focus for Meteor instead of rushing to get new features out.

I mostly agree with what you said, but I think it also brings back the old question of how opinionated Meteor should be, or whether it should stay somewhere in between.

To me, Meteor sits in a middle ground that is interesting, but also sometimes quite confusing, especially for newcomers. I pointed at that a while ago here: Should Meteor have an official router package maintained by the core team? · meteor/meteor · Discussion #14207 · GitHub

What makes Meteor a bit unusual is that the ecosystem is not just split between “core” and “community packages”.

In practice, a newcomer has to understand several different layers:

  1. what is there by default when you create an app, for example with meteor create --full
  2. the standard / official Meteor packages you can plug in easily, like accounts, roles, check, etc.
  3. community packages that are highlighted because they solve common real-world needs
  4. the broader Atmosphere ecosystem
  5. and then the whole npm ecosystem on top of that

That flexibility is actually one of Meteor’s strengths. It does not force a huge all-in-one framework, and a lot of things can be added very easily as small building blocks. In that sense, I think Meteor often finds a very good middle ground

But at the same time, this layering can also be very confusing when you first discover the framework, because the boundary between “built-in”, “official”, “recommended”, “community”, and “just npm” is not always obvious :grimacing:

And I think this has a real impact on perception.

For example, the first time I read the routing tutorial, I was surprised to see the docs explain routing and then immediately recommend installing ostrio:flow-router-extra: URLs and Routing | Docs

Same feeling when some sections point to extra packages around methods/security: Application Security for Production | Docs

And again with simpl-schema here: Collections and Schemas | Docs (Btw I think it"s redirect to the wrong page (npms one and not MCP one)

For someone new to Meteor, or even new to development in general, that can create the impression of a framework that feels slightly incomplete at first glance, even though Meteor itself works perfectly fine without those packages. The problem is not that extensions exist: the problem is that the boundaries are not always clear enough (imo)

I also think npm adds another layer of confusion here. Having access to npm is a huge strength, but not every package that looks equivalent is actually equivalent in a Meteor app. A good example is simpl-schema: there is a Meteor context around it, and it is not always obvious for a newcomer which package is the right one to use and which one will not behave as expected in Meteor :man_shrugging:

So for me, the question is not only “what should Meteor ship out of the box?”, but also “what should Meteor clearly identify as built-in, official, recommended, or ecosystem-level?”

I realize I got a bit sidetracked, though. What I mainly wanted to say is that I mostly agree with your post, but I think we should distinguish between different kinds of missing building blocks.

For me, in Meteor, we should separate:

Things that should absolutely be standardized (imo)
jobs, schemas/validation, HTTP middleware / rate limiting, observability hooks, uploads/storage

Things that should probably have an official answer, without necessarily living in core
email previews/templating, i18n, caching, admin panel

Things that can stay in the ecosystem
advanced search, push notifications, highly opinionated backoffices

So overall, yes, I agree with the direction of your post. I just think the conversation is not only about what Meteor should ship, but also about making the different layers of the Meteor ecosystem much clearer for developers evaluating the framework for the first time :wink:

1 Like

Hi,

Using AI for formalism.

I agree it’s not only about what Meteor ships, but also about making the layers clear for newcomers.

One thing that often steepens the learning curve: two ways to load data on the client, with two different client-side data models.

  • With classic publications / subscriptions, documents land in Minimongo: you read them like a local collection, and reactivity is wired there.
  • With methods (or a plain HTTP fetch), that’s not the case: you get a one-off result, and the app must decide where to put it (UI framework state, locals, manual merge into a collection, etc.).

Meteor’s own documentation for jam:pub-sub states this plainly for method-based fetching: the data is not automatically merged into Minimongo, you lose the usual reactivity story, and you end up needing your own client stores—which matches the feeling of two places and two sets of rules for “where my data lives.” It’s not literally “two caches” in the strict sense (Minimongo is mainly a reactive view of subscription-synced data), but for a beginner the split feels the same.

The community package jam:pub-sub (documented here: Pub-sub | Docs) offers Meteor.publish.once on the server with the same Meteor.subscribe you already use on the client: data is fetched via a Meteor method and merged into Minimongo, so you read from one place on the client again. That pattern isn’t the right fit for every app, but it’s a good example of a convention / primitive that reduces friction between pub/sub and methods.

So beyond the checklist of missing building blocks, I think there’s real value in documenting explicitly this pairing: Minimongo (via pub) vs. method return values, and optionally in recommending patterns (or “recommended” packages) so teams don’t each reinvent the bridge between the two.

1 Like

Agreed, would love to see Meteor provide more out of the box as a framework. IMO, it should lean more on the opinionated side of things. This of course means that Meteor would need to provide the “right” set of things and maintain them. You can still adopt other packages or build your own as you see fit of course.

I think you identified the main missing pieces, jobs are critical for almost any app so I would rank that near the top along with file uploads, a modernized slingshot that supports pluggable storage including Cloudflare R2.

Not strictly true :slight_smile:. There’s jam:easy-schema which builds on top of check and has Mongo jsonSchema support out of the box. So you get true end-to-end validation using one schema in a tiny footprint. I’d love to see something like it for Meteor core.


Beyond that, I’d love to see many of the ideas contained in the jam packages make their way to core. For those interested, you can check them out here: