Hacker News new | past | comments | ask | show | jobs | submit login
I created the exact same app in React and Vue (medium.com/javascript-in-plain-english)
301 points by techbio on July 29, 2018 | hide | past | favorite | 180 comments



As far as I can tell, Vue doesn't introduce anything new over other front end technologies. It's ironic developers who complain about React being the "new hotness" turn to Vue. It's the same core concepts as Backbone, Knockout, Angular, Ember, and the countless private frameworks we've home-grown on top of jQuery in our front end jobs. This is highly stateful, object oriented, mutate-by-defualt, class based, imperative programming, with imperative DOM manual wirings, separate templates from view logic (probably the biggest sin), and programming by non-transferable conventions (v-model="todo", this.$parent.$emit). I don't even want to know the implicit magic that makes list.push() update the view (notice how the author of the article doesn't know either!), but this is again the same as all of the above.

While I don't personally prefer any of the above style, the point is not a criticism, but to point out that fundamentally Vue doesn't seem to offer any different core concepts than other frameworks. I think it just hit a sweet spot timing of being a React competitor, when developers who didn't like (or, I suspect, don't fully understand) React's fundamentally paradigm and convention shift. As a biased pattern match, most times I see people comparing React to Vue, they're new to both, and don't get React.

I'm biased, but I'm biased through experience. Building Backbone apps where you glue events to DOMs written in strings with magic stateful data classes, and then scaling and debugging those apps, _sucked_. We didn't know any better back then, though, because we didn't have React to compare it too.

React can introduce problems (like any framework), but instead of trying to jump through hoops of convention, custom data binding and HTML tags, now my problems are my own. They're problems of composing functions or structuring my data flow. React is so thin that it's rare to have a "React" problem, now I have vanilla "Javascript" or even "function" problems, and it's such a breath of fresh air. Even when I'm debugging performance problems, I don't feel like I'm dealing with React, I'm dealing with comparing Javascript objects.


Vue doesn't really introduce anything we haven't seen before indeed.

Fortunately it doesn't regress from what we have learned before either.

The most important factor in favor of Vue however, is that it 'just works'. When working in the reaction ecosystem I feel like I'm constantly trying to couple together chains that call functions on functions on objects.

Then there's the components that have bugs that make them fail in the most basic of situations.

And lastly I have to write 3 times as much code to get all of it even running.

Give me Vue and it's magic any time of the day.


  When working in the [react] ecosystem I feel like I'm 
  constantly trying to couple together chains that call 
  functions on functions on objects.
This is a very good explanation of how I feel as well. At work I use React, but on sideprojects I'm a Vue fan. React feels like layers and layers of render functions, with chains passed down and pared down as you get deeper, which becomes excessively cumbersome to reason about. Vue feels like it compartmentalizes things much more effectively. A component can just be a component, not a stateless function that renders a react component that wraps around a redux plugin component, with each step having its own little isolated DSL.


> React feels like layers and layers of render functions, with chains passed down and pared down as you get deeper, which becomes excessively cumbersome to reason about.

This reads more like a design problem than with React. React gives you the component and some good practices and advices in the documentation, but how you compose them is in the end your responsibility.

> Vue feels like it compartmentalizes things much more effectively. A component can just be a component, not a stateless function that renders a react component that wraps around a redux plugin component, with each step having its own little isolated DSL.

I think it's unfair using DSL here. Even Redux makes a big point out of not creating too many conventions nor sugaring, and people actually complain about the boilerplate. Redux's `connect` is a function that does no magic: returns a function that will return you a component (which like you point out could even just be another function) with props mapped as per your initial arguments. No DLS, no magic.

That a component can be just a component, not a stateless function to me doesn't make much sense, given how functions are primitive constructs and components are not. I think the fact that components can be just stateless functions is good because it means composing components is no different from composing functions.

And again, if a stateless component renders another component and wraps a redux connected component it either makes sense based on what the developers are trying to achieve or maybe they are just over-complicating things, but React wouldn't be responsible for either decision.


> React feels like layers and layers of render functions, with chains passed down and pared down as you get deeper, which becomes excessively cumbersome to reason about

This is like saying recursion is hard to reason about because you're dealing with a function which calls itself then calls itself then calls itself and there are layers and layers of calling itself with chains of arguments passed down through the many layers.

> a stateless function that renders a react component that wraps around a redux plugin component

IMO React's recursion makes it much easier to reason about than something imperative like Vue, while its function composition enable powerful patterns for reusing logic.


Recursion IS hard to reason about, and then implementing it efficiently (in a runtime / compiler) is also hard, and then an efficient implementation restricts your expressiveness, and then when someone else needs to read such code, it's hard for them to reason about it.

There are actually a lot of similarities with React.

Neither are useless nor bad per se, but given options, in majority of cases both are more of a smartass thing to do rather than the most optimal or most maintainable / developer friendly thing to do.


> Recursion IS hard to reason about, and then implementing it efficiently (in a runtime / compiler) is also hard

Regarding recursion, I find that recursion is easier to understand than an equivalent while-loop, but maybe it's personal preference. Also, most people shouldn't have to worry about optimizations like tail recursion.

> when someone else needs to read such code, it's hard for them to reason about it.

I'll admit, there are a few negatives with React, but they don't outweigh the positives. Micro-optimizations in user-land should never be seen by designers and if they are, then something is wrong. React's diffing algorithm is a leaky abstraction and forces the designer to be aware of component optimization, since how you break up your components affects how much work the diff has to do.

The new context API is inelegant and it feels like a square peg in a round hole. Additionally, shouldComponentUpdate is the wrong abstraction -- it is very imperative and it pushes you to break your components down into smaller components even if your app's organization suffers.

Reusability and organization should be the only two reasons for creating new components -- performance shouldn't be a plausible reason, because it creates a higher degree of overlap between the developer and the designer.


Recursion is hard to reason about. As a teacher, it's one of the first concepts my students have a hard time with.


Seeing those quasi-JS expressions in HTML attributes is enough to put me off Vue.

I understand why people feel overwhelmed with the whole React/Redux/Router/Saga stack but you really don't need most of that when you're just getting started and React itself is quite simple and elegant.


> Seeing those quasi-JS expressions in HTML attributes is enough to put me off Vue.

They are supremely useful. Ultimately, it's knowing how to use them to their maximum potential.

I've been coding since '02-ish. When I code with Vue, I have an App Developer mindset, rather than a web developer jQuery mindset.

When I use an attribute, it's just referencing a variable. It reacts to its own state in real-time.

I'm not the best at explaining. But with a legacy mindset, you have to interact with the DOM in some way. Whereas with HTML attributes in Vue, you can use the state in the local component to determine whether something is shown or even if a particular class is shown depending on what the state is of a variable.

Even better, that could be a computed variable or one that's watched. This functionality allows a bit of logic to then be run to determine how that variable behaves. This alone minimises the code I need to write in terms of legacy applications. Which also leads to less bugs.

Using if, for, show, and binding classes are very very powerful. I rarely interact with the DOM now and everything in state that is complex is an array. I can write way more complex apps with Vue, than I ever could with jQuery.

About the examples given here by the developer. You can still see that he's coding with a legacy mindset and that he hasn't internalised a lot of what Vue offers.

Some minor nitpicks:

- No need for this.$parent.$emit. There is a better way to use $emit.

- this.$on. <- What is this? An Event Bus? This should really have been a method.

- No need to use id attributes at all.

- Why not pass in the index attribute (which he is not using) to the delete function and then he can simply splice the array?

