Replace Next.js with Meteor?

For a long time I’ve been planning on using Next.js (or Nuxt if you fancy Vue more) over Meteor on this new project of mine because of two reasons:

  • SSR (+ caching) for SEO and snappy page loads
  • Dynamic imports for small bundles

Just so happens, Meteor has catched up and seems to support both. With v1.7, Meteor is passing the competition with support for building two different bundles, one for modern browsers and one for the legacy ones, which is a huge win for bundle sizes beyond just code splitting.

So, has anybody toyed with the idea of “build your own Next.js” with Meteor? Is it doable? What is missing and what’s only half-way-there? What is Next.js doing better or what Meteor cannot do?

When I think about it, Meteor already has:

  • It’s own node based server
  • DDP + Methods or Apollo
  • Dynamic imports / code splitting
  • SSR
  • React for view layer

I’d be more than happy to do some extra leg work in the beginning to stay in the comfort of my familiar spaceship :comet:, but if the experience of building a Next.js -clone with Meteor is going to be more like a space trip with Laika the dog, then I’ll pass and just go with either Next.js or Nuxt which claim to provide what I’m looking for “out of the box”.

Any ideas or tips before I dive into Next.js docs?

9 Likes

Would be happy to contribute to say the least. I’ve some experience with Next and am also building stuff with Nuxt. I think Meteor’s ecosystem combined with a proper structure would be a very powerfull combination.

1 Like

I have some experience with Meteor’s code-splitting and dynamic importing, but SSR to me is the scary part which I haven’t touched and have no idea how easy it is to accomplish.

The guide doesn’t say too much about it:

Server Rendering

The Blaze UI library does not have support for server-side rendering, so it’s not possible to render your pages on the server if you use Blaze. However, the React UI library does. This means it is possible to render HTML on the server if you use React as your rendering framework.

Although Flow Router can be used to render React components more or less as we’ve described above for Blaze, at the time of this writing Flow Router’s support for SSR is still experimental. However, it’s probably the best approach right now if you want to use SSR for Meteor.

https://guide.meteor.com/routing.html#server-side-rendering

Anybody had success implementing SSR?

3 Likes

If you’re okay not using a folder based routing like next, you’re propably going to have fun with https://github.com/juliancwirko/scotty

2 Likes

Thanks, very much relevant!

I did. I actually started writing about it in my blog:

https://www.chrisvisser.io/meteor/how-to-set-up-meteor-react-with-ssr

1 Like

Doesn’t Vulcan already fit this bill?

3 Likes

Meteor ssr settings quite simple, everything info is here in this forum, in particular works nice with react-router-config, light weight bundle size, crawlable by search bots excellent and green cards on page speed insight

Good to know, I guess I’ll have to gather all the bits and pieces from the forum and maybe try and curate it into the official guide.

This has completely slipped past me. Even though I’m not looking for a solution like Vulcan, it will surely come in handy when trying to figure out how to setup SSR properly :slight_smile:

3 Likes

After working almost three years on a Meteor app that’s become quite the beast, it’s really something to type

meteor create --minimal my-new-app

1 Like

@arggh I did it successfully a year ago (but only client side Meteor).

Take a look at this article I wrote, I hope it can be helpful to you.

1 Like

You can check out SSR working with React in Meteor in my starter:

I even have a branch for rendering to node streams - for even faster performance. Really this needs a front end cache on it, to super charge it, but that’s a bit beyond the scope of a standard Meteor app.

3 Likes

Cleverbeagle’s Pup does that as well:

1 Like

A major hinderance in performing full SSR using Meteor is the fact that Meteor does not use cookies by default in its authentication mechanisms. So basically when a Meteor powered node app renders the page for the first time (via onPageLoad function from server-rendering package), it really has no idea whether a user session exists or not, since that information (the token basically) is stored in browser local storage.

So if you would, lets say, login to a website that implements SSR (incorrectly) and afterwards refresh the page, the output from the server would render the DOM as ‘not logged in’ whereas the client would render the DOM as ‘logged in’ and react/vue whatever would complain due to mismatch of DOM between server/client renders.

This is not a show-stopper, but it basically means Meteor users are limited to implementing SSR for public facing routes only which do not require any authentication which isnt too bad (do authenticated users really need SSR anyway?) or having the client set a cookie on login that the server can then read (not good security wise) and render the page accordingly.

