What if Meteor Was Created in 2025?

Re-Inventing Meteor: Modernizing a Timeless Framework

Meteor remains my favorite framework for building applications. In 2022, I wrote a blog post explaining why I continue to choose Meteor for new projects, and that reasoning holds strong in 2025. Its strength lies in letting developers focus on business logic without wrestling with the “core components” every app needs—authentication, routing, bundling, deployment, and more.

A Pivotal Moment: Meteor 3.0 and the End of Fibers

Meteor 3.0’s removal of Fibers is a game-changer. Fibers shaped Meteor’s architecture and philosophy, but they also tied us to legacy components. With Fibers gone, we have a unique opportunity to modernize the framework’s core while preserving its essence. The challenge? Addressing the elephant in the room: scalability.

What Made Meteor Great?

Meteor’s magic came from its opinionated, “batteries-included” approach. You could start coding your idea immediately, with real-time capabilities baked in. Developers fell in love with the seamless real-time experience—until apps moved from local machines to production servers. The “magic” faded when scalability issues surfaced.

Real-time applications thrive today, and they scale. So why can’t Meteor? I believe the answer lies in technical debt and outdated implementations. Meteor 3.0 is our chance to return to the basics and reimagine how we’d achieve Meteor’s original goals in 2025.

Tackling Scalability: A Modern DDP

The first hurdle is scalability, and the legacy DDP (Distributed Data Protocol) implementation is a bottleneck. I’m working on a new ddp-server and ddp-client to replace Meteor’s outdated SockJS-based solution. Here’s my rationale:

  • WebSockets/WebTransport: WebSockets are battle-tested for real-time apps, and WebTransport is on the horizon. Using a WebSocket emulator like SockJS no longer makes sense.
  • CBOR over eJSON: CBOR is a lightweight, efficient message serialization format that reduces bandwidth compared to eJSON.
  • TypeScript: Improves maintainability and developer experience.
  • Redis: Redis has long been discussed as a solution to Meteor’s scalability woes. My implementation uses Redis to manage connections, enabling better horizontal scalability and potentially opening the door to serverless Meteor apps.

Try It Out

I’ve published an experimental package to test these ideas. Check it out and share your thoughts!

Starting the Server

  1. Clone the ddp-server repo.
  2. Install dependencies: npm install.
  3. Run node ./tests/run.js to start the test server.

Starting the Client

  1. Clone the ddp-client repo.
  2. Install dependencies: npm install.
  3. Start your Meteor app and watch real-time subscriptions in action.

Let’s Discuss

Meteor’s core goals—simplicity, real-time magic, and developer productivity—are as relevant today as ever. With modern tools like WebSockets, CBOR, TypeScript, and Redis, we can rebuild Meteor to scale without losing its soul. What do you think? How would you modernize Meteor in 2025?

My Meteor 2025 Goals

  • ddp-server in 2025
  • ddp-client in 2025
  • ChangeStream Support
7 Likes

I like this Idea, i was thinking last year of doing something similar for my grapher-nova package to support real time data using redis, but you took it 10 steps further. Awesome.

There is an issue with sockets, and is that is not stateless as an http call. And most parts of an application don’t require a socket connection, only certain pages might require it.

Having both http and sockets options for data fetching will be also great for scalability.

Awesome PoC, I’ll give it a try this weekend.

1 Like

I think another thing is that meteor doesn’t have a common pattern for caching DB queries. I know we can implement one ourselves, but having a caching system might help with giving a sense that meteor framework is built for scaling.

First of all, I applaud your effort here and agree with many of your points. I’ve been thinking about your core question quite a bit as well. I think there are a couple other points to consider in tackling the scalability issue:

  1. Meteor must get rid of oplog tailing.
  2. I think managing subscription state should be reconsidered now that the landscape has shifted quite dramatically from when Meteor was first created. More thoughts on that here: Rethinking Meteor – managing subscription state