If he wanted to be real flash. He could have written the ToDo component as a JSX render function and taken the array from the parent and looped out the list. I know the Vue community looks down on it, but would have been a better way of going.

I don't really want to seem like I'm crapping over this. I'm not. I've only been using Vue since April myself. But there seems to be a lot of mistakes here and it's just not idiomatic.


Hi there - Thank you for taking the time to read and review, I really appreciate it. I wondered whether you would be interested in making an update to the git repository with the suggestions you have made. I'd be more than happy to update the article and credit you for your input. If so, the link can be found at: https://github.com/sunil-sandhu/vue-todo

As an aside, I thought I'd let you know that I've been a developer for just under one year, so admittedly do not have anywhere near the level of expertise that you have. I've also only been using Vue since April, but I guess that my level of overall experience, relative to yours, is lacking somewhat.


Back in the day before React was a thing, I got invited for an Uber interview. Their standard challenge is to make a sudoku app on GitHub before they even see your face.

I got ambitious and tried to do with Vue.js and learn the framework in the process. Magic state updates were nice when it worked but with deeply nested models it always failed and I had to hack around to force it to update. I spent a ton of time fighting vue magic. I was ambitious. I wanted to make a generic NxN sudoku game where N was a url param.

Overall vue was like angular, done slightly well but it still had angular like problems where the magic failed and you had to dig very deep in code. It was also very slow to update the Dom. I had to revert to DOM element mangling just to speed up initial shuffle algorithm. I believe vue2 got on the vdom bandwagon so that’s nice.

I finally got it done, with two loooong nights.https://github.com/nojvek/uber-sudoku/blob/master/README.md

Uber did meet with me face to face but I didn’t want to move SF at the time and they didn’t have a Seattle office.

Overall vue has great ideas, probably good for a small project, but if you want to do a big SPA, I would not recommend unless you are really prepared to learn the internal magic.

Nowadays I really prefer preact. It’s the React api, it’s small, fast (has a better license - before Facebook got its shit together). One can read the entire source code in an hour or two.

It does one thing, it does it really well. This is what I like to see in libraries.


Really nice job on the Sudoku!


Thanks


I'm pretty sure React was already a thing when Vue started out


> > Seeing those quasi-JS expressions in HTML attributes is enough to put me off Vue.

> They are supremely useful. Ultimately, it's knowing how to use them to their maximum potential.

Supremely useful for a typical full stack developer -- yes. Supremely useful for a dev team with members who specialize in web design (plain HTML, CSS, etc) -- not necessarily.

When your source code mixes a bunch of different web technologies it limits the types of developers who can effectively work on it.

Many commenters here regard React and Vue as "easy", but for many designers it's not easy. There are plenty of talented web designers who are just not interested or not capable of working efficiently with React/Vue.

Our company built an in-house JS component framework that is heavily inspired by React and Vue but that doesn't suffer from the intertwining of disparate web technologies. HTML, CSS and JavaScript stay separate from one another. As a result, our designers can independently iterate on UI without needing to touch a bit of JavaScript or quasi-JavaScript constructs.


Coupling the CSS and JS and HTML isn't a random design choice. It came out of some very useful styleguides for AngularJS (and other guides too, I'm sure). These guidelines suggest grouping the CSS and HTML and JS together when they are related. It makes a lot of sense in larger applications, but maybe not so much for server-rendered static pages.

There are global styles, and there are styles that are relevant only to a particular component. Hoist styles up to a global (or more general) layer whenever you can, but I really appreciate the fact that I know the important styles I need will be in the same file/folder.


> These guidelines suggest grouping the CSS and HTML and JS together when they are related. It makes a lot of sense in larger applications.

I absolutely agree with you on that.

It's important to point out that grouping and intertwining are two very different things. If you are building a large client-side rendered JavaScript web app, then it is very beneficial to group together the JS, HTML and CSS for a particular component. That's what we do too. However, it is highly debatable whether the JS, HTML, and CSS should be intertwined together (i.e., literally mixed within the same lines) and controlled using framework-specific quasi-JS syntax. As I mentioned above, when you do the latter, you will unquestionably limit the types of developers who are able to work effectively with the code base.

If your team is comprised of a bunch of full stack developers, then you won't face much limitation. But if you're like us and your dev teams include web designers who are JS 'lightweights', then it's a problem.

Reading your other comment from above:

> I hate seeing code syntax mixed with markup syntax. You can end up with hard to parse views (reminds me of PHP and Rails), and abstracts the final HTML structure from the developer.

You hit the nail on the head -- I couldn't agree more.


If your designers aren't programming, they probably don't need to write HTML/CSS either.

Full disclosure: I'm a founder of Pagedraw, which lets designers make UIs as easily as they draw them in a design tool, but are production ready. The designers don't need any code, but programmers can connect it to Javascript data bindings/event handlers as needed.

No one has to write HTML/CSS by hand any more.


If it is so good, why don't you open source it?

Edit: not sure why this is being downvoted, I am genuinely curious.


I'm not arguing that our framework is better than React or Vue -- our framework just works better for us.

We do plan to eventually open source it, but there's a lot of work to be done before a public release: better documentation, better tutorials, remove some constructs specific to our company, etc. We've open sourced some of our internal JS libraries before and it's worked out well -- the contributions submitted and bugs reported by others have been very helpful.


There is a reason for all those mistakes in react : it's more complex, it's harder to learn and getting it right. Also the documentation is nowhere as good.

Ease of use is a feature.


I'm the opposite. I hate seeing code syntax mixed with markup syntax. You can end up with hard to parse views (reminds me of PHP and Rails), and abstracts the final HTML structure from the developer.

I think a much nicer way to work with templates is to see your markup with the same structure it will have once rendered, and attributes that describe those elements (just like real HTML attributes).

When it comes to accessibility, and creating predictable interactions without elements snapping around, I find it easier to visualize the end result when the markup isn't littered with text that won't be rendered.


JSX is not markup


JSX is PHP-mix-HTML templates and JSP all over again. Those that fail to learn from history are doomed to relive it.


It's not. It's nothing but a `React.createElement` function call. It's a paper-thin XML-like DSL over real unadulterated JavaScript code.

HTML-in-PHP wasn't PHP. HTML-in-JSPwasn't Java. JSX in JavaScript is JavaScript. And that is a whole world of difference.


To add, you can get very far without Redux! There's a significant subset of Reacticians who think React + Redux are an inseparable whole, and that setState is evil. I really liked Meteor's approach using live-collections in the browser for handling data. The action/dispatch (or whatever) paradigm that Redux forces upon the user feels slightly over-engineered for the problem it solves, and I think it's a source of additional complexity for new users.


Yeah exactly. You can build some fairly complex apps with React alone. Redux itself is also not too hard to understand IMO even if it does add a lot of boilerplate but once you bring in redux-thunk or redux-saga to deal with async actions the learning curve gets very steep.

I haven't tried it yet but I'm definitely going to investigate mobx for my next react app.


What are some good tutorials to learn building apps without redux (in your opinion)?


I'm not sure about specific tutorials, but you could look into MobX, Apollo, Minimongo, and other reactive client-side data stores. I thought Meteor collections had a simple API and I think separating reactive-Minimongo from Meteor might still be an unsolved problem. IIRC there were a few people from React working on it a few years ago.


> As far as I can tell, Vue doesn't introduce anything new over other front end technologies.

