If you like Blaze, awesome; use that. It works today and will still work next year. You like Angular, great. You like React instead, great. Just pick one and build something people enjoy.
I’m positive everyone could have learned X framework with the amount of time spent in this thread.
React helps my large apps from crumbling and aligns with the functional methodology (which I enjoy) so I’ll pick that one. You should pick the one that makes you most productive/happy.
My proposal for how MDG should handle this whole situation:
Keep Blaze around as an introductory, “training wheels” solution for smaller apps and quick prototypes. Don’t deprecate it, but make it clear what its downsides are (no code splitting, no SSR, etc.).
Spend as little time as possible on it. Don’t introduce any major new features, maybe just try to get low-hanging fruits.
Transfer control to the community. This can be a gradual process, leading to some kind of Blaze working group that’s independent from MDG.
Recommend React as the “real” front-end solution for any serious production app.
Do not waste time on a Blaze-React bridge or migration path. It’ll take up resource, and nobody will be happy with it since Blaze people just want to keep using Blaze, and React people are already using React.
What does the new user onboarding process look like in this world? Does the front page tutorial introduce you to Blaze, and then at the end you learn about React and it says “if you’re building a real app, use this instead?”
It just seems a bit awkward - I’m not convinced that it’s worth the time having a whole other framework just for training wheels.
Actually, in that world that’s something we’d need to figure out for Discover Meteor, too. One solution would be to start with Blaze, and then give people the option to switch to React in more advanced chapters.
I guess it all boils down to how much easier to learn Blaze really is compared to React. Obviously some things ({{#if}}, {{#each}}, for example) are much easier to do in Blaze, but is that enough to warrant keeping it as a first step? I don’t know yet…
@sacha@sashko
I would propose that it makes more sense to have two versions of Meteor, you can never have both ways without making it mediocre. I think Meteor has an advantage to being the fastest prototyping SPA app in the world if you optimized for that.
Meteor Prototype Edition:
Slow moving / frozen API
Blaze templates
MongoDB as the only database (instead of upcoming ones)
Packages can be marked ‘approved’ so they just work and continue to work
Everything is aimed at creation speed (insecure, autopublish, more stuff like this)
Aimed at assembling leggos that are semi customizable (like accounts-ui)
Rails style generator to make CRUD apps even faster (with standard layout)
Meteor
Focuses on keeping up with the fast moving JS world
Aims at keeping med/large apps maintainable yet easy to build
Flexible view layers
Flexible database layers
no default insecure or autopublish packages
Improved subscription (eg, declarative like Falcor/GraphQL)
This would kill two birds with one stone by essentially just freezing off updates to an agreed ‘version number’. Say Meteor 1.2 will be ‘official’ version. All packages could say ‘Meteor Prototype Edition approved’ and could have a special version tag.
Beginners and prototypers alike can benefit from no restrictions and can build very rapidly and both wouldn’t care about being up to date, secure, or maintainable. However, because it’s just a version constraint there’s nothing from stopping a user from removing insecure or adding React… it would just break out of the ‘Prototype Edition’.
Just my 0.02
Edit I just created a poll in this thread to see how the community feels about this.
React itself will break the principle of simplicity. The paradigm that goes into easy templating will be distorted by an attempt to humor a loud group of non-Meteor developers. Don’t go against your own principles.
React is in fact designed with only React in mind. Blaze is designed with Meteor in mind.
There are people invested in Meteor based production apps. People spending money on working Meteor apps. How do you ever expect Meteor to be a viable option for production if you pull stunts like this. I’ve agitated for Meteor. I’ve heard so many comments of Meteor not being ready. Don’t give these people more power. There are projects that depends on Blaze. There are those of us that would like to see a Meteor-centric Blaze and continue using it. React will die in a year or two, like many did before, let’s not be the one community that died because of concesions. By trying to please everyone you’ll please no one.
avoids hurting existing blaze investments, allows for freedom for the innovators, and upgrade paths in between. heck multi entry points is possible with different learning curves.
Also
using packages it should be fine. However, having docs for blaze, react, angular 1+2 is expected, whether they are MDG or community based, or a mix. What Urigo and friends do with Angular 1+2 shows it is not impossible.
I love Blaze as it is right now. The decision to have Blaze stay where it is and move forward with React seems promising.
I hope to see better Tracker-integration, like what @faceyspacey is doing, for React. I’m getting constant reruns and it’s been frustrating to the point where I’ve moved a couple of projects back to Blaze to have Tracker run correctly.
I think an important question is:
With the deprecation of Blaze, what is the future of Tracker?
I’m overstating a little here, but I think Tracker will be dismantled in favor of something Redux like… This, along with React and GraphQL, will mean the Meteor stack will basically morph into something akin to the Meteor-Facebook stack.
This means MDG will abandon most-all the tech we the Meteor Development Community (MDC) uses. This includes, but is not limited to: Blaze, Tracker, Atmosphere, and more. Basically our entire stack is on the chopping block at this point.
To me this is a false choice, and I reject the premise that Blaze+Meteor is equal to slow changing.
MDG could (despite what they may say) do a Manhattan Project style Blaze reboot, taking lessons learned from React and the other great UI packages out there – and surpassing them all.
Building on the momentum, they could then focus on a Tracker reboot/update and add code splitting for Blaze+Meteor.
Despite the rhetoric I’v read so far, I think we do not yet know why MDG is choosing to replace their stack with the FB stack. Their new strategy seems to be becoming the glue around new innovative tech from FB and others, and that becoming their value proposition, instead of building innovative core tech as they’ve been known for in the past. This core tech is what got Meteor where it is today, abandoning this approach in favor of the tech glue approach seems misguided and shortsighted. I hope I’m wrong.
I’ve been doing a shitload of research in this area to discern whether Tracker is really worth backing up. The downside of the reactive approach React is taking is that it’s taking the “functional” route, not the true “reactive functional approach” which is based on observables taken by tools like Cycle.js and Elm. The difference is that the latter parameterizes time–it makes values over time a standard variable/parameter. Elm and Haskell have gone to great lengths to parameterize values over time as first class citizens to achieve the purity of mathematical equations. When we program, y = 1 * x is an assignment, but in Elm or in a spreadsheet, f(x) = 1 * x has a different meaning: it’s indicating the value of f(x) aka y over time.
Now that all said, Meteor’s approach (called ***“Transparent Reactive Programming”***) is a lot closer to the spreadsheet/Elm/observable approach! That on its own is a good thing. Meteor/Tracker has always been pioneering the “spreadsheet” approach. However it lacks purity; it has side effects. Why? The observable parameters are not in fact passed in as parameters, but are rather global (or outer scope) variables. So that brings along all the problems that side-effects have. But what it gets you is a lot of automation.
But there’s more to it: if all we had to do was pass in observable variables–e.g. the return of collection.find()–we could just, for example, parameterize all our Blaze helper methods. But it doesn’t work that way–you can’t just pass in observables wherever you want; Meteor/Blaze/Tracker expects you to actually call the reactive data source within the function. And that’s just the beginning!–to get the pure observable parameter approach to work, all your code must be running within a sort of loop–um “Cycle”–that consumes observables and outputs observables. This is the approach used in Cycle.js or Elm’s approach with Signals (and a few other tricks Elm has to make this even more natural).
Now this isn’t so far off from what Tracker is doing. Tracker tricks us into thinking our Helper functions and autoruns in general are just standard functions. They too are running in some sort of “reactive container” if you will. But it’s not a complete loop/cycle. It’s basically a hack. The main benefit is that it lets you continue to program in the imperative way you always have, but with side effects. To do it in a fully pure way would require full on functional programming–it seems. I’m researching if there is in an in-between that will allow for the autorun Transparent Reactive approach but with more purity.
Another thing to think about is: what is a parameter? Does it have to be passed in between parentheses (or equivalent in other languages)? Is Session.get('foo') or collection.find() called within a function really not a parameter just because it’s not passed in between parentheses?? What in fact is a parameter? Let’s just say–for sake of keeping this post short–that a parameter is just a variable when used by a function guarantees a given output 100% of the time whenever it has the same value. Then, what does it matter whether you pass it in between parentheses or not. The next place your mind will likely wander to is: what about tests? Ok, so fixtures are needed–you can’t as easily test for a given output based on a given input. Instead, you must do things like populate collections. So the question is again: just because the parameter isn’t passed between parentheses is it not a parameter? Eventually this train of thought leads you to: Is additional setup/teardown work an order of magnitude more work that it rules out TRP in favor of FRP? …and all that is not to mention that Tracker re-runs your functions many times unnecessarily–my assumption has been: if we can solve re-running, is TRP still inferior?
I wish I had the answer right now, and could stamp my vote, but I don’t. I’m still determining whether TRP has a life-span worth building on. I can say that it looks like the industry is determined to take the FP and FRP approach. And that means something. That means “ecosystem”–an ecosystem you won’t have by building on an approach not in line with trends. I also think the same goes for React’s “FP” approach: React too is on the chopping block; Elm and Cycle.js does what React does, but better. They certainly are the future in my opinion. Same with stuff going on in the Clojurescript community (though I’m concerned Om is using React rather than a true observable approach). Either way, React is definitely old news compared to those 3. With React your code just happens to be triggered to re-run (ALL OF IT!), you aren’t using real observable constructs–you aren’t using parameterized variables over time. Time based variables. Units whose value represents a lazy list of sorts, but which you can compose like any other variable. That to me seems to be the future. TRP is closer to FRP than React’s FP approach in fact. But its lack of purity will likely get it into trouble as tooling expands around pure functions (observable or not).
That’s my conclusion. I’m still looking into whether it’s worth optimizing Tracker, etc. But first I personally must master Elm, Cycle, clojurescript, etc–and more importantly, its concepts–to really be able to say. That’s my sentiment at least. There may be something else, totally different, out there that trumps all of these (which is always true given the ever-evolving nature of software/life). But you gotta work with what you got to start. I’ll end by saying this: what Elm is doing is a thing of beauty; Cycle.js is doing something close, but it seems messier and more limited but makes up for it given it comes in the flavor of a way more accessible language, namely javascript. Once I know exactly what Elm does that trumps Cycle.js I’ll get back to you–it likely has to do with Elm’s use of types. Elm gets a lot more value out of Types in your daily work than Java does for example. Clojurescript similarly–even though it’s dynamically typed–uses protocols to achieve similar things. Basically custom overloading because of types seems to allow for a lot of natural constructs, particularly when it comes to an Observable time-based type–you end up using an Observable/Signal variable 100% precisely as you would an array/list. Everything just seems to fit like a natural equation. Cycle.js has this feel of endless chaining, which feels less like quality programming. On a side note, I love clojurescript’s concept of Transducers (and its constructs to achieve it). Elm seems to take that stuff to the next level in its combination with time/signals, which were a first class concern when designing the language.
Some changes are good and should get in sooner than later (ex: ES2015, more intelligent dependency control system a la webpack, hot reloading, etc). Others are a matter of taste.
An old saying in my country says that “to make happy everybody, you end up to make everyone unhappy”. That is exactly what it feels like. I think Meteor sometimes suffered of chasing the fads more than solving the biggies. There is too much relativism in the Javascript world today. Too many options and too many choices most of them with their pros and (do not forget) cons.
For example for me supporting Blaze, React and Angular is going to be quite a challenge. If you want to build packages you have to do it in the Angular way, the React way or the Blaze way… how much time is going to be wasted by the community to rewrite the plugin X that was originally written in Blaze for React or maybe for Angular… Now I also have to think “Which framework is going to be the one that sticks?” And try to do a good bet so I do not have to redo everything later when some options are abandon. . At different times I used Blaze, React and Angular. My favorite is … It does not matter. But this relativism “Meteor is just a collection of packages, choose your favorite flavors” leads to confusion and waste ton of community time in rewriting, refactoring, dealing with each different edge case related to permutations in the plugins…
Part of Ruby On Rails’ success came from making things opinionated and simple. When I used Backbone, I used to find 3-4 ways to solve a problem and wasting time to find out why different people used those different solutions.
I think that sooner than later it is better to make bold decisions and stick with them. Evolve them but unless something it is clearly 4x or more better, do not disrupt the past. And frankly in this matter, waiting a little is a good strategy. Time wipes fads and make good choices to stick around.
It would may be faster to fix the problems of Spacebars, did you consider that? I agree with Slava here on the problem of Handlebar. Cannot this be fixed?
As an entrepreneur I want to spend time building my product, not chasing the latest changes and waste 50%+ on my time on refactoring code that is already good and work just because I can run on v1.3 best practices instead than v1.2… because it is going to be pretty much the same story with for v1.5, v1.6, etc.
I wonder if @gschmidt looked at Elm and Cycle.js before deciding that React is what Blaze 2 would look like:
It also makes me wonder if choosing React and the FB stack that will surly follow is more strategic than technical.
Are you in any way communicating with MDG on your findings and if so do they seem open to taking outside input and perspectives (and by outside, I mean outside MDG’s very tight circle)?
Thanks for taking the time to post this by the way.
I think Transparant Reactive Programming like tracker has definitely a future. It just has to be improved. The TRP philosophy behind tracker and Mobservable is pretty much the same.
But Mobservable makes a very strict distinction between autorun and computed values.
Autorun always produce side effects, because sometimes you need them to bridge to non reactive pieces of code like making network requests etc.
On the other thand there are computed values, which need to be pure functions of the observable state. Although the state is accessed through closures instead of parameters, all the other typical properties of pure functions are enforced: The should produce values and cannot have side effects (e.g. it isn’t allowed to change other observable values (this is checked). So evaluating a computed value with the same state always yields the same result. This enables massive optimizations. Purity isn’t imho not about the way parameters are passed in, but about idempotency, memoizability, cachabaility, side-effect freeness and the possibility to either evaluate eagerly or lazily.
The primary challenge here is too teach people that they use autorun to often; in general you shouldn’t use autorun to respond to state changes but write derivations in stead (like serializing data, building an UI representation, apply search patterns can all perfectly be derived). When sticking to this rule code becomes generally speaking very elegant.
As explained in my latest blog unecessary computations can be optimized away completely when using derivations that consists of pure functions. When applied to react for example it also removes all unecessary renderings, fixing the issue of unnecessary renders you mentioned.
So I definitely believe TRP has a future, it solves some issues that are not solved properly in Cycle (or actually, RxJs) imho:
Glitches cannot be avoid and developers need to manually construct the ‘dependency’ tree, but using operators like combineLatest. This is suspectable to under / oversubscribing and not very declarative. People are confused a lot with all the operators available in RxJS.
Developers need to manually dispose / end streams in many cases, otherwise there are a still a lot of unnecessary combinations that are run.
TRP allows for much better runtime optimizations: For example when using combineLatest but not using all streams in the function body some streams could be halted / disposed (possibly temporarily)
Expressing state as values over time still feel unnatural to me. I really like RxJS when manipulating time matters; for example when throttling. But to express a counter as the sum of all past tick events is a bit quirky imho; it isn’t really that pure; state is very much determined by the inner state of the streams; all the past events. Having explicit objects with values are imho easier to (de)serialize and test (some argue that RxJS shouldn’t be called FRP because of its focus on reacting to events time instead of declaratively reacting to state changes like Excel)
The issue with Redux (and ELM?) like approaches imho that they require a state tree. Even abramov admits that full topdown rendering of a state tree isn’t scalable. (While that is actually the simplicity that attracts people to Redux in the first place). But when you start applying connectors and such you get the same subscription mess like everywhere else and it is still hard to get it performant (+ bloated actions).
I think that is precisely what makes TRP elegant; it scales really well into large applications without more complicated code then you need for really simple apps. Also describing the state / domain model is way more flexible; with TRP you can use cycles, ensure referential consistency, use classes etc. So imho TRP is less opiniated to your stack than a lot of other approaches.
So I wouldn’t declare TRP dead to quickly, I think the conceptual model is very strong and remaining syntactical inconveniences can be fixes once ES6 proxies are generally available.
Good to see you here @mweststrate. I meet Mobservable today, I see the “word” on various post and google search´s but until now I didn’t know anything about. I migrating a App from Blaze/Tracker to React/???, Right now I don´t know what choose: TrackerReact, Redux, MeteorFlux … Mobservable?? … it took me time to learn Javascript, Meteor, MongoDB, Blaze and Tracker …
The magic behind Tracker is invaluable is a shame that his creator is not more involved @glasser.
@mweststrate a Mobservable/Meteor examples/article will be invaluables for incomers/newbies.
I totally agree with you on the advantages of a well designed TRP model, especially for large applications with a lot of state views. I just wouldn’t oppose this model with the possibility of having a state tree ; being able to serialize all components state into one big data structure is very appealing. For instance, in development having to replay 3~4 clicks/actions to get back to the state of the component you are working on is very frustrating and time consuming.
Last time I encountered Mobservable I didn’t read its Gitbook documentation, but your comment here motivate me to just do so Maybe you address this question of full state serialization in it?