Its amazing how many tutorials/howto’s etc. miss this basic use case and its definitely something to be aware of.

4 Likes

Thanks for pointing this out!

My use-case would survive this hindrance though, since all that’s going to change is probably a small part in the header and maybe some buttons being enabled or disabled. So I’d be happy rendering the view as not-logged-in on the server, then doing the authentication dance after hydration, but I can see why that’s not the case for everyone.

Have you made an issue about this in the Meteor repository on Github? Maybe it’s worth talking about.

I think Meteor just needs HMR at this point - its like the top the thing Webpack users shout about

5 Likes

I have done a small project with HMR and Meteor using https://github.com/ardatan/meteor-webpack

It’s not for production usage, just for teaching https://github.com/filipenevola/wantch

The stack is pretty simple, MongoDB, Meteor Methods (instead of GraphQL or pub/sub) and React.

3 Likes

Hey there Chris, ive been trying to find an email to get ahold of you… is it possible to send me a message at admin@chosenmasters.com. I wanted to chat about working on something with you, i have a angular js/meteor app and i want to migrate to React but im having trouble figuring out if i go next js or just keep my meteor backend and upgrade it so i can do SSR, curious about your thoughts and if your a free to hire for some help on this?

Hey. It’s been a while, but I seem to be back now. :slight_smile:. Though this is the Meteor forum, I’m going to be brutally honest with you.

Meteor is Awesome. Next is Awesome. I love both frameworks, but they cannot be compared. It’s not even apples compared to oranges. One is an apple and the other is a basket full of apples. The risk of this basket is that there is always this rotten apple that you might want to throw away even though you’ve now paid for it. The real question you should ask is does the price of buying the apples separately outweigh the price of buying 1 basket and throwing away some of them. Even more so, if you consider that the apples of the basket were picked by real apple experts, do you really want to take the risk of picking the wrong apples yourself?

Both Next and Meteor have their purpose and what you should look at is what they give you vs what you have to build or throw away.

Next.js is your apple. It’s an amazing view layer and it provides you with all the tooling needed to easily integrate your React frontend. Not only that, it follows some nice patterns to allow plug-ability which keeps your code-base nice and tidy. Some of the things where Next.js really shines is pre-rendering, serverside rendering + hydration, routing and optimized hot module replacement capabilities. In other words, it takes care of all the complex render related stuff and provides convenient functionalities to hydrate your components using getServerSideProps and getStaticProps and also a nice CLI tool to help you build and pre-render it for serverless purposes.

One HUGE thing that Next.js doesn’t have though is the state layer. With state layer I mean UI state and domain state. The Meteor guide used to have an excellent explanation about the difference between the two, but I can’t find it atm. It might still be there. Just to be sure that the difference is clear: UI state is essentially the internal state of your components and layout. For example a dropdown that is open or a collapsed menu View state is unique to an app. Domain state however is business related. For a webshop these are products, for a blog this would be articles and the categories of those articles. The real downside of Next.js is on the domain state side, because there is none, except for the hydration helpers that I’ve just mentioned.

Of course you could use Apollo, but that means that you need to create another application for its server and you need to install its client into the next project, provide it with all the boilerplate and create mechanisms to provide serverside rendering.

I’ve seen most developers do Apollo Integrations or in fact any API integration VERY wrong, creating a fundamentally broken project that requires months of refactoring to get it in good shape. Its exactly this practice that developers in companies never get time for. Its simply not feasible. Another downside is it’s reliance on React. But I would also call it a positive point, because it allows ‘proper’ integration using React best practices.

I’m very experienced in React, but I need to admit that React is a moving target. I would consider it a low level UI component abstraction with powerful state management tools like hooks and providers, but besides basic documentation for its tools, it does not promote many best practices with the result of having a very scattered community. That React is a low level API also reflects back on the number of breaking changes. React is atm on version 17/18. Any project (that includes the Next based ones) that has been there for a couple of versions has had to go trough quite some refactor rounds just keep everything up to date.

It does enforce the best practice of continuous refactoring, but it also makes people focus on the wrong things.

Meteor is your basket of apples. It has mostly awesome stuff. Especially on the server. The server by default is typically THE frontender’s weekpoint. Since the introduction of so called BFF’s (Backend for frontends) - which promised to provide a proper abstraction over existing frontends I’ve seen people doing Express.js integrations that make me cringe. Even worse, without them knowing it, they are essentially reinventing something that Meteor OWNS to the core from when it first appeared 8 years ago (2012).