That's what is great about Vue. It consolidates all the idiosyncrasies of the countless private frameworks that we've home-grown, and presents their features in a standard fashion that we can use across jobs. We can look at other people's code and understand it. It's exactly what experienced front-end developers do when they do it their way.


> hit a sweet spot timing of being a React competitor, when developers who didn't like (or, I suspect, don't fully understand) React's fundamentally paradigm and convention shift

React is elegant and simple and I think most people understood it. I think they were less excited about the licensing, which was probably responsible for things like Vue and Preact. Personally I don't like Vue -- the "magic data" is touted as a plus, but IMHO it's room for confusion. At least when I setState in react, I can see the function call to "setState" implying I'm queueing a reactive change.


"I'm biased, but I'm biased through experience"

BAZINGA!


I agree with you for most of that, though I have definitely run into cases of "React" as a paradigm getting in the way. I'd love if someone here has a good solution.

The inherent problem I run into with React is that it's "context-less", in the sense that the "React way of thinking" makes it hard to represent things like animations where you care about the previous state and how you got there. So in my case, I'm doing a multiplayer boardgame. Someone plays a card, I want to animate the card getting pulled from one deck and shuffled into another.

The best solution I've found so far is to add extra "annotations" (using terms loosely) into the current "board state" that represents the changes that happened, and that allows me to queue up the necessary animations. But that feels clumsy because it means persisting stateful data into the data structure alongside the actual "pure board state".


Well without knowing the specifics of your use case, the two most practical react packages for animation I've used have been react-move and CssTransitionGroup.

They both work on the principle of toggling the animation based on a property "show". It's pretty great!


React is certainly more elegant than Vue.

But for me, the key question is which allows me to build faster. Does elegance mean I will spend so much less time fixing bugs that this benefit outweighs the much smaller amount of boilerplate required to put an app together in Vue? I don't really think so, but I haven't come to a firm conclusion either way yet.


> React is certainly more elegant than Vue.

It's also slightly more powerful.

- It has more functionality when it comes to JSX.

- It handles reactivity better.

However, judging the comments by Evan in Mays webcast. He mentions these two will be resolved by 2.6, 2.6-next.

I think the gap will be closed somewhat.


Actually, you can do jsx in vue. So it should be on par, except it has mobx-like state management built-in.


> Actually, you can do jsx in vue.

Never said you could not. The difference is that React is way more powerful and easier when building complex applications with JSX.

With Vue. I have a functional component that renders out JSX templates 6 levels deep and other DOM elements on-demand. All from a single multi-dimensional array.

In terms of the code count and simplicity. You couldn't achieve the same result with Single File Components so JSX to the rescue. But I'm sure someone could with SFC, but it would be such an over-engineered mess, it would be counter intuitive.

It was seriously difficult compared to what React offers because the functionality for Vue just isn't there. But I am sure in time, the functionality will be there. Starting with Vue 2.6/2.6-next.


> separate templates from view logic (probably the biggest sin)

Can you please explain a bit more on this?


> It's the same core concepts as ...

I agree that it feels similar to those frameworks. I'm not put off by that because it's a framework that's clearly learned from all of the above and refined the forumla.

> This is highly stateful, object oriented, mutate-by-defualt, class based, imperative programming, with imperative DOM manual wirings

Vuex is a state management library similar to Redux which you can use to structure your app. Vue now has functional components, and there are libraries that let you process form data entirely from the store.

Have you never used $refs in React code? That's about as manual as I've seen Vue wiring get...

> separate templates from view logic (probably the biggest sin)

I think this is more a matter of taste. I really like that .vue files let you specify things like the kind of style loader (css/sass/less), script type, etc. Everything's still in one file, but each part is separate. I think (if ? then : else) stacked multiple levels in JSX looks pretty ugly. :)

> v-model="todo", this.$parent.$emit

v-model is just sugar for something like v-bind:value="todo" v-on:input="setTodo", which provides an initial value and makes a simple function that sets the component's todo property, similar to how you might call this.setState({...}) with React.

I was put off by this.$parent.$emit as well. You can simply pass the delete function as a prop in Vue as well, which is what I would do.

> implicit magic that makes list.push() update the view

This part is a little bit magic, but of course you could use Vuex for a more complex application. I was under the impression that excessive use of the analogous this.setState is frowned upon - am I wrong? Doesn't it do a bit of its own magic as well?

> While I don't personally prefer any of the above style, the point is not a criticism, but to point out that fundamentally Vue doesn't seem to offer any different core concepts than other frameworks.

Vue.js, Vuex, and Vue-Router are all maintained and released by a core team that coordinate changes. They all have pretty good documentation. I don't feel like Vue is fighting Javascript. I feel like there's usually an obvious way to do what you want to do most of the time. Nuxt.js (built on Vue) is incredibly simple to set up and offers an app skeleton, express templates, SSR, automatic rendering and plenty more.

> React's fundamentally paradigm and convention shift... [...] As a biased pattern match, most times I see people comparing React to Vue, they're new to both, and don't get React.

I had done a lot of messy jQuery stuff starting around 2006 or so. I played around with Backbone for a bit on the side, but found it messy. I tried to get into Angular 1 but found it overly complicated for little reward. I tried multiple times to get into React, but (and maybe this is less true now) after you choose the view layer, you still have to put together the rest.

I like functional components, explicit state management, and Vue + Vuex has those. I don't mind template syntax - I prefer it separated out into its own concern. It's not revolutionary, but I think it provides a solid, sensible foundation.

> Building Backbone apps where you glue events to DOMs written in strings with magic stateful data classes...

I've used Backbone some myself, and I agree that event handling is just plain messy. I don't have this problem writing Vue code.

Re: your last paragraph I rarely feel like I have a Vue problem because usually the way to do something is obvious. And when I do the errors are usually understandable, and Vue Dev Tools browser plugin is excellent. You can easily pick apart your app and Vuex state with it.


It’s not owned by a reprehensible consumer surveillance utility. That is 50% of why I chose Vue.

The other half is also programmer happiness, due to impedance matching with Rails.


> It’s not owned by a reprehensible consumer surveillance utility

I don't like Facebook that much either, but that doesn't mean they don't write useful software.

> The other half is also programmer happiness, due to impedance matching with Rails.

So impedance matching with a limited technology is a good thing? I find that to be... a limitation.


Utility does not improve ethics, which is why making the trains run on time did not excuse Italian fascism. Choosing React is to condone its owner.


Fascist trains didn't really run on time. It is just that nobody could say they didn't.

But, yes, utility is poorly correlated with ethics, at least in the short term. Longer term, maybe not. Ethical failure has a way of gumming up communication paths.


backbone was pretty thin, but you seem to imply you might have had backbone problems?


I still prefer Ember.js, it is the only one which is focus on developer happiness, and corporate friendly, ideal for big teams. Modern, fast, lightweight, and easy to learn: www.emberjs.com, www.yoember.com


> separate templates from view logic (probably the biggest sin)

Not a sin.

> or, I suspect, don't fully understand

Your suspicion is wrong and so pointless I'm shocked this comment became the top one for this thread. Usually, pointlessly provocative stuff gets downvoted, as it should.

> React's fundamentally paradigm and convention shift.

You mean the paradigm shift of mixing HTML and JavaScript in the same hodgepodge? That's what we moved away from in the first place. React brought it back and many people convinced themselves that now it should work.

> React is so thin that it's rare to have a "React" problem, now I have vanilla "Javascript" or even "function" problems

Ah, this explains it. So deep into the... I don't want to say fanaticism but I can't think of another word, that there's even a preemptive rationalization of the technology's problems.

