
I created the exact same app in React and Vue - techbio
https://medium.com/javascript-in-plain-english/i-created-the-exact-same-app-in-react-and-vue-here-are-the-differences-e9a1ae8077fd
======
stevebmark
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.

~~~
cageface
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.

~~~
no1youknowz
> 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.

~~~
EB66
> > 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.

~~~
oatmealsnap
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.

~~~
EB66
> 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.

------
imhoguy
> 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?

~~~
PretzelFisch
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.

~~~
imhoguy
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.

~~~
aidos
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.

~~~
mrunkel
Somebody else agrees with you..

[https://github.com/gothinkster/realworld](https://github.com/gothinkster/realworld)

~~~
aidos
Woohoooo! That's brilliant. Thanks.

------
lmiller1990
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.

------
honopu
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.

~~~
Vinnl
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.

~~~
honopu
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.

------
RayVR
[http://todomvc.com](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.

~~~
richrichardsson
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.

------
wolco
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.

~~~
trevyn
Thoughts on Mithril?

~~~
bostonvaulter2
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.

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

------
bkovacev
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.

~~~
BigJono
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.

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

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

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

------
jpochtar
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.)

~~~
kitten_mittens_
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.

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

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

------
sunilsandhu
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 :)

~~~
yunyu
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...](https://babeljs.io/docs/en/babel-plugin-transform-
class-properties/)

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...](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-
pattern-e0349aece318)

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

~~~
rvanmil
> 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.

~~~
yunyu
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.

~~~
cygned
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.

~~~
yunyu
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.

~~~
always_good
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.

~~~
yunyu
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](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...](https://twitter.com/sophiebits/status/938075351414063104?lang=en)

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._

------
geist
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.

------
Arbalest
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.

------
ak39
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.

~~~
joshribakoff
[http://todomvc.com](http://todomvc.com)

~~~
mattlong
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.

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

~~~
wensley
Most of them seem to be on keydown except Vue.

------
ben_jones
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!".

------
tnolet
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.

------
codingdave
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.

~~~
tanilama
props is more explicit to control the timing of rendering.

------
stevev
The react app looks more complicated and verbose.

~~~
bordercases
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.

------
rhaps0dy
>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.

------
hiram112
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.

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

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

------
sktrdie
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.

------
RobertRoberts
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?

------
timwaagh
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.

~~~
fenwick67
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.

~~~
timwaagh
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.

------
epx
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".

------
jaequery
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.

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

------
SilverSlash
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.

------
Pistos2
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)

~~~
zmmmmm
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.

------
meagher
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](https://github.com/tmm-
archive/front-end-code-test)

------
techbio
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?

------
crooked-v
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.

~~~
fastball
styled-components[0] or death.

0: [https://www.styled-components.com/](https://www.styled-components.com/)

~~~
crooked-v
Why that particular one?

~~~
fastball
* CSS-in-JS

* Written as actual CSS

* Styles that are easily extended / composable

Would be my main reasons for liking it.

~~~
crooked-v
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.

~~~
fastball
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.

~~~
jholman
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.

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

------
fpgaminer
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.)

~~~
hypercluster
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...](https://hackernoon.com/upgrade-your-react-ui-with-state-
machines-30d1298e90be)

------
chx
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](https://softwareengineering.stackexchange.com/a/221658/13510)

~~~
eksemplar
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.