I think your proposed changes can be done completely under-the-hood so there are no changes to the current Meteor public APIs or at least that should be the goal imo.

Regarding your specific points:

100% agree. There was a GitHub discussion some time ago on making the move to something else.

Interesting. I don’t know much about CBOR but benchmarks would be interesting to evaluate.

Meh. I think Meteor should use JSDoc for all the same reasons that Svelte migrated from TS to JSDoc. Functions exported from Meteor core can and should still have all the same benefits of TS that you’re used to (typechecking, intellisense, inline documentation etc).

My position is, types are fantastic, TypeScript is a bit of a pain … as soon as you use a .ts file, then you have to have the tooling to support that … there’s all of these points of friction when you use a non-standard language like TypeScript that I have come to believe makes it not worth it. So instead, we have put all our types in JSDoc annotations, and we get all of the type safety, but none of the drawbacks, because it is just JavaScript, everything is in comments, you can just run the code. This is what we do in the Sveltekit codebase and it has worked out fantastically so for Svelte 4.0, we’re going to do the same for Svelte because it’s going to enable us to move much more quickly.
Rich Harris

Let application developers use TS if they’d like. My other belief is that in time TS will phase out much like Coffeescript. I expect that JS will eventually adopt the types as comments proposal. We’ll see though.

I think this is one possible solution and maybe a really good one. I think it’s also possibly worth exploring something similar to ElectricSQL – essentially a service that sits between your Meteor app and MongoDB and uses change streams. It could even be used as a caching layer so that MongoDB is hit relatively infrequently and be written in another language that is built for scalability and concurrency, e.g. Elixir. Perhaps this is similar to radekmie’s DDP Router but I’m not really sure since details were limited. My hypothesis is that jam:pub-sub could get most apps relatively far where they wouldn’t need to reach for either Redis or an Electric SQL equivalent, both of which bring in more complexity and I believe would only truly be needed at large scale.

1 Like

You know what, I actually agree with this take. I only used TypeScript for this module as it seems Meteor Core team has been favoring TypeScript for their new features.

Modern IDEs provide the same context with JSDoc as TypeScript. The only benefit is CI tests.

2 Likes

You can already do that with DISABLE_SOCKJS env var. We do that for performance and bandwidth reasons. (However, I know that there are some projects where supporting pre-WebSocket browsers is still a thing.)

You could do that by overriding DDPCommon.parseDDP and DDPCommon.stringifyDDP.

Can you explain how do you plan to do so? I checked the code, and I see that the active subscriptions are stored in Redis, but I couldn’t find any place actually making use of it (I guess it’d be here, but it’s not).

Lots of articles attempting to overhaul the Meteor system all at once :sweat_smile: chill guys!

I’d like to cut up the changes you’re considering into two categories.

  • WebSockets/WebTransport: WebSockets are battle-tested for real-time apps, and WebTransport is on the horizon. Using a WebSocket emulator like SockJS no longer makes sense.
  • CBOR over eJSON: CBOR is a lightweight, efficient message serialization format that reduces bandwidth compared to eJSON.

These changes are pretty tame in my opinion and if done correctly shouldn’t impact the backwards compatibility. Convention-over-configuration is a must but also having sharp knives. Meteor should allow you to swap out the underlying websockets library; currently it’s hard-wired to sockjs. Though @radekmie’s comment makes it seem like it’s already possible??! I’m not sure.

  • TypeScript: Improves maintainability and developer experience.
  • Redis: Redis has long been discussed as a solution to Meteor’s scalability woes. My implementation uses Redis to manage connections, enabling better horizontal scalability and potentially opening the door to serverless Meteor apps.

This second part, I’m a bit on edge about due to @jam’s comments and other consideration. Since these changes would take definitely longer and are of a much greater size. I’m not putting them down but saying need a greater discussion while the first two things you suggested I think should be done already.

1 Like