And this comes from someone who, over the last two years of experience, has taught himself to stop hating react by sheer force of will.


> You mean the paradigm shift of mixing HTML and JavaScript in the same hodgepodge?

Are you talking about JSX? If so, this doesn't ring true to me; it isn't a mixture of HTML and javascript, it's just javascript with an HTML-like macro syntax. I've personally always found that really weird, but it isn't a hodgepodge, it's just normal javascript function calls with a weird syntax.


> it isn't a mixture of HTML and javascript, it's just javascript with an HTML-like macro syntax.

This is a distinction without a difference. The point is that putting HTML and JS logic in the same file is what was usually done in the early days of programming on the web, before separating code from event attributes into their own script tags and files became the norm.

All JSX does is the exact same mix in the opposite direction: it's not about JS inside HTML; it's HTML inside JS. And I understand that that's fine for many people -- and I've learned to stop caring -- but I take issue with pretending that it's a "paradigm shift".


At risk of repeating myself, it isn't HTML inside JS, it's just JS function calls with a weird HTML-mimicking syntax. You aren't putting "HTML and JS logic in the same file", it's literally all JS. It's like how you could write lisp code with the s-expressions represented with XML: it's not a different thing, it's the same thing with a different syntax.

Maybe your point is that you don't like the style of building up HTML strings by composing function calls. If so, fair enough, but I would argue that the jury is very much out on the trade-offs between that approach vs. an interpreter for a template language. React's string-building API is not the only example of this style; for instance lisps seem to do it that way pretty often (probably because sexprs are a quite natural syntax for this). Personally, I find the string-building approach much easier to reason about. It's a more explicit and well-defined problem. Instead of parsing and augmenting an existing string, the implementation just needs to transform some parameters to an output string.

As I said, I'm not really a fan of JSX itself because I find it weird (and unnecessary), but I do like the simple string-building API it gets translated into.


I feel worried reading this post, because it doesn't seem like you have separated impulsive emotional responses from objectivity, and when I see engineers have this behavior, I believe it masks our ability to asses technology well. For example mixing view logic with view templates, both in the view concern, (and the concept of a DSL), follow computer science principles of domain/concern separation, vs separation of technologies like ("html" and "js", which isn't even fully accurate for JSX), is not a computer science principle, and has no benefit when separated.


> I decided to try and build a fairly standard To Do App that allows a user to add and delete items from the list.

Isn't it enough of such really? These (micro)apps which are actually single extracted screens of anything seriously larger can't help to decide about a stack.

What about other aspects of real apps: user auth, undo, back-button action, rich forms, client-side error logging, permalinks, rendering/filtering user markup, uploading/attaching content, drag&drop, notifications, SEO, integration with other useful libs (e.g. bootstrap, highcharts, d3), app extensibility with customer views/plugins?


I agree with PretzelFisch.

It's not necessary to delve into framework minutia and ALL possible use cases in order to get a feel for how the frameworks operate.

The OP made a very wise decision by choosing to build a demo app that incorporated a list and child components. Lists with child components provide a very succinct encapsulation of the primary challenges that JS frameworks must manage. Managing state between parent and child, one-way or two-way binding with repeatable items, etc.


I am not sure having all of that together in one demo would help or just be to much noise. It might be better to pull each feature in to its own isolated demo. That you can see how they are differ.


Right, but real apps are such glued "noise". For isolated demos we already have countless todoapps on GH and snippets on StackOverflow or some JS Fiddles.

Then when it comes to integration of a front-end framework in a real app with non trivial but common use case the one has to compare and learn the hard way by scouring forums or diving deep down into source.

E.g. dynamic templates are discouraged in Vue, but customers would like to have a control over couple of loadable HTMLs without npm work - think of most CMS stuff.

My point is that I came to this article with true intrest that the author made a real non-trivial application comparison, thus we could learn subtle gotchas and battlefield tactics. But then I got letdown it's another todoapp to compare basic syntax.


I’ve thought for a while that this would be an awesome community project for people to work on together. Pick a project and create it using a few different technologies. It would also help to demonstrate the best way of doing things in each framework because everyone would be competing to make their framework appear to be the most compelling choice.


Somebody else agrees with you..

https://github.com/gothinkster/realworld


Woohoooo! That's brilliant. Thanks.


I posted this below, but I'll repost it here for better visibility.

https://github.com/gothinkster/realworld

This is a medium clone built in various frontend and backend technologies.


There is also this: http://todomvc.com/

A todo app written in many many frontend tech stacks.


Except that, unlike realworld, this is about as useless (for proper comparison) as the OP app if not more.


Is a todo app really a good way to compare any kind of language or framework?

I work with several large apps, some in Vue and some in React. After the learning curve, they are more or less the same. They solve the same problem, more often than not in the same way (or rather using the same concepts). I don't think either is better or worse, or introduces significantly more or less code.

The one big different I have taken away from my experiences with both is React is more approachable for "developer" types, who are big on unit tests and design patterns. Vue is more approachable for people coming from a design background, partly because of its (not so much once you understand how it works) "magic" two way binding and single file components (which let you write <script> <template> and <style> inside a single file, which is way designers are used to).

If I know the app will have more designers, or less experienced developers, I think Vue is a good choice. If it will be built mostly by more developer types, React seems like a good choice. Once you know one, though, it's very easy to pick the other one up.


I find vue to be much more approachable, and easier to teach to people that might just modify components, and they like the standard syntax. If you work in PHP, which I don't anymore, there's pretty decent exposure to vue through laravel, so you can get some halfway decent "full stack" apps done by a person or two on a pretty tight schedule.

I've since went to node on the backend and vue on the front-end, going to work with Nuxt next for a small project to see how I like it. I have exposure to React as well, vue to me makes more sense, I built a pretty large angular 1 app in 2011-2012 that's still running out there, so angular was my first real exposure to this sort of thing. I've had zero interest in angular since then. Vue works well for me, though I could easily hop back into react if necessary.


I think React is most approachable to developers with a good grasp of Javascript and the DOM, and Vue (which I admittedly have less experience with) is more approachable to designers or developers with a good grasp of other programming languages/not the DOM.


Perhaps. I do trust in the work of the the shadow dom manipulations behind the scenes, they're way smarter and way more interested in that. I work with people that make stuff in squarespace and just do html and css, and vue is a choice just in case they decide they want to come over and try some of the other apps. So approachability to me a feature, I don't want to be the only one that can make a trivial update just because someone goes in, looks at the JSX and nopes right out of there.


http://todomvc.com

This is exactly what he described not being able to find.

I’ve seen several different websites collecting these todo app comparisons.


I was slightly flabbergasted when he said it was going to be a to-do app for comparison. It's on the third page of Google results for "compare javascript frameworks", but I'm sure it was higher about a year ago when I had that question.


I've been struggling with the thought that both react and vue feel wrong when writing. Vue seems quickier but things like emit feel gross. React is kinda fun to write small items but things turn ugly when you start breaking down components into smaller and smaller components.

AngularJS still feels nicer until you get into directives.

I think there is still space for one more framework to rule them all.


>...turn ugly when you start breaking down components into smaller and smaller components.

Care to elaborate?

This seems opposite to how components ought to work.


Take a table that is broken into rows then cells, within the cell you have a media object within that you have a list with items.

Each of those become separate components. Can you reuse them, yes but it would be more helpful to keep them in one component.


