By the way @sacha - thanks again for another awesome State of JavaScript survey! The level of effort you put into these survey’s (among the many other things you’re working on) is really quite incredible. Your work on this is greatly appreciated - I can’t wait to see what next year brings!
It’s interesting to see for me as someone that only learned about and picked up Meteor in the last 6ish months. I can’t really understand why so many that used Meteor are no longer interested.
Occasionally I run into old criticisms of Meteor, and they seem to be either already solved, or to do with changes that made Meteor more like the rest of the JavaScript ecosystem
Either way, despite having to deal with a lot of legacy spaghetti Blaze code, I’m happy with where Meteor is and where it’s heading
Better documentation on Minimongo + REST/JsonRoutes solutions might address a lot of the concerns that push people towards Express. DDP is great for optimisitic UI; but the State of Javascript in 2017 is that REST endpoints are still the standard in the majority of businesses I talk with.
“It is difficult to get a man to understand something, when his salary depends on his not understanding it.” – Upton Sinclair
Cough.
I’ve been using Meteor for two years now and have really been pushing it to the max with now Apollo and GraphQL, REST endpoints, and intensive real-time applications with large data sets. I still love Meteor. That said, I think the two biggest reasons many devs don’t use Meteor is
- They make standard websites and not web apps. Meteor is not great for basic websites because of poor SEO and initial load times. There are solutions for better SEO but who wants to need to add services to get them to work, when normally you don’t have to? There isn’t a clear benefit to learning Meteor here.
- They don’t want all their eggs in one basket. If their company survives but Meteor doesn’t, that’s a big risk. It could also be seen as something that’s hard to integrate with and scale because it feels monolithic. The scaling problem has been figured out, but it is more complex to scale than a traditional web app because of its heavy reliance on websockets. Integrating also has some truth to it because it’s not as straight forward to build a REST API with than say PHP. With Express, however, the process is damn near identical. This might not be as much a real problem as it is a perceived problem.
Meteor has a lot of pros for me. The reactivity model is brilliant, I don’t need to build an extra API or data access layer (huge time savings). Authentication is done out of the box (I used to not be a fan of this, but once you’ve figured it out, it’s really easy to replicate across projects). I also found real benefit in the atmosphere community of packages, and now even more with NPM integration.
I’m also excited about being able to use GraphQL with Apollo now. It does sort of feel like a step backwards… because it’s more complicated to set up and subscriptions are not automatic like we’re used to with Meteor, but I like the benefit of being able to serve a GraphQL API to third parties and use different backend data stores. I think for that reason, the standard pub/sub model should stay in place. GraphQL is too complicated starting out and should only be used when needed, and the benefits outweigh the cons. I also personally don’t know what was wrong with Blaze. I still like it and find it much more understandable than React. I don’t know if I’m the only person who feels that way? React might be ahead of Blaze by a couple years, but Blaze is still 10 years ahead of a lot of things that are out there, and a dash more friendly too. Dropping it I feel was premature.
Meteor has going for it its simplicity and ease of use. That is what constantly sets it apart. Be sure to keep that.
Well, my biggest issue is that it has been dropped by MDG…
I was very happy with Blaze, but saw that the bandwagon is going clearly into the React direction - after some funny loops along the way. I like the modularity of React and won’t switch back, also because Blaze code quickly turns into some kind of Spaghetti, no matter how hard you try to avoid it.
But I’m not sure if I would have gone all-in with Meteor if it hadn’t been that easy using Blaze. I still think that Blaze should be a first-class citizen, along with React.
I wholeheartedly agree. It still is there beside React for now, but MDG dropping Blaze support doesn’t look good for the future (I still have issues open there that haven’t received a response in months). I think replacing Blaze with React and replacing Meteor’s pub/sub minimongo model with GraphQL would be shooting themselves in the foot. Yes, they offer more flexibility, but it’s a heck of a lot harder to learn. I don’t believe I would have invested so much in Meteor either had it been for that.
All Meteor really needs is an easier to access and configure server router (probably some connect middleware would work). If it had that, and it was clearer how to turn off the DDP socket connection, Meteor could be quite lovely even for static website type stuff.
We kind of have a solution to that with SSR now. But Flow Router is still the recommended router in the Meteor guide, and I think that’s a mistake outside of maybe Blaze (does Flow Router even support SSR), because for Angular, React and Vue.js there are much better alternatives. Also, Flow Router has the optics of being abandoned, which isn’t great.
For React apps built with Meteor, React Router should be the recommended router, and the guide should show how to set up SSR with perfect code slitting right from the beginning. (I wish I had the time to contribute more!)
In the 1.6 release notes, there is a note about how things will change - even a reference to Vulcan.js (which I like, but I find the setup to be arduous compared with the simplicity of Meteor). There’s also a coming multi-bundle subsystem which will enable things like offline first publications filled through web workers (I have that set up for a couple of sites now - it’s slick!). All of this is pretty exciting!
What exactly did you find arduous? We definitely want to improve the first-time developer experience, we know it’s a pain point.
Hey @captainn, I have been thinking of something like that myself. Could you share some details of your setup? I’d even encourage you to do a blog post about it; I’m sure it will be very well received by many out there looking to improve their Meteor app’s initial load.
Sounds like you’d probably like Vue! We used Blaze for a medium size app, then used React for a new development, but while I felt Blaze was lacking in a lot of ways, I feel like React/Redux is unnecessarily complex. Now I’m starting with Vue and really liking it. Never heard of anyone switch from Vue to React; but plenty going the other way.
Sure - I could write a blog post.
I’m basically using an action creator (I’m using redux/thunk - but it could be any function, tied to a route, or some load event), which sets up a computation, and watches the remote store through either pub/sub or a meteor method (super easy to swap that out with apollo), then updates a local ground:db for offline storage (this could be swapped for a redux backing store too, there are a bunch of middleware for that).
On the React side, I drive everything out through a Meteor connector (withTracker
), always pulling directly from the offline store from ground:db. It keeps the front end code super clean.
There are a couple of sticky spots - I can’t update ground:db with a full document, so I have to remove/insert each time, but that’s not a big deal, as long as you key everything off a unique identifier (the mongo id works).
For loading from a method it’s super easy:
export const syncGamesList = () => (dispatch, getState) => {
dispatch(gamesListLoading())
Meteor.call('getUserGames', function (error, games) {
if (error) {
dispatch(gamesListError(error))
}
GamesOffline.clear()
for (let game of games) {
GamesOffline.insert(game)
}
dispatch(gamesListLoaded())
})
}
This uses redux to marshal the status flags through the system. On the loading side, if there is anything at all in the offline cache, I override these flags (set to loaded) and load from cache. In the future, I’ll display anything from the cache, and use the redux flags to show a “syncing” ticker or something.
There are other aspects of offline first to consider - you need a way to cache the app bundle, and css files for use offline. Fonts and some images also need to be cached. I use Meteor’s appcache
package for those things, because it’s supported by every browser today. It was difficult to get the service workers overall size down far enough at first, but I submitted a patch which avoids including dynamic files in the cache manifest, which helped a lot.
Service workers are only supported by Chrome and Firefox. Eventually I’ll use Service Workers (they provide some benefits, like on Chrome for Android if you want to trigger an “add to homescreen” dialog, you have to have a service worker). There is an API in appcache
to disable that on a per browser basis, which I’ll use when I replace that with Service workers. Service workers require additional bundles (technically, we could just feed it your main bundle, and do some feature detection in there, but that’s a lot of extra overhead). Service Workers also have a Cache API, and I’ll probably use that for anything that it replaces from appcache, but most of the rest I think are better in other solutions - like ground:db, because that is supported by more browsers (and the code path is already mature).
Content (and route) specific links, like images, also need some special consideration. Right now I’m just using the standard browser cache, but will probably start to stuff all images into indexedDB and draw them from there eventually, as I can better control the cache that way (I think).
Eventually I’d like to place all that syncing code (above) into a web worker as well - that way all that loading runs off the main thread, and web workers still have access to the offline cache backing store in indexedDB. So it’ll work pretty much the same, except no hiccups on the GUI!
Once it’s possible to do additional bundles to support web workers and service workers, I’d love to do a blog post.
BTW, there are a couple of things to finish before I have what I would consider an ideal offline solution:
- Remove dynamic js files from
appcache
(this is done!) - Additional js bundles - for workers - web and service. (this is coming soon!)
- Preload dynamic modules when offline functionality is desired and make sure modules load from the cache if we are offline. Dynamic modules are already stored in indexedDB - so the cache part is already done! (I’m going to attempt a patch for this if I can find the time.)
- Create a service worker with Cache API to replace
appcache
for compatible browsers.- This could be based on a configurable Service Worker API, since Service Workers can be used for more than just caching. Either that or we just register multiple Service Workers. There may be a reason (particularly a Cordova based polyfill for iOS) to try and structure any SW API to only register one Service Worker for Meteor’s general use.
I think that’s actually it!
There are a couple of things to consider for implementation:
- The
dynamic-imports
package should be aware of whether or not an offline plugin is installed (appcache
or something new), and preload dynamic modules if it needs to (this is my next task). - The
appcache
package could be modified to be aware of the presence of aservice-worker
package, and wrap its API to use the modern Cache API, or it could just turn itself off if a newer (and better)offline
package is installed (this would be my preference), which would use theservice-worker
package, or just create it’s own service worker (this way is less complicated).
last time I looked Service Worker is enabled in the new Safari preview builds! so polyfill for iOS may not be necessary much longer.
I think Apollo adoption would be much higher if the official tutorials were kept up-to-date. Much of the code does not work anymore, and calls for an update by frustrated users (including myself) have been completely ignored.
Meteor is fine. An opinionated full stack framework like Meteor is never going to fit everyone’s needs. As it is, the changes over the last year or so have alienated a lot of early Meteor users and this forum is full of threads about how things have become too complex with the addition of npm etc. As Meteor tries to gain more adoption within the wider JS ecosystem this is inevitable.