It’s a paradox. People were shooting at Meteor, because it “was hard to make it work with existing backends”, but now we are introducing “BFF’s” that should provide the exact level of abstraction that Meteor gives us, but most devs fail to build an efficient toolkit that even closely matches that of Meteor. Even worse, I found myself diving into existing projects of just 2 years old and it unfortunately had to become my sole purpose to maintain parts of the API that I would never even have to touch in Meteor.

Meteor works with, but also without Mongo. Most people dont realize this, but is very easy to NOT use Mongo, but still Minimongo. Minimongo is the number 1 type of library that I always miss when building big UI interfaces. I get optimistic UI and server sync for free. In Apollo this is still very complex. Unfortunately Minimongo has been originally built to work closely with Mongo (hence the name) and that’s why people get confused by it. Best way to look at Minimongo is by looking at it as a full-stack domain data layer for the UI with powerful query and sync mechanisms. It’s NOT Mongo, but it does use similar powerful features. You can use ANY backend as has been proven by the Redis Oplog package and the SQL integration layer. I’ve been using Meteor mostly on top of existing Rest backends.

Funny enough, I see many big companies still create a BFF with Apollo Server on top of a refactored backend that also uses GraphQL?

So why do people want to use Apollo Server then? Well… GraphQL is awesome. Complex, but awesome. It’s complex, because it has a high learning curve. It forces standards and introduces a different paradigm, but I do feel that it’s the way to go. Meteor’s EJSON actually provides similar capabilities and together with DDP and Minimongo it provides all the tools you need. You could also use DDP without Minimongo and have your own UI state manager.

Meteor has a couple of “first class UI citizens” like Blaze, React and Svelte (Not tried Svelte, but it’s a cool new UI lib). It also provides Vue integration - though 3th party - but it illustrates that integrations are doable, though admitted not that simple - especially on the HMR part.

Another huge advantage of Meteor is its backwards compatibility and history of baby bottom smooth transitions to major version upgrades. That’s in contrast with Next. Given that Next works on top of React, I must say that the Next team does a good job of simplifying the transitions though.

IMHO. Meteor’s biggest downside used to be its greatest asset, which is its built system. I love Meteor’s build-system, its very efficient in bundling for targeted clients. Old browser? Here’s a special build for you! I challenge you to try and configure that with Webpack! The problem however is that most of the community has shifted towards Webpack, because of its plug-ability (Like WHY?! I just want my darn frontend to load magically, because build tools are boring… aint nobody got time for that? No offence brilliant gods that maintain these things! I truly need and endorse you!). Somehow developers love doing things themselves, because they think they are doing something really special - It’s horrifying. However a new trend is emerging. Vite is an emerging tool that relies on just the basic stuff. It’s VERY fast and simple to setup. Meteor might benefit from this new trend - though there are many directions and options on how to benefit from it.

Another downside (not sure if its solved) is SSR and hydration for Minimongo. If your app requires it, you might not want to use Minimongo. However you could of course just integrate Apollo Server and Client with Meteor and have the best of both worlds: https://www.apollographql.com/docs/react/integrations/meteor/

In conclusion
Admitted. Both frameworks are awesome, but they work on different levels. Next.js, Nuxt.js, Gridsome and many other UI frameworks focus on JUST the render layer. They have excellent documentations and I love the communities (big mention to the Vue and Nuxt communities and of course @evanyou and @akryum who has given us the Vue integration package for Meteor). Meteor is still a league of its own. It works with other tools like Apollo and the different UI libraries. You could even use Meteor’s server and integrate it with Next.js or Nuxt.js! Many devs do this. There are just a few frameworks that sort-of approach parts of Meteor’s API layer functionalities. One of them is Feathers.js, but it’s mainly focused on ‘just’ the API client / server part. Another one is RxDB, but I see that one more as a replacement for Meteor’s DDP, Methods and Minimongo integration. Again, just 1 part of the total picture.

The choice is up to you, but if your focus needs to be on features, I would choose Meteor. If you simply require a UI framework with very powerful features and things like static rendering, use Next. (That is if you decided that React is your tool of choice)

Also if you are working on a large React only project and are considering Meteor, maybe its better that you migrate to Next. However if its going to be an app that requires a BFF, then consider Meteor

15 Likes

This could be a great dev.to article!

2 Likes