Then don't split them. If you use powerful methodologies to keep track of complex state in one component, not splitting is generally easier too, although you will lose slightly on performance. No one forces you split a component into multiple ones. I've implemented entire games in just one component with logic cleanly described by a finite state machine.


Reading this makes me feel better I make large monolothic components. Most examples would have you believe doing so is a big no no.


You can keep them in one component. Nobody is making you split every single object into discrete components.


So keep them in one component.


Just because a framework/language gives you a tool, doesn't mean you need to use it. Instead of emit, you can easily track state in a Vuex store and then have that change propagate to the required components.


You can also inject sideways data dependencies in React by using an event emitter. Shitty POC:

  // global-store.js
  const remove = (arr, el) => {
    const i = arr.indexOf(el);
    if (i < 0) return false;
    return !!arr.splice(i, 1);
  }

  class GlobalStore {
    constructor(data){
      this.data = data;
      this.subs = [];
    }
    sub(cb){this.subs.push(cb)}
    unsub(cb){remove(this.subs, cb)}
    notify(newArr){
      for (let s of this.subs) 
        s(newArr);
    }
    addData(item){
      notify(this.data = [...data, item])
    }
    removeData(item){
      if (remove(this.data, item))
        notify(this.data = [...this.data])
    }
  }

  // my-component.js
  import myStore from "./stores"
  class MyComp extends Component {
    ...
    componentDidMount(){
      myStore.sub(this._cb = data => {
        this.setState({data})
      })
    }
    componentWillUnmount(){
      myStore.unsub(this._cb)
    }
  }
Obviously, not super optimized, but it's just a POC.


A store could be used and things get cleaner but the overhead increases too much.


If ($)emit is not something you use for very ephemeral events, that otherwise cannot be expressed as state changes in natural way, or in a custom, reusable component (i.e something you could publish separately from your application), you're using it wrong. I rarely ever use emit and when I do it's either a very active reusable component or a solution for an otherwise very difficult problem. And I don't see what a meaningfully prettier/better API would be.


> Vue seems quickier but things like emit feel gross

FYI: You can pass a function as a prop in Vue.js too, just like React.


I agree with you.

What are your thoughts on https://github.com/hyperapp/hyperapp ?


V2 is coming relatively soon, and will have breaking changes.


Thoughts on Mithril?


I rewrote a ~30k line React app in Mithril and since then it's been my go-to view library. It's not mentioned here often, which is surprising given how nice it is to work with. The biggest improvements for my workflow have been closure components and the css selector syntax.

Closure components let you use closures to hold state, which ends up being a very elegant pattern. In react:

  class Square extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        value: null,
      };
    }
    render() {
      return (
        <button
          className="square"
          onClick={() => this.setState({value: 'X'})}
        >
          {this.state.value}
        </button>
      );
    }
  }


Is roughly equivalent to the following mithril code:

  function Square() {
    const state = { value: null };
    return {
      view() {
        return (
          m('button.square', {
            onclick() { state.value = 'X'; }
          }, state.value);
        );
      }
    }
  }

Notice that the closure gives us access to the state without needing to know what `this` refers to. You can also see the selector syntax in the mithril hyperscript above (`'button.square'`). That becomes especially nice if you're using an approach like tachyons for css, where simple classes are layered to create a style. I use this all the time for layout, which in react I would have created a bunch of stateless components for. Also worth noting: we happen to be directly mutating state in this example, but since mithril isn't opinionated about that you could really store and update your state however you please. Also, for quick projects that don't justify all the cruft that you get with `create-react-app`, it's nice to be able to just use a framework with no build steps whatsoever.


Mithril felt really slow to load for me, using it on a little hobby site and was not impressed with it's page-load performance.


I've been working with Mithril for 2 years and never heard anybody say that before. What's the site?


> I think there is still space for one more framework to rule them all.

People should learn to write apps with the DOM, that's the framework to rule them all and it's already in the browser. There no need for a framework to write apps that follow the unidirectional dataflow principle. That principle just need to be taught, like MVC or SOLID.


Oh my goodness, please no.

I already lived through the home-rolled, pure-js, custom frontend "frameworks" made by each team's resident "smart guy" once. I shudder just thinking about those days.

React/Angular/framework-whatever are glorious angels protecting us from the tyranny of half-baked, poorly thought out approaches to frontend development.


> Oh my goodness, please no.

You don't educate developers to good practices just by abstracting the hard things. You don't need to use React/Angular/Whatever to manage state the right way in a front-end application. You don't need a framework to make code maintainable or testable, or you're just saying front-end developers are so incompetent and undisciplined they need a framework. No they don't, just like one doesn't need a framework like Rails or Spring or Django to write a server app.

> React/Angular/framework-whatever are glorious angels protecting us from the tyranny of half-baked, poorly thought out approaches to frontend development.

No they are not, they are making the developer ignorant of the underlying DOM architecture.


Uh oh, I think we found our 'resident smart guy.'


No, i'm not smart, I'm just not ignorant. Learning Django isn't going to make you learn HTTP spec for instance, you know what i'm saying? the same way, learning Angular OR Vue.js will not make you understand how event bubbling or event delegation works. plenty of "full stack" front-end developers out there who know nothing about the DOM.


There's Angular 2+, which largely follows the Shadow DOM + Web Components specs.


Relevant xkcd [0]

[0] https://xkcd.com/927/


If you are using Vue for anything other than the most basic use case and are not using Vuex you are not doing things the "best practice" way.

Same goes for React without Redux.

The frameworks have a strong architecture the moment you introduce the flux architecture (vuex for vue, redux for react). Writing vue/react code w/o flux is like putting your entire application code into the view layer of an MVC app.


The creator of Redux disagrees: https://medium.com/@dan_abramov/you-might-not-need-redux-be4...

Writing vue/react code w/o flux is like putting your entire application code into the view layer of an MVC app.

You can easily create a model that knows nothing about the view without Vuex/Redux.


>You can easily create a model that knows nothing about the view without Vuex/Redux.

Sure, but why not use the standard solution for the ecosystem.

As far as that linked Abramov post, it felt like a hedge to me. Basically he's saying you don't need redux to write a react app, which is a truism, then lists all the reasons why you should use redux.

Redux "code" is a simple library. But if you follow Abramov's architecture opinions that he only implies in the redux guide, you end up with a full highly scalable front-end framework architecture.

Plus vanilla react is non-deterministic with state. Redux solves this problem and that alone is worth the price of entry.


As a backend developer that is trying to get into frontend what bothers me the most is that no one knows what is the proper way of doing things in React. There’s no golden standard.

Sure, there’s opinions, but no standards within the React framework, and that’s what keeps bothering me the most. I can’t get into react because person x will tell me - “oh you should do x like this instead, because of y’ and then I’ll read y is heresy. I don’t have enough experience or time to vet what’s good or bad and I can’t make that choice. I also however don’t want to refactor every other month because someone suggests the new best practice.

With Vue, at least for myself, things felt more natural and straightforward. Not saying I understand Vue fully either, but, I made a fully working standalone project that complements the business in less than a day. JWT, multiple api calls, toasts, Vuex, components and voala it was done, while for react it took a real front end dev almost an entire week to get something up and running.

At some point it’s not about modularity or code perfection, but rather delivering. It was easy for me to get something up and running with Vue, but I was overwhelmed with React. I don’t want to spend 3-6 months learning something only to be able to write PR passable code.


There's right and wrong ways to do stuff in every other ecosystem too. The difference is some of the wrong ways get baked into 'best practices' and you can't engineer a clean code base even if you want to.


