Choosing Ember over React in 2016
blog.instant2fa.com
blog.instant2fa.com
I came here to say exactly this. Ember is a fantastic choice and it doesn't seen enough love on hnews.
It's got a bit of a learning curve, but once you climb it then it's plain sailing.
Also checkout Ember twiddle [2] to play around first without installing a thing. You can add libraries and even other Ember adding through twiddle.json
Three or four times I've been about to pull the trigger and every time the things that's stopped me is that when I go to look for a sample project to have a read of an actual app using it in anger it seems impossible to find one that meets my criteria: 1. Uses current version of Ember. 2. Uses idiomatic ember. 3. Big enough to not be a toy, ember-data, being the recommended way of doing things, I want to see how it's formatted.
Every time a look it seems like everyone is saying something along the lines of "Here's a good example project except it's N versions old." or "… except it doesn't use insert-feature-that-docs-heavily-recommend-using because that wasn't around when this project started" or "… it uses local storage in place of a database".
I've read the documentation end to end multiple times over the years. I'm not sure why that's not enough for me. I just assume I'll run into trouble and I'd like to see an application with routing, component composition, backend calls, and understand a bit about the recommended backend before diving in.
Ghost admin: https://github.com/TryGhost/Ghost-Admin
Hospital Run: https://github.com/HospitalRun/hospitalrun-frontend
Hummingbird: https://github.com/hummingbird-me/hummingbird-client
repo: https://github.com/travis-ci/travis-web site: https://ember-canary.travis-ci.org/emberjs/ember.js/builds/1...
It even has a version that tracks commit by commit right off ember#master https://ember-canary.travis-ci.org/emberjs/ember.js/builds/1...
We also have a Slack where you can ask a large group of us questions about it at any time, or just reach out to me using contact info in my profile.
And even that time was largely spent eliminating deprecations, which still worked.
My opinion, for whatever it is worth, is that Ember might be good for smaller companies and smaller codebases. The cognitive overhead of using Ember is massive for me and several people on my team. I find that I have to store the contents of many files in my head at once to understand how a given component is being rendered and how it is receiving its data it requires. Your view code is implicitly coupled to promises all over the place which can really bite you in the ass. Mutable APIs abound and it is an extremely unpredictable and volatile way to develop web applications at our scale.
My personal, largely unfounded belief (based both on intuition and anger from dealing with Ember) is that the supposed gains from Ember's severe convention-over-configuration ideology don't pay off nearly as much as is advertised.
I never want to work on an Ember project ever again.
...disheartening. Because (at least for my team and the specific projects we do), mobx was much much better.
(Disclaimer: We use React to incrementally replace/upgrade pages and panels in a very large admin console. So we have a ton of very small apps that share a lot of concepts, but are still distinct apps. Obviously this multiplies the amount of boilerplate we have to deal with compared to if we were using a single "monolithic" SPA.)
Key advantages:
1) Way, way, way less boilerplate. With redux you soon grow used to the dance of adding a new sub-reducer, a new batch of constants, a new batch of action creators, then wiring up the new action creators to your container, wiring up the new state sub-trees to your container, and boom, now you've got some props that represent your data, and some functions you can call to change that date.
With mobx, you add some new observers and (optionally) some actions to change those observers and...you're done. It feels odd at first; when you're used to redux you're used to setting up a new app (or coming to grips with an old one you haven't touched in a while) as a very elaborate process. With mobx the "skeleton" is done before you even really start. It's almost worrying.
2) Redux has some very specific ways it wants you to structure your project, and some of them are quite good. A junior dev might struggle to grasp what's required to set it up from scratch, but I think for an intermediate dev it can be quite helpful. It strongly forces you to make some good choices about data flow, seperation of concerns, logging, etc. But for a senior dev it can be a little...limiting. I actually know what I'm doing, and sometimes the right answer doesn't 100% fit into the Redux way of doing things, even if the "redux way" is great 95% of the time.
Mobx allows a lot more flexibility. I suspect that could be a drawback in some cases too, but for this particular case, it's quite nice. You can actually implement a number of different patterns on top of mobx, including a redux style state tree, or (as we've done) some Backbone/ActiveRecord style models. Which obviously have a lot of limitations and are great for everything, but are really great for our specific use case.
3) On a related note, redux really needs data to be normalized; you end up devoting a remarkable amount of time to normalizing data (using normalizr or whatever) and then de-normalizing it in your components to handel relations properly, and then figuring out how to modify your normalized state tree in your reducers based on actions triggered in your denormalized component tree. Totally doable, but a pain.
Mobx makes it easy to use references, avoiding the entire issue.
4) Closely related to the last two points, components written with redux in mind often end up with very extensive lists of props, because they end up needing a little bit of data from six different reducers, plus a dozen action creators. It works. It's fine! But...
...with mobx, at least the way I'm using it, you can generally get away with just passing in the relevant model, You keep ending up with situations where you pass your ProductList model into your ProductList component, which maps over the Product models it contains and passes them into a component called Product. Your actions are just methods on the model class. Components with 1-2 props are easier to reason about and (in my experience) easier to test.
All of which is basically just 4 different ways of saying that for me, it lets me type a lot less (which is good), but most of all it lets me think more about the problem I'm trying to solve, and less about the libraries I'm using (which is key).
Redux is just a big switch statement that ingests plain action objects and outputs a modified state object, along with a connect function to bring parts of the state object into your components. Mobx looks quite baroque in comparison.
The second was a dream because we built it after a couple of years dealign with the fallout from a bad ember app (plus "data down - actions up" was now the prescription).
Ember can be really nice if you follow the happy path.
Small sample size for me (2 Ember projects, 6+ React projects), but the entry level engineers to the senior level engineers seem to grasp React/Redux MUCH faster than Ember.
Care to elaborate what that scale is? We're using ember for a new app that expects very large traffic volumes on continual basis with realtime components etc... I've worked with ember for the past few years and opted to use it but always interested in hearing other viewpoints esp for "high scale"
It sounds like an interesting but probably relatively common situation these - relatively experienced developers, but inexperienced where it comes to the front end, who are accustomed to working in a non-javascript language. In this case, sounds like it's python.
Sounds like their senior developers, who previously worked in Python, will now be doing at least 50% of their work in javascript.
If you have to do this, it sounds from this article that Ember is a good way to go. On a related note: I'm so bummed that this is the trend in languages. Just so bummed. Python and Ruby are really nice languages. To have to switch from that to Javascript feels like a big step back in developer happiness.
I'll dig more into webassembly when I get the chance.
I'm quite sure it will catch on with Apple, Google, Mozilla and Microsoft working on it.
I'm intrigued by the server side Swift frameworks coming out right now. If they could replace JS on the server and browser that could be interesting.
I'm a very experienced Front-End developer and a lot of the tooling questions still hit us in the ass. A few years ago we switched from a Backbone framework to React based with Reflux and Browserify. Within 6-8 months the mindshare switched to Redux and Webpack and now we're on to those. But its days to weeks to gain full understanding of those (Webpack is a slog) Unless your constantly keeping up to date every time you start a new project right now you're back to the drawing board on the current state of the React ecosystem.
I love React, I'm bullish on React-Native as well for a lot of use cases. I'll be happier once the community starts to lock in a bit better on a more consistent stack and I'm totally okay with their choice of Ember (curious on why this over Angular if they're doing a follow up ;-)
The question is, have things stabilized now? There's some evidence it has: Redux & Webpack have had the mindshare for almost 2 years now. But a lot of people now recommend mobx over redux, the redux plugin situation is still evolving, react-router seems to have finally got things right with version 4, et cetera.
That being said, I think the above sounds more pessimistic than it really is. For example, redux vs mobx is really two different use cases IMO.
I wouldn't go that far, I'd say it's different ways of thinking about the same problem. Crucially, switching out your Redux stores/sagas for MobX stores should be a drop-in replacement for the most part. Actions are still actions, and stores are still stores. The only/main difference is that for MobX a reducer and an action are the same thing.
That's why we use TypeScript.
I've been using Python for well over a decade and despise Javascript. TypeScript is incredible. React is pure goodness. React + TypeScript is really cool to work with and doesn't feel like a step back in dev happiness.
Of course I miss the Python ecosystem there, but the JS ecosystem itself is improving thanks to Facebook mostly (yarn...). At this point the main complaint I have in that ecosystem is the three layers of transpiling which are causing backtraces to be unreadable.
Also, I'm unhappy about Python's half-assed move towards not-really-static typing. Optional typing is, and has always been, where it's at. Did I mention I love typescript?
Speaking as a Python developer who needed to pick up JS and maintain two Ember codebases this year, getting to know JS has actually been a pleasure. I was dreading it and I cursed it for a while. But using ES6 with Ember has been... pretty nice. There are objectively bad parts of it - some that are historical baggage, others that are just unfortunate (undefined and null!!). Oddities aside, I find it nimble and fun. I like Douglas Crockford's characterization of JS as "a LISP in C's clothing".
* ES6
* React
* redux and redux-saga
* react-router
* fetch
* lodash
* webpack
* post-css
* karma/mocha/sinon/chai
Of all of these things, to build a decent React app, you only need React.
It seems chintzy to bill React for the cost of webpack/browserify. I understand why someone would: it's the worst part about working in modern Javascript environments. But it's a build tool, not a library.
You Don't Need Redux. Most applications that use redux (or any other Flux library) probably shouldn't. Even redux's author has been taking pains to point out how overused redux is.
You definitely don't need react-router, which is an inner-platform disaster.
Billing React for fetch and lodash also feels chintzy (especially when you try to add a surcharge for switching from underscore to lodash).
I'm also not clear on how ES6 is somehow React's problem. Ember developers use ES6 too. Because ES6 is better than ES5.
I'm not saying the Clef team is wrong. If they're happy with Ember, God bless them! I'm just wary of tech advocacy articles that try to make these kinds of stack complexity comparison arguments; I usually find them to be pretty dubious.
React on its own does not compare with Ember.
This isn't because React is bad, it's because React is just the view layer! If we look at it this way, we can re-examine that list as:
* language
* view
* data modeling
* routing
* network connections
* functional utilities
* build
* styling
* testing
And, with React, when you have just a view layer, if you want to build an advanced application, you likely need to add on a bunch of other layers to get everything working. I hear you about being able to "just use React", but I also think that's a an oversimplification the other way: how many applications on the web today are built with only the view layer and none of the others?
After evaluating all the decisions we made in the past when building a React app, we decide to trust someone else to make them for us :)
p.s. the original title was "Choosing Ember of the React ecosystem in 2016" but I ended up shortening it :)
Any attribute of constructing an application you break out, people will build libraries for. But are they necessary? In some of the cases we're talking about --- routing and network connections, for instance --- the answer seems to be a clear "no".
I think this article could easily have been titled "Choosing Ember over building our web framework"
I intend to try Mobx sometime soon but I've also found you can go very far using stateful vanilla React components and no third party state libraries at all.
CSS in JS has many limitations and virtually every alternative adds either another library or some other convention/configuration overhead.
Other frameworks struggle with this as well but it feels like React really shrugs off styling as the community's problem and subsequently there's a hodgepodge of solutions that work in this or that scenario but no gold standard.
What tends to give people so much trouble with styling?
Other comparable libraries include styling into their philosophy, but React is irritatingly unopinionated about it.
Could you elaborate a bit on how the ember-data patterns felt outdated?
In the React ecosystem, I think there's been a pretty stark departure from that general pattern with things like redux and GraphQL, so while we love it, compared to what we'd been using , it felt a little behind.
Does that make sense?
With most kitchen-sink or CoC frameworks, this is kind of the achilles' heel. patterns get codified because they're easy and "good enough" but they DO NOT age well. How does Ember deal with this? Also, what about the ecosystem? Is Ember work driven almost entirely by the core framework, or is there a plugin ecosystem that attempts to have an answer for every problem? (yes Rails, I'm looking at you.)
There was a lot of breaking changes in Ember going from 1.x to 2.x but now api is stable mostly. You need to remember that Ember is very opinionated, that's why maintainability is a lot easier over the time. There is only "Ember way" in most of the things (routes,templates,components etc). I have now around 130-150 files in my Ember app and what is a little iritatin is that routes, controllers and templates are in different files by default if you use ember-cli (you should with ember, it's great, really great tool, one of strengths of ember).
> Also, what about the ecosystem? Is Ember work driven almost entirely by the core framework, or is there a plugin ecosystem that attempts to have an answer for every problem?
You can build full app (with routing etc) without using any plugins at all. But there are a lot of plugins on github that you can use if you need something special.
The only thing I'm not a huge fan of is their JSON-API as a default data adapter, since there's a ton of immature JSON-API server-side libraries with varying levels of spec compliance and completeness. If you're backed by Rails, you're in good shape. If you're backed by Java, you're fairly fucked.
Remember how much the Javascript ecosystem changed in 5 years? There is no way we could have maintained the same code base without Ember; we would have needed to rewrite the app once or twice by now. And with each rewrite small features, little subtleties would have been lost, replaced by some bike-shedding about how we should hand-compose an entirely new stack.
Instead, we upgraded quietly from time to time, and kept all our carefully tuned code and beloved UI tweaks with us. To be honest, the maintenance and version bumps took quite some work, and some early upgrades required heavy refactoring. Ember paradigms changed frequently during the pre-1.0 era, and later React clearly influenced the best practices recommended for Ember 2 (like Data-Down Actions-Up, etc).
But boy is it worth it. Ember-Data is neat, the testing tools are great, the Ember-Inspector add-on is a joy, and the CLI tools gets us so many free features. And we never could have maintained this product without a stable framework across all these years, and the friendly developers community.
Also, to answer your question about add-ons: they're great. Among the core team there is a nice commitment to make many new features available as add-ons (rather than baking them into the framework). And the community solves many common problems for you indeed.
At this point they're pretty good about issuing deprecations a version before they make breaking changes, so upgrading just involves bumping the version and fixing any deprecations that come up, to prepare you for the next version.
They have been pretty aggressive about ensuring addons work with the latest version; you may have issues with newer addons if you're stuck on a very old ember for some reason. `ember-try` is great for running CI against all ember versions.
## Stability Overall very well, we've never done any rewrite (apart from a coffee-script -> JS conversion, but that had nothing to do with Ember).
## Updates Upgrades has been easily, except for the early days. But since 1.5 or so it's worked really well.
## Addons There is a lot of power in the Ember ecosystem, but it also stays away from some things (widgets etc) which I think is great. For, say, a date-picker you'd use an addon (https://www.emberaddons.com/?query=date) or build something yourself.
## Progress Despite having used the framework for several years it's still very modern. Ember has done a good job of keeping up with new technologies without causing unnecessary pain for developers. ES6 modules, good alignment with web-components, ES6 classes, modern tooling etc. None of this wasn't in place in 2012, but Ember has managed to bring it all on board without causing upgrade issues or painful breaking changes.
What exactly about this thing warrants the use of a behemoth of a framework like Ember?
The entire app looks like an optimization of a poor experience in another web service. I'll conserve my cynicism for their actual app, which could have been implemented without even the need of a framework.
What is exactly complicated about a few different screens? I fail to see the need for even a web app here.
Also, I'm not sure I understand any of their arguments. Does it really take days to setup a test harness in anything?
Also, the bit about progressive enhancement -- are we really talking about this still? When using a single page application framework? For an app that does two factor auth. I'd also be concerned about the security surface area for an app like this that pulls in a dependency like Ember, on a third party site during the login/auth experience. It's bad enough that we have third parties pulling in react to display some simple forms and buttons.
As someone who really enjoys his <0.3s page loads (that is fully fetched & rendered, less when from cache) even on mobile it feels annoying to not have a 'middleground'.
For example my current project, which is basically a small website where people can upload artwork, does not need to be a SPA. However, I'd like to integrate some interactivity to make browsing easier. Like a 'browser' view when you click a picture, or in place reloads (so the CSS doesn't need to be reloaded, nor perhaps the JS. However there doesn't seem to be a library for that to my knowledge. All I know are either on the jQuery level where you have small seperated pieces, or the React/Ember/Angular level where you have to write all or nothing in that language.
I wonder if it is even possible to have an 'augmenter' library that just makes existing HTML better (Perhaps with some hints in the 'data-' attributes), or maybe my google-fu is just bad.
[1]: https://allinthehead.com/retro/367/why-is-progressive-enhanc... [2]: https://github.com/jamesallardice/Progressive.js
Still a great framework for large web apps.
Interesting. In my experience the clean separation of layers in Ember-Data (network, serialization, models) make it quite suited to non-standard APIs. I found writing a custom (de-)serializer for a non-standard API to be relatively easy.
Care to elaborate on what were your issues precisely?
Otherwise, you have to write the same code that you have to write in other places... except that w/ Ember Data there are core patterns and its easy to add tests.
Writing Ember against an API that speaks json-api is a magical experience :-D
The company that I joined was using Ember, but their app was more of an analytic dashboard and it didn't really have more than a handful of routes. the amount of views and logic and state that lived on each route / controller was insane. Also, between the few routes you really needed to share state and things got very messy. I'm still with the company today, and the app's routing is still controlled by ember, but we have switched entirely to react + redux and are a lot closer to being off ember completely.
The real boon for us has been the single source of truth and the connect function from react-redux. Basically any component can just declare the data it relies on via store query functions e.g. getLabelsForUser(state, userId), which breaks you free from the uber painful process of passing properties down the entire view tree to child nodes.
I also got a lot better at developing when I started developing for react, because I was no longer writing framework code, I was writing and utilizing my own functions and abstractions.
I'm not saying ember is inferior, but of course there are trade offs to both. I absolutely love yehuda and tom, they are so prolific, but I would be interested in seeing how ember apps fair when there are only a couple of routes but a ton of view logic and state; where does the state live and how is it coordinated. How do you coordinate data across the app hierarchy? Asking because I really failed at that 2 years ago and ended up with a mess, it definitely felt like uncharted territory. Would totally accept developer error.
I was deeply unhappy with the 3x-5x widening iOS and Android JavaScript perf gaps through 2014 and 2015 (TL;DR Qualcomm has completely lost the plot) but in 2016, it's.. even worse.
The good news is, Ember 2.10 looks like a major speed improvement! The bad news is, Android is still 10x slower with Ember.
http://discuss.emberjs.com/t/why-is-ember-3x-5x-slower-on-an...
It would be a bit more even if Apple wasn't delivering substantial speed improvements, year after year, consistently.
As soon as you are working with different platforms (the author mentioned WordPress), you should not necessarily integrate everything all the way up. Because now you have your Ember based build process and maybe something gulp-based for WordPress.
I always try to find frameworks, which has all the things only concerning itself integrated into (say server-side rendering etc.) but then stops there and makes use of preferably the two or three leading tools (e.g. grunt/gulp plugin) for all the other concerns.
That way you can choose a standard stack and only consider new frameworks if they work reasonably well with it.
Alluring, yes. Good? You shall see. When you embark on using an opinionated framework development can, at first, seem easy. It's when those opinions change that you can easily get hurt, however.
One example is an Ember RFC I read recently about the required folder structure of Ember projects. It wasn't clear to me at all why they were even doing this. Like, what were the gains? It turns out the entire point is some magic auto-discovery of things like Handlebars helpers.
My problem with React aren't complaints about front-end tooling and build systems. My problem with React is its emphasis on a tree like relationship among components. This is an unnatural paradigm for application development. Certainly user interfaces can be thought of in the form of a tree, but another way to think about application development is to consider the view a canvas, with areas to fill in.
React's strong tree type architecture makes some forms of common user interface development feel unnatural and ungainly, things like modals, toasts, or things that just don't fit into a neat little area of the screen in a sibling child parent relationship. Also anything that happens after a render, like animation, also has the same kind of unnatural cludgy development process and I often have found myself fighting what to render when with shouldComponentUpdate.
I'm not saying these things are impossible or even hard, it's that they're unnecessarily ungainly when those things should be simple. I've also think in practice that components far down the React tree become second class citizens, the source of bugs, less well designed and often quite dependent and highly coupled with parent elements.
Another problem I have is tooling related, it's the wave updates that you have to deal with whenever React updates. React and many well maintained libraries do this really well but there's always some bad actor in the ecosystem that makes it a pain and frankly I never look forward to a new React version. Again I understand that all these things are problems that can be overcome and I have, but I'm frankly over it.
I know I'll probably be writing React based applications for an employer for a very long time, but I would no longer recommend it. I think vue.js is a promising new library. I think there are things to be said about how React is very good about enforcing modular component development and I quite like flux and redux, but React in general. React is just not great.
That's actually where React is very strong compared to other functional-style UI frameworks (eg: Elm's). Portals in React are really elegant and makes dealing with modals and toasts (or anything that doesn't fit in this model) quite nice.
I was working today with someone who was making a browser extension to inject stuff in host pages (think something like LastPass or those rulers for designers).
We made a set of components that create arbitrary elements at arbitrary locations, or highjack existing ones, and from there you get to manipulate things like you would any other functional-style UI. It's quite lovely (all thanks to the lifecycle hooks and React's ability to render subtrees anywhere on the screen). Very few tools do it as well as React does, otherwise I'd be writing Elm all day instead of JavaScript.
The entire reason for React's existance is to slap escape hatches on top of a vdom so you can work functionally in a non-functional environment.
Conventions over configurations comes to the benefit for small team, beginners and is in general more fun to code with. But it comes at the cost of being much slower in adopting new patterns and innovations. As there is currently so much speed in javascript development happening, I wonder if for now configuration do outpace conventions, until the battle field has settled.
React has acknowledged the situation and tries to get the best of both world with its quest for a React CLI. Did they know about it at the time of writing?
As the perlers wisely said: TMTOWTDI
[1] https://github.com/NYTimes/kyt [2] https://github.com/facebookincubator/create-react-app#altern...
Component architecture, check. Two way binding, check. Optional type, check. IDE, check.
My favorite, typed components, check.
1. create your own build system when something like create-react-app exists
2. use something like redux-saga when promises and async/await would suffice
3. likely you probably didnt even need redux, the application looks fairly small and doesn't look like it has a lot of internal state.
tl;dr you did it to yourself
But you're right, we should really emphasise that "none of the above" is very often the right answer when choosing libraries to build a React app.