I think some thing that set Meteor apart from frameworks like Next and Nuxt is that they are too focused on rendering React and Vue respectively. And things that set Meteor apart from stacks like T3 (see: https://create.t3.gg/) are:

  • It’s actually a cohesive framework, not a stack
  • Accounts and Roles (more critically) and other convenience packages hiding a lot of config complexity like Email (less critically)
  • Writing apps looks mostly the same - major architectural changes have occurred (e.g. the removal of fibers, RIP the promise of JS coroutines (slides)), but apart from meticulously sprinkling some async/await across our codebases and some edge cases with reactivity in method stubs some have found, the logic’s largely the same.
  • Hasn’t needed to compete on the bleeding edge. Of course there have been Coffeescript, fibers, Apollo GraphQL that side hustle from MDG, ES6-style imports in function bodies etc, but ultimately the community’s been around long enough to actually adapt and learn from that, which is hard to say when you look at other frameworks in the JS world.

The things that have made me consider moving from Meteor over time (and some resolutions to them) have been things like:

  • :x: Build system & build times (and deployment times, I’ve been spoilt by Vercel, I need instant gratification now dammit! :coffee: :crazy_face:)
    • :white_check_mark: I believe this is all being actively addressed, either adopting SWC (current) or looking into a future adoption of Vite (rumour or planned?)
    • :white_check_mark: Technically jorgenvatle:vite addresses this too, but some extra courage is required
  • :x: Incompatiblities with things like Node ESM exports (thanks Hono…)
    • Increasingly an issue, has to be solved with the build system, I believe that’s happening?
  • :x: Getting stuck on Vue 2 and and fourseven:scss during the Apple Silicon transition and just before Meteor 3
    • :white_check_mark: Vite addresses this
  • :x: the NPM-Atmosphere duality that’s resulted in workarounds like @meteor-vite/react-meteor-data
    • I guess this can be addressed by carefully reducing coupling between Meteor components?
  • :x: Sometimes too much tribal knowledge that seems tangential to the rest of the JS ecosystem
    • :white_check_mark: Replacing some of the community best practices that used to be in the old v1/v2 Meteor Guides in a Meteor v3 guide
  • :x: Hesitancy over Meteor’s pub-sub scalability and the operational complexity you have to undertake longer-term (e.g. redis oplog) vs just using REST (or pseudo-REST) APIs and something like TanStack
    • :white_check_mark: jam:pub-sub’s work with change streams and Method-based publishing essentially address this
  • :x: Serving API endpoints (you have to glue a few things together to make use of the excellent Accounts ecosystem)
    • :white_check_mark: We would have to address this with the Accounts and Webapp packages I guess otherwise everyone will do their own thing (see: tribal knowledge)
  • :eyes: I gotta admit, those hybrid incremental SSR rendering systems are very attractive

If I had to say goodbye to Meteor, and make my own stack, I’d be leaning towards…

  • TanStack Start for a solid fullstack SPA+SSR basis?
  • TanStack Query to functionally but not spiritually replace Minimongo and pub-sub
  • BetterAuth (or start using Kinde, maybe)
  • I would have said Turso for the database but they don’t support ap-southeast-2 while Atlas and Galaxy do, so… if not those, maybe Neon Postgres?
  • React with Chakra-UI, or Solid with Ark UI (or Park UI)? Or their shadcn equivalents…
  • And nodemailer etc.

But nothing is as quick to get up and running, and now instead of pointing someone to maybe 3x sites (Meteor, Frontend framework site, UI components site) to figure out how everything runs, it’s about 5, 6, 7 or so? It’s a lot of fragmented knowledge.

Or I’d just give up and go make an MPA with Adonis maybe…

Somewhat related: The doc site’s down at the moment, but @leonardoventurini was working on a Meteor-like fullstack RPC framework called Helene:

That might be of interest if you want to explore a sort of “Meteor from scratch” approach to things not needing SockJS.