That's why the TodoMVC project was created, so we show off how to build the same app in all those methodologies.


The difference being that the TodoMVC projects are written by different people, so each one follows the best practices for each framework.


Except the author needs to be proficient in both, and this author wrote two anti-patterns in the Vue example.


Do note that you can use React with much less boilerplate! The nice thing about React is it's very easy to write abstractions on top of it, since it's just a small JS library. For example, instead of writing value/onChange/setState, you can use valueLink={linkState()}. (Note valueLink and linkState were both formerly shipped with React and since deprecated, but it's easy to write them yourself.)


Recently I was looking at my 200Kb app minfied for what was the largest portion of it, and, Lo and behold, react-dom comprised a little under half that size.

Part of this is because React and ReactDOM haven’t switched over to ESM (and still use CJS), but calling react small is probably not entirely honest, at least if you use it like most folks do.


Dan Abramov has said several times that switching React's codebase to ESM won't result in any magic size drops from tree shaking, as there's really not any "unused" portions of the React codebase.

My understanding is that React's synthetic event system is a large portion of its size. Dan suggested that React 16's support for custom renderers would allow creating a "lite" equivalent to ReactDOM [0] if people wanted to, and at least one person has done so [1].

[0] https://twitter.com/dan_abramov/status/938937405524017152

[1] https://github.com/jquense/react-dom-lite/


They meant its API surface, not filesize. React is ridiculously small and simple for what it can do.


yes, this is exactly what I meant. Thank you!


Gzipped and minified, React with React DOM is 32k bytes. Which is fine for most apps.


Thank you for posting my article. It would be awesome to hear all of your thoughts and to applause the article if you liked it :)


Just a side note - you don't need the constructor boilerplate to initialize state in React components if you use property initializers (I see you're already doing it for handleInput): https://babeljs.io/docs/en/babel-plugin-transform-class-prop...

Additionally, you don't need to .bind on deleteItem since functions initialized as class properties are automatically bound (you should just be able to do deleteItem={() => this.deleteItem(key)}).

Another thing is that there are certain weird things that happen if you use the index as the key for ToDo's render function (consider using the actual item text itself): https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-p...

Overall, great article! Hope that's not too nitpicky!


> you should just be able to do deleteItem={() => this.deleteItem(key)}

Don’t do this. Arrow functions (and bind) are reallocated on every render, so this can result in a lot of useless re-renders.


That only matters if the child components are actively attempting to optimize themselves by implementing `shouldComponentUpdate` with a shallow equality check (or are PureComponents, which do the same thing).

Please see this post for clarification on the actual pros and cons of creating functions in `render`: https://cdb.reacttraining.com/react-inline-functions-and-per...


I think you meant allocations instead of rerenders - if you wanted to reduce rerenders, switching to PureComponent would be the way to go. IMO, what you're suggesting is a premature optimization.


An arrow function as a prop is a new function instance on every render causing child components that extend React.PureComponent to render even if no other property has changed.

I consider this a code smell (b/c we had huge problems with it) and I usually give the advice to do it differently. There are exceptions, of course.


Fair enough. In this case, I guess it's a tradeoff between code organization (should the child component be concerned with its position in the parent) versus avoiding rerenders.


I don't think it's a concerns issue. You can simply decide to never create functions in any render(). There's even an eslint rule for it.


The rationale behind that is avoiding re-renders, which can (but doesn't always) improve performance (shouldComponentUpdate can be slower than simply always re-rendering, per a React core developer): https://news.ycombinator.com/item?id=14418576

If you're concerned about allocation, here's what the same core developer has to say about inline functions in render(): https://twitter.com/sophiebits/status/938075351414063104?lan...

Also see the article that acemarke linked above.

This is a textbook case of premature optimization. Why make your code harder to read just to achieve some performance gains that likely aren't even noticeable?

Lastly, regarding the ESLint rule, sophiebits put it better than I can:

I don’t recall ever having seen a credible-looking study about this, including in 2015.


Awesome feedback and many thanks for taking the time to point these things out. The article has started to gain a lot of traction over the past few days and the last thing I want is for there to be parts of the code that are not following best practice (as a result of my relative inexperience with React).


My first thought for the React example would be to replace the CSS files with styled-components, emotion, or one of the other copycat CSS-in-JS libs with an identical base API.

    import { css } from 'emotion';

    const WhateverComponent = () => (
      <div className={css`
        background-color: green;
        height: 100%;
      `} />
    );

    export default WhateverComponent;
...or...

    import styled from 'react-emotion';

    const WhateverComponent = ({ className }) => (
      <div className={className} />
    );

    export default styled(WhateverComponent)`
      background-color: green;
      height: 100%;
    `;
...or...

    import styled from 'react-emotion';

    const BigGreenBox = styled('div')`
      background-color: green;
      height: 100%;
    `

    const WhateverComponent = () => (
      <BigGreenBox />
    );

    export default WhateverComponent;


Hi Sunil, I’m thankful for your article as you helped inform my framework choice for a new project.

Please know this feedback is presented constructively. I had a bit of difficulty following if the example was Vue or React. One place under “How do we mutate data?”, the last word is Vue: followed by React code. Under “How do we pass data through to a child component?” both say “in React”. I’m very uncomfortable giving editorial advice to a stranger this way; it’s a great article and just wanted to trade some polish for the valuable information you shared. Thanks.


that's a great post, very useful and down to earth. Now i think there's room for a "part 2" post, talking about routing, state management for large project, etc.


Can you give a TL;DR? Which one do you prefer and why?


Hi mhermann. I did originally consider writing my preferences and why, but decided against it as my intention was simply to try to objectively highlight the differences when it comes to adding/deleting items, passing props from parent to child, emitting data from child to parent etc - all so that the reader can then form their own opinion.

But seeing as you've asked, I prefer Vue at the moment as you can achieve the same things in React but with fewer lines of code :)


My question as well, I scrolled down to the end and didn't find a result summary?


In a well-written review, the article is the summary.


While I understand why we don't really see them, I would love to see a much more involved comparison. A reasonably sized app would probably use redux/vuex, routers, async, etc. which changes things dramatically. Even just adding the state managers changes things completely. Then you have things like cost to maintain/upgrade.


I don't really like that we're trying to draw comparisons based on a toy app. The things which really tell you how good or bad something is comes when you start reaching the edge cases, which in complex applications is practically guaranteed. This makes the simple app for comparison a trap, a poor heuristic. The problem is, hobbyists don't have the time to try something deeper, time is simply too valuable to explicity replicate work. An organisation would have to commit to this.


This is great. It’s an excellent idea for Rosetta Stone(s) for different JS frameworks - all side by side with minimal but working code. This could be a start.


There's a really awesome project called RealWorld that's trying to build full stack example apps (a medium clone) in all the various frameworks: https://github.com/gothinkster/realworld


Wow thanks for sharing, this is really cool! Looks like a great way to learn how other frameworks work.



Thanks for the link! I just played around with the React and Vue.js implementations. With the Vue.js implementation, there is a perceptible lag (maybe ~300ms) between pressing Enter and the new item appearing in the list. With the React version, the same action is essentially instantaneous. Curious if anyone else is experiencing the same and/or knows what might be the cause.


The Vue one creates new items on keyup while the React one creates them on keydown.


Most of them seem to be on keydown except Vue.


i noticed a lag in the vue one only on the first entry - everything else was basically instant (less lag than I could perceive). Basically instant on react too, although I tested that one separately. Too lazy to clear browsers and test again.


Thanks!

This looks like a proper list. I’m happy to see older frameworks like Knockout listed too. Many thanks for this.


In addition to TodoMVC and RealWorld, there is also https://hnpwa.com

On thing I like about HNPWA is that there are multiple examples with varying stacks and each one is built by someone who really knows that stack well. There is also a somewhat objective measure of success in the lighthouse score.


https://github.com/gothinkster/realworld/blob/master/README....

That is what you want, maybe. Lots of different frameworks, building the same working application.


Though the intent is good I'm not a huge fan of posts like these because no developer is equally proficient in two frameworks. One example is going to be more idiomatic, avoid more pitfalls, use better abstractions, etc. Were this a large production scale project it would be even more evident then a vanilla to-do app. I hope nobody sees this and goes "x is better!".


However well written the article is for beginners, I’d love to a comparison where more real world concerns are part of the equation: authentication, authorization, internationilzation, API interaction, form validation etc.


I've only been coding in React for a year, but this article feels like it is depending on state far more than a production app would. State is definitely a key part of react, but props are more the norm for moving data around. When you do change state, it often just makes an update to one small thing, which then re-renders everything downstream with new props.


props is more explicit to control the timing of rendering.


The react app looks more complicated and verbose.


Funny, I had the opposite impression. Vue outsourcing a lot of custom non-HTML compliant properties into the DOM code made me think it would be a harder job to get rid of it if I decided to switch. React's state updating does look a bit more circular, but at least it stays within the file.


I agree, the Vue snippets look cleaner and simpler.

Even if it's not 100% vannila HTML or Javascript, its still worth the effort due to the simplicity and clarity of the syntax.


>If you’re not already aware, a CLI (short for Command Line Interface) is basically a thing that you can install via npm that allows you to terminal/command line commands that will quickly build a general Vue/React file structure for you

No, not really... Good work for doing this comparison though.


As a backend dev (though I've been slinging jquery for years and do know enough javascript to dislike it), I've finally convinced my boss to let me write a small front-end app that's due in about a month.

It seems like most of the various teams are using React, but I've heard Vue is easier to pick up. Since I've only got a month, can someone with experience in both weigh in?

If all else fails, I wrote a small AngularJS app about 2 years ago, and will just reuse its base if both React and Vue seem too complex to pick up in a few weeks. The app I need is just a simple crud / tree app to add users to a hierarchy of groups.


If other people in the company are using React, use React and reuse the tooling they have.

In any case, though, don't use AngularJS. It's really low-performance compared to anything more modern, and the way it depends on dumping stuff into the DOM and then only doing operations on that afterwards leads to all kinds of really annoying edge cases (for example, certain functionality just plain not working inside <table> tags because only certain DOM elements are allowed there).


Vue seems to have a lower learning curve for people with a background in webdev, because it's more relatable to the old school way of doing things. React seems better coming from other areas of programming, especially functional. React is also better considered "infrastructural": every React app needs to piece together a framework (router, "state management", forms, etc), whereas Vue has community enforced norms & standards that can answer those questions for you. Personally I use React.

Good luck!


If you're familiar with AngularJS, Vue would be easier and faster to pick up.


I second this. Vue is more declarative to me. Which I appreciate.


Angular today is different from 2 years ago.


Everytime a todo-list. Can we try implementing more reactive applications? Perhaps a tic-tac-toe game would provide more insight and understanding on the underlying powers of the frameworks.


I just learned Vue.js and it seems he made it harder than it needs to be. Is he using Vue.js version 1? (I didn't recognize some of the paterns he was using from the documentation..._)

Also, from the comments it seems like React has "don't do it this way or you get an error" or "people get caught with this because they didn't know the side effect of xyz..."

Vue.js had almost not surprises once I learned how the system worked, maybe I am not deep enough into it yet, and it has similar gotchas as React?


having just had to remove jquery from an angular application because it was flagged by static analysis i can say i do not want any frameworks. i just want to make them go away.

it is just extra stuff to learn to debug. the angular part fails even after i think i removed the jquery code. it fails silently, so i do not know where it fails. maybe i missed something. im just a stupid webdev who also works with ten other frameworks on our ten other applications we maintain for this client. but maybe angular/react/etc is just added complexity that was unnecessary in the first place for a simple crud app. framework code also uses arcane language constructs that further obscures things and there are quite a few of those tricks in JS. not to mention that you only use a few bits of it, but all the code is there for you to sift through when it breaks.

then corporate will likely decide they want Polymer and we have to learn to debug Polymer. then polymer fails the static analysis or the pentest and polymer needs to be fixed/thrown away.

frameworks are just parts that can go wrong. yes react can be pretty cool but it also introduces complications. unnecessary complications. unless there is a very good reason to have a framework and there will never be a reason to migrate and you never have to deal with higher-ups, i'd recommend sticking with vanilla javascript.

it is quite powerful these days. maybe include some small library to organise things. jquery was allright in the day, although i would not use it these days anymore because most of the stuff it did can be done easily in plain JS now.

there is something called the KISS principle. it deserves more credit than its getting.


I used to think vanilla JavaScript was the way to go, but then I rewrote a vanilla JavaScript SPA with a framework (Vue) and realized how many times I didn't have had to type element.querySelectorAll('x')||[] and element.addEventListener / removeEventListener anymore. Vanilla is good sometimes but it gets tedious on bigger stuff.


I don't mind writing stuff i know and understand. although if you are a framework expert and/or the framework code is very minimal (which is somehow never the case), i can understand choosing to remove the drudgery.


I did similar to choose between the Big 3 frameworks, and I chose Vue. Was thinking about polishing the code to make the test "publishable".


React reminds me of the good ol' PHP days. The days where it used to be an all out freedom of expression (pure hacking) doing whatever you want whenever you want. Sure code can get ugly as sin, but it does leave you with a liberating feeling.

It wasn't long ago where separating content from presentation was actually a thing. Now we are going the other way around and quite honestly, I like it.


Give me some code snippets that are ugly as sin ... seriously, Please!


I love react, I think it's extremely elegant and easy. It's a glimmer of sanity in the insanity that is javascript. I came from a non js programming background and just couldn't deal with the mess of a language that js was/is (especially pre ES6). Without React I would've never gotten interested in front-end development.


I can't imagine writing a real-world Vue app without Vuex. As such, I can't help feeling like this article, despite the best of intentions, is probably misrepresenting things. The last several Vue apps I've written have not used `emit`; not one single time. (context: `emit` is shown/used in this article)


Well, not even Vuex is needed for that matter. It's funny that the author goes out of their way to comment on how you can mutate state directly in Vue, then doesn't take advantage of that.

Both components can share a single "plain old javascript" model object, which they just both freely update. The TodoListItem doesn't need to notify its parent of anything. In a small scale app, it's fine.


I agree, generally, that most apps eventually need it, and that this isn't the best representation of real-world vue, but there are also plenty of lightweight use cases for vue that do not require a vuex store, or even emit. if the linked comparison did use vuex, it would then suffer from a lack of redux on the react side of things, too.


did the same for a take-home coding assignment. once i did one, it was pretty trivial to convert it over to the other. you can check out here:

https://github.com/tmm-archive/front-end-code-test


A todo is a little too little to do. How about pair programming between to coders adept in two stacks?

For that matter, how about in Android and iOS?


The React example seems like it should really be using Emotion or a similar library to make the separate CSS files go away. While it is bringing an extra library into things, there's several that have an identical basic API, so it's a fairly generic approach for React apps now.


styled-components[0] or death.

0: https://www.styled-components.com/


Why that particular one?


* CSS-in-JS

* Written as actual CSS

* Styles that are easily extended / composable

Would be my main reasons for liking it.


You don't seem to have looked at Emotion, because the most basic parts of it are clones of those parts from styled-components functionality, with variance once you get into the extended API.


I haven't. Not really sure why that matters though? I was highlighting styled-components as a much better way of handling styling in React compared to inline JSX styles or CSS files.


It matters because you replied to a comment about Emotion saying "styled-components or death".

If you wanted to compare it to something other than what the parent comment was talking about, maybe you should have made your own comment thread, or been more clear, or something.


You're very right. I somehow missed the reference to Emotion in the OP.


Because then you might write "styled-components or Emotion" rather than "styled-components or death".


stevebmark's comment got me thinking about UI technology in general and computer science.

The thing about UI ... it's just, plain, _hard_.

There's not much more to it then that. "UI is hard". User interfaces, no matter if they're text based or graphical, are perhaps the most frustrating field of computer science. They look simple. "Oh, this is just a bunch of boxes and text. I can bang that out in an hour!" three weeks later. Sound familiar? It's that illusion of simplicity that drives programmers crazy. UI has, as far as I can tell, the highest ratio of perceived simplicity to actual difficulty of any other computer science field.

So here we are. We have several decades worth of computer science under our collective belts. Over the plethora of decades that our field has existed we've: invented the transistor, made it the size of a handful of atoms, flew to the moon and back, beat humans at chess and Go, can make video calls half way around the planet, and have crammed unthinkable amounts of technology into our pockets in the form of smart phones. My house bends to my very _voice_ thanks to modern computer science.

But in all that time ... UI is still hard.

I don't think a lot of programmers stop to think about that. Maybe, just maybe, all this thrashing about with UI libraries has more to do with the fact that UI, as a computer science problem, is perhaps one of the most complicated, impenetrable problems we've come across. The perceived simplicity of the problem so often blinds us to that fact.

I believe it stems from a shared "ancestor" with multi-threading: concurrency. Every programmer knows and fears the problem of multi-threading, but they don't fear UI in the same way. Yet, these two problems are more alike than not. A UI is a system that is filled with concurrent, unpredictable, events and threads that could happen in any order. That's a multi-threaded system.

So it's no surprise when viewed like this that UI is hard. It's very difficult for us to reason about a multi-threaded system. Even the best engineers in the world make "obvious" (in hindsight) mistakes when they build concurrent systems. Look at all the bugs that pop up when researchers attempt to do formal verification of concurrent primitives implementations.

So if it's impossible for us to reason about UI, as a concurrent system, then what do we do?

My time spent with Rust, the programming language, has given me some theories. Rust is most popularly known for its memory safety, but its true power lies in its type system. Rust is the first language I've encountered to expose to the user an advanced type system in a practical way. Languages like Haskell et al have of course had these advanced type systems for _decades_. But Rust offers them in a way that is digestible and ergonomic. For us common folk at least. It's perhaps the first chance that we as an industry will have at a widely used programming language with advanced typing and static analysis.

That advanced typing system is what gives Rust its true power. Most salient to this discussion is its usage of the traits Send and Sync. These two traits allow us to communicate to other engineers and the compiler that "this type is safe in these concurrent scenarios." Suddenly the frightening world of concurrency blows apart. Instead of being afraid, you can be fearless. Write whatever code you want and then the compiler will check it and prove (in a limited sense) that your program is correct and safe.

It's an incredible shift for programmers to have this power. Send and Sync are a small step in a new direction: being able to leverage static analysis by the compiler to assist programmers in designing their systems. Before, in e.g. C, it was up to the programmer to think about all the state of their program in their head. At best we suck at that, especially in complex scenarios like concurrent systems (and UI!).

Now we have tools that can augment our mental facilities. In the same way you don't have to think as hard about memory in Rust as you do in its ancestors, you don't have to think as hard about concurrent systems because the compiler and the libraries and types we build alleviate the number of problems we need to think about.

I believe that it's possible this road that is leading to a brighter story for concurrent programming is also leading to a brighter story for UI. Rather then having to think about _all_ the states that a UI and its backing state machines can be in, we instead build type systems that allow us to describe how we believe the system should look in our heads. And then the compiler will do the dirty work of proving our assumptions correct. Our compilers will be 1000x better then us at considering an exponential number of states that a UI could be in given its concurrent and unpredictable nature.

So just imagine a UI framework built on top of an advanced typing system. We could do insane things like using the typing system to say that certain View elements should only be visible given certain states in our model. For example, the Logout view should never be visible when the user isn't in the LoggedIn state. And the advanced typing system, combined with the compiler's static analysis, checks all of our state machines to prove that Logout will never be visible unless the LoggedIn state is active.

It's crazy, right? But I think it's possible. Just like Rust's lifetime analysis can prove when certain objects will be alive so that the borrow checker can check all your references are alive and safe. I don't think it's so crazy to imagine a future where the compiler can determine the lifetimes of a View and make sure they aren't referenced in certain states.

Anyway, the most important thing I wanted to communicate is that UI is hard. Really hard. And we shouldn't forget that. We should approach UI with the same caution and respect that we do multi-threaded programming. Perhaps with that mindset less programmers will fall into the trap of frustration. That trap that has led so many to believe that it is our libraries and frameworks that are broken, and to go off and build yet-another-framework in the vain attempt to "solve" UI without making any real attempts to innovate on the core computer science problem that is UI.

P.S. I'm not terribly good at communicating the strength of Rust's type system and underlying compiler. There's just something magical about Rust that makes it easy to write an API where A) it's obvious to users how to use it, and B) it's a compiler error to use it wrong. It's not any one thing and it's easy to compare Rust to other languages. So I'm not people will reply with "but language X has feature Y just like Rust; how dare you argue that Rust is some kind of revolution!" Oh well.

I'm also sure some will come along and take issue with my assertion that Rust makes memory management easier. Rust makes memory management easier only if you take the time to consider the full story. That is to say, it's quite easy to manage memory efficiently in, say, C. But to do it _without_ bugs? It takes _decades_ to write a C program with no memory bugs. Yet I can write the same program in Rust and the compiler will _ensure_ memory is managed correctly. (Within certain limits, it's possible to leak memory, etc, etc.)


There are ways to use state machines in web development [0]. Couple that with TypeScript and you maybe get something like that.

[0] https://hackernoon.com/upgrade-your-react-ui-with-state-mach...


This is refreshing to hear. As a UI developer. More curious about Rust now. Thanks.


Am I the only one who recoils in horror reading this and hopes for the day when WebAssembly gets DOM support so we can put this language where it belongs -- the trashbin of history?

Obligatory https://softwareengineering.stackexchange.com/a/221658/13510


I’m not particularly looking forward to that. There is an advantage of having the entire web in a single language, I mean, I still think SPAs are kind of stupid in concept, but we write them because the toolset for them is so good.

Do you really think there will be equal tool sets available for you in your favorite language when webassembly eventually makes it to the browser?

I’d say we’re a good 20 years from it having any form of productivity, and from a human resource point of view, you won’t see companies replacing staff over it, so JS is still the future.

I don’t really understand the hate js gets though. Sure recursion is ridiculously slow, it’s a little verbose, and you certainly need your team to agree on some standards (or you can decide for them), but I actually think it’s kind of decent, once you get to know it.


Please don't do programming language flamewars on HN.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: