Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Under the hood ReactJS (bogdan-lyashenko.github.io)
266 points by bliashenko on July 3, 2017 | hide | past | favorite | 117 comments



There was a previous discussion on how do you know when someone is addicted to over-engineering, and looking at this giant UML diagram, I think this might be the case.

The amount of complexity I'm willing to accept is proportional to the the difficulty of the problem. In this case it's manipulating web pages, which shouldn't be too hard. This isn't a knock on React in particular, but it seems all the major vendors are competing on complexity. React has "fibers", Ember has a "virtual machine", Angular has their own overblown architecture (I don't know anything about it, and don't want to).

Now that the DOM API is implemented in a standards-compliant way across most browsers, it should be the perfect time to use it. I don't like the current mess that is front-end web development, and more of the status quo isn't going to get any simpler, quite the opposite.

Shameless plug for my own DOM utility: http://simulacra.js.org


React's complexity literally only exists for two reasons:

1. To sidestep problems with the DOM. The virtual DOM helps with performance, and fibers help with responsiveness.

2. To implement reactive components. Virtual DOM makes rebuilding sub trees of the DOM cheap, making it possible to have clean components that don't need to constantly attempt to tweak the DOM. Doing this style of programming without DOM diffing is possible, but much slower.

There are other approaches, but this one is significantly nicer to code for than DOM binding and is significantly faster than any naive approach.

Yes, you can extract the essence of React into a several kb bundle. It's been done to death. But why? React is fast, mature, has a great ecosystem, and it's nice to code for. It does nice things like seamlessly support SVG and intelligently batching changes. If you're truly making a complex app, it's worth the bump in bundle size.

The largest part of any web app is the browser. If the DOM wasn't so bloated and ridiculous, maybe we wouldn't need to spend all of our time minimizing our interactions with it. But if you try to count all of the work the browser has to do to layout and render one DOM element, suddenly React feels very tiny.


You don't need to rehash the marketing pitch of React here. It's the same old "virtual DOM fast, real DOM slow" that I've heard countless times from fanboys and repeated ad infinitum in any discussion about React.

What's missing is that you can make complex web apps without any of these things, or the abstractions used can be something completely different. The reasons you stated just sound like ex-post facto rationalizations of what they did after they built it.


>that I've heard countless times from fanboys

If you're unaware, "fanboys" is a grenade to incite juvenile flamewars instead of collegial discussion.

>What's missing is that you can make complex web apps without any of these things,

To attempt better instructive discussion instead of arguing from vague and generic platitudes about "needless complexity", can you explain how your simulacra.js (~12kb) is better than reactjs (~130kb)?

For example, does Simulacra have the same features that React? If so, how did you eliminate ~100kb of Javascript to accomplish it, or conversely, what redundant or incompetent code takes up additional ~100kb of wasted bytes in React?

If Simulacra accomplishes its smaller 12kb footprint by having less features, which features in React do developers no longer need because of "modern browsers have standards-compliant DOMs".

In other words, some concrete analysis would be a more productive discussion.


A paragraph of well thought out text will be ignored. A critical remark on the web framework du jour will be carefully deconstructed, rebutted, and shamed. Funny how that works.


Well for one thing, I really think you're taking this a bit too personally. I don't think anyone here is intending to 'shame.'


If shaming isn't the purpose of downvoting, or the soft suppression of controversial opinions, then I don't know what is.


Crying "shaming" in response to people pointing out your neither being constructive nor producing a substantive point to engage with is, honestly, rather missing the point of how HN works.

The purpose of downvoting is to indicate that your comments mostly consist of assertions that "react is bad" without really making a proper case for it, and as such don't really contribute to the signal of the discussion at hand - especially since the discussion at hand is about an explainer of the architecture, not a critique of the architecture itself.

If you look at e.g. discussions on vue vs. react posts you'll find that the "react is overcomplicated, here's a cost/benefit analysis" opinion is not controversial at all, and that a reasoned discussion of it will be responded to constructively (or that non-constructive responses will themselves be downvoted).


You missed the first sentence:

>A paragraph of well thought out text will be ignored.

I don't feel that it is necessary to have to explain in depth why having such a complex architecture for doing a simple task such as manipulating web pages is a bad thing. It would be like having to explain a joke. Moreover, such a critique would hardly be specific to React, but rather all of the current mainstream front-end web frameworks.


If you've ever compiled Chromium before, you may understand why I don't sympathize with this argument too much. If what we're doing is actually so simple, we lost at step 1.

And maybe, maybe we have.


You haven't really made any constructive comments though, beyond general belly-aching about how shitty frameworks are.


If you're taking this personally, you're not going to develop personally from the critical engagement. Remove your ego from the discussion.


Why would I take comments from disembodied strangers on the Internet on a personal level, or "develop personally" from people replying only to copy and paste verbatim from marketing, doesn't make sense.

All I did was write the only critical comment in this thread. Everyone else who replied to the OP contributed, "great job, thanks A+".


Sure, the abstractions can be different. I didn't say React is literally the only answer. I said it's fast and it beats the naive approach (i.e. jQuery crap.) But even if binding is fast, I think most people who moved on from stuff like Knockout to React do not have any desire to move back. I know I don't.

But if you're going to accuse React's value proposition as being just a marketing pitch, I'd love to hear what evidence that virtual DOM is in fact pointless, and then why Angular 2 and Ember are doing the same sort of thing despite this, even though they have vastly different programming models than React.

Also, regarding your last point, I really doubt Facebook accidentally made DOM diffing without realizing it would improve performance of reactive programming in JS.


No, the main point was that it's

> significantly nicer to code for than DOM binding

There are other ways to code this nicely, but _those_ are slower than virtual DOM. Real DOM _can_ indeed easily be faster, but that's not nearly as nice to program for.


Simply saying "No" after a point and not rebutting it is not a good argument.

A lot of people like to point out that the "real DOM" can be just as fast, but far fewer people have any good examples of this being done.

Yeah, for making a button that signs you up to a mailing list or a simple SPA or something like that, you can just use the DOM. But if you have a complex app with a huge amount of data flow and many components, React (and Preact and etc.) absolutely will beat the naive answer because it will get rid of needless DOM updates. And it will do that without you having to do caching everywhere, because it's all done in one place at the lowest level before hitting the page. I'd love to see the horrible abomination of hand DOM updates that can magically beat a large React app.

edit: Just noticed this wasn't a reply to me, but I think the points I raise here are still fairly valid, if I'm understanding your reply correctly. Sorry if that was confusing.


Yeah, we're agreeing :) "Real DOM" can be just as fast if you do all the work React does by hand, but it's bound to be a mess - resulting in the programmer making mistakes that makes it slower.


Hey if you really feel this way, you might like my new "framework" even more, it does declarative UI in < 100 lines of UMD JavaScript:

https://github.com/guscost/protozoa

Performance optimizations, cross-browser events, and safety features not included. Good luck if you ever have to build a huge UI with it, you'll be the first person to try!

Seriously though, while it's pretty cool for embedding interactive DOM nodes in a webpage, don't think that you always need "simple" when sometimes "easy" is a much better idea.


I am sorry but this sounds like Dunning-Kruger effect on your part. You have created library that you think the problem, but which seems to have limited adoption in the wild. What experience in the field you have? Have you wondered how much you don't know about problems and scenarios that view layer has to handle?

I've been in same situation once with my OS project. I've did something small that I've been certain does what all those other heavier solutions do. But when users came I've learned that there's unimaginable number of edge cases and scenarios that are common enough to require annoying amount of work.

React.js is not "DOM utility". Its battletested view library running one of busiest social sites in the world. It's highly performant, capable of handling thousands of components at single time, and handles countless edge cases, like maintaining input state while user is typing in it and its moved around DOM, normalizing events between browsers, maintaining scroll between large redraws or jumping user to components #fragment.

Ember.js and Angular are complete app frameworks that implement view, layers, services, data, communications testing, tooling and more. Those are solid options for people writing dashboard applications (think intercom or Podio), even if they are losing ground in public-facing sites to more elastic stacks like React or Vue.


This is by the way, a thinly veiled insult. Citing Dunning-Kruger effect is just a way to call someone an idiot who thinks they are competent.

Nobody looks at objective benchmarks. My own DOM utility is faster than React.js, and in fact it is not such a difficult feat, there are a few DOM utilities which are faster, also authored by relative nobodies.

I don't worry about catering to IE8 users, neither do most websites, and that number is vanishingly small. I'm also not interested in competing on complexity, which is what happens when one preemptively builds for edge cases.

I will probably never work on a web app that has a wider reach than Facebook. Setting up arbitrary personal goals for success like working on "one of the busiest social sites in the world" and even achieving that won't make me any happier. How much is enough? I've already proven that I beat Facebook at the DOM performance game, and still I'm the Dunning-Kruger idiot.


But React is bloated. Check it out in comparison to something like Mithril which does everything it does and more in a much smaller and faster package.


Last time I've checked Mithril it had no event normalization, JSX, scroll control and input state preservation. Does it have those now?

I've did Mithril for 6 months year an half ago, before that Ember.js for two years and Angular.js for year even before that. I've eventually settled with React.js because it was just view library, with everything else up to you.


JSX and input state preservation were already there a year and a half ago when you were using Mithril. It does not automatically normalize events, though I'm not sure how important that is in 2017. I don't know what you mean by scroll control.


You can compile JSX to hyperscript.

https://mithril.js.org/jsx.html

I've never needed any of the others, not sure.


I've done very little marketing, and I am effectively a nobody without a huge following or elite credentials unlike some of the people behind the most popular frameworks. It would be completely unfair to judge me based on popularity and making negative assumptions about my experience, rather than merit.

In fact I refuse to market my pet project as if it is something to be bought and sold. or to assign it a valuation based on how many big companies are using it.


Now that the DOM API is implemented in a standards-compliant way across most browsers...

At Facebook 'most browsers' has a very different meaning compared to other websites. When Facebook deploys code that works for 99.5% of their users that means they're failing ~10,000,000 people. Consequently they have a lot of code to handle the cases where they can't just rely on 'most browsers'. It's entirely valid that they maintain a relatively large library, and pretty awesome that they share it publicly.


The place where complexity should be is exactly in third party library with a simple public API, avoiding as much complexity and optimizations as possible in your own application code.


Why does the third party library need to be so complex? And why should there be complexity in the first place?


Not the OP but my answer to that is because something has to be complex in a large web app.

Complexity can be avoided until the number of features reaches some threshold (I don't think there's any debate that it's impossible to avoid complexity entirely if the app is large enough). In those cases, which I think are the majority of use cases, a simple DOM utility like yours would be enough to hide complexity because there wasn't much to begin with.

But some of the websites React powers exceed that feature threshold. For example, if multiple sections of a web app want to update at once, the author could leverage React's lifecycle hooks where needed and rely on its reconciler, but if using a simpler library, might have to explicitly schedule each update in a more hacky/less efficient way.


I think the conventional dogma that one must resort to a framework for a large web app is wrong.

Your assumption that simpler is more "hacky" or less efficient, just isn't true. One can use built-in constructs like for loops in vanilla JS to update multiple DOM nodes at once, this yields the most optimal performance. Or one could use React/Redux and setup an action and a reducer and action creator and action type constant and... you see where this is going.


> One can use built-in constructs like for loops in vanilla JS to update multiple DOM nodes at once

That's not the kind of use case that'd require React. I think we're on the same page that for the majority of apps, that setup is overkill. I'm just pointing out that there are apps with complex use cases where the "see where this is going" will end up being more elegant/simpler than fleshing out your own constructs (certainly more than a for loop)


It's not complexity that you take on. The React API is minimal. It's complexity that the React authors take on in order to provide a stable, cross platform, predictable component lifecycle. And if some of that complexity leaks through, or you don't like the file size of the resulting library, feel free to not use it, but I wouldn't go so far as to say that solving hard problems via sufficiently abstracted away complexity is a bad thing.

With React Native I re-use over 75% of code from the web version of my apps. An actual measurable leap in productivity. Or even just for the web version, React and other frameworks (inb4 "not a framework"), provide their own proven patterns and best practices for scaling a code base, a task that is out of scope of any DOM utility library. And if providing those patterns requires more complexity under the hood, well, you don't refuse a free Lamborghini because it's "more complex under the hood" than your current Toyota.


You're being a bit dishonest in these posts. Maybe it's your marketing style and maybe it works, but it puts me off.

I even see it in your landing page marketing.

    > MINIMAL
    > One function
    > Its entire API surface area is a single function
Then I scroll down.

    var bindObject = require('simulacra')
    var bindEvents = bindObject.bindEvents
    var animate = bindObject.animate
    var retainElement = bindObject.retainElement


This has been revised. There is now a separate entry point for helpers, to make it obvious to people who don't read docs, that it is separate functionality:

    var helpers = require('simulacra/helpers')
    var bindEvents = helpers.bindEvents
    var animate = helpers.animate
There is no practical difference. It is just for those who read code but lack reading comprehension skills.


I'm not sure what that accomplishes.

The "entire API surface area," as you put it, surely includes more functions than the only one you need for a landing page's hello-world. I don't evaluate something like Simulacra with a hello-world in mind, else I wouldn't need Simulacra.

My advice is to just change "one function" to "tiny API". Or maybe "just three functions in the public API". That's just as respectable and spares you from needing to split your API into a pointless "helpers" namespace.

    const {bindObject, bindEvents, animate} = require('simulacra')
^ looks ideal to me.


No, the entire API really is one function. The events and animation helpers can be implemented by the user in a few lines of code, they are not at all required. There is nothing stopping you from adding event listeners or CSS classes without these conveniences. Putting rather trivial functionality in the same level as the only core function would be highly misleading. I would rather completely remove the helper functions, than to satisfy pedants who complain, "but there's two completely optional functions so it's not just one!!1"


There is actually only one function, that is the one returned from `require('simulacra')`, the others are merely conveniences that are common enough, and `retainElement` is a symbol, not a function.

To demarcate this separation better I have considered moving the optional convenience functions into a separate module, which might help clear things up.

Edit: actually it seems that you were being dishonest when quoting me, this is what it says, you cut it off short:

>Its entire API surface area is a single function (with some optional helpers and symbols)

That makes it pretty clear that the core functionality is a single function.


I appreciate your attempt, but we don't need any more astronaut-architects. We have the tools.

It's 2017 and high time for JavaScript tooling to finally slow down a bit and settle into its bigger britches.


>Astronaut-architects

Facebook can come out with a project that's over 40k lines of code, and it is "extremely simple". But no, it is me with my little 5kb function who is the "astronaut-architect".

>It's 2017

I don't care what year it is, you act like the current frameworks are the only viable options in the future. Hint: they aren't.


Let's revisit this in 2020. I have a strange feeling that React will still be heavily used (though maybe encroached by some future framework, you are correct about the changing landscape!) with Angular still trying to follow the leader.


If Angular is trying to follow React (which I'm supposing is "the leader"), it is doing a very crap job of it. I'd say Mithril is following React, but I wouldn't say that about Angular.


Well, that's like judging a car to be difficult to drive by looking at the listings of all the embedded software in its cpu's. These are details of internal implementation. The public API which you actually use is very very simple.

Calling React "DOM utility" does not sound fair. While one of the major problems it solves—slow DOM operations, I'd say that unidirectional data flow is even more important.


Your analogy isn't apt, a better analogy would be judging a car to be difficult to maintain by looking at the listings of all the embedded software. I know a guy who restored a 1960's VW Beetle to working condition with minimal expertise, the same couldn't be done for modern cars without a full machine shop that specialized in that make.

Fancy selling points like "unidirectional data flow" don't actually mean anything. Each fanboy has their own variant of this, like "transclusions", "immutables", "dependency injection", etc. These are all phrases I've heard that don't translate to tangible results.


These are all phrases I've heard that don't translate to tangible results.

Yeah… but they do translate to tangible results. Using something like React helps to make front-end code simple, scalable, fast, and testable.

The car analogy is even worse. A modern vehicle is better than a 60s Beetle by almost every conceivable metric – performance, emissions, safety. In both of these cases, it is preposterous to assume that complexity was introduced for no reason.


These are marketing buzzwords that can be said about every single web framework, effectively thought-terminating cliches. Every fanboy says their preferred framework is the simplest, fastest, most scalable and most testable.

In the car analogy the improved performance of modern cars have more to do with mechanical engineering than software. And the analogy falls apart when you consider that modern web frameworks are invariably slower or roughly equal in performance to its vanilla JS counterpart, but never faster.


It's not a thought-terminating cliche, though. The problem with learning all this terminology is that you apply it to any viewpoint you don't agree with rather than taking the time to thoroughly consider it.

In this case it doesn't make any sense because people who use React (like me) have taken the time to see whether it matches up to its promises. Quite the opposite of "thought-terminating".

Do you have anything to say about how React was the single most loved library in the Stack Overflow developer's survey? https://insights.stackoverflow.com/survey/2017#technology-mo...

Surely it's not just "thought-terminating cliches" getting it up there; if it were, then Angular would have scored just as high as legions of programmers failed to critically analyze whatever framework they were using.

Hopefully you can understand how your ability to say "everyone else thinks in thought terminating cliches about their favorite framework, including everyone I'm talking with, but that doesn't apply to me" doesn't lead to a reasonable debate.


Developers are generally not rational people who critically analyze the pros and cons of the technologies that they use. Honestly neither am I, I don't make decisions based solely on objective measures or benchmarks for that matter.

That is why it's called "most loved" and not "best tool to use", it's based on emotions. And this hardly has any relevance unless you're invested in the developer tools market.


Every fanboy says their preferred framework is the simplest, fastest, most scalable and most testable.

That's a way argument though; just because these are metrics on which frameworks are compared does not mean that there is no comparison possible. In fact, I'd say quite the opposite!

And the analogy falls apart when you consider that modern web frameworks are invariably slower or roughly equal in performance to its vanilla JS counterpart, but never faster

What are you measuring? I'll bet that React will be a whole bunch faster than whatever DOM reconciliation library you build up from scraps of vanilla JS, in the process creating your own half-implemented framework (because I'm pretty confident that nobody builds an entire application using copy-and-pasted Javascript.)

In the car analogy the improved performance of modern cars have more to do with mechanical engineering than software

So what? It's irrelevant. Mechanical engineering of a modern car is also much more complex.


>I'll bet that React will be a whole bunch faster than whatever DOM reconciliation library you build up from scraps of vanilla JS

You don't have to bet, you can verify the results yourself. Look here at these benchmarks [0] and compare, Simulacra.js is 22-42% faster than React v15 (depending on whether you also use Redux or MobX). My "scraps of vanilla JS" performs faster! Vanilla without frameworks/libraries is and always will be king of the performance game, though.

[0] http://www.stefankrause.net/js-frameworks-benchmark6/webdriv...


Those all seem to be single-widget relatively simple benchmarks.

What happens in an app with multiple views on screen into the same state and multiple pieces of data updating at once is much more interesting.

Remember most of these frameworks are aimed at things that are far more 'web application' than 'web site'.


That describes the DBMon benchmark [0] pretty accurately. It has a hundred "components" (rows), each with several subcomponents that re-render based on state changes.

Actually it is less interesting and indicative of mainly one aspect of web app performance, that is re-rendering. The JS Framework Benchmark gives one a more holistic overview that includes bulk insertion, deletion, swapping, events, startup time, etc.

On this benchmark, Simulacra.js outperforms React by a wider margin.

[0] https://mathieuancelin.github.io/js-repaint-perfs/


Your Simulacra.js is a framework, though. Yes, one framework might be faster than another; that's why there are other tradeoffs.


Simulacra.js is a single function (!), not much of a library, and very far from being a framework.


Car analogy was just so say that external API does not necessarily reflect complexity of the implementation.

How much of the buzzword is dependency injection you understand when forced to go through entire codebase and replace instantiation of some concrete class with something saner.

Not every user of some framework is its fanboy, some just choose based on the value they think particular framework provides. And React is not a framework.


To me they very much translate to tangible results. Not having them usually translates into mess that is very difficult to untangle.


Because when you build large web applications, things get complex. Now a large part of that complexity is not my problem. Its Facebook's/React's problem. And I'm fine with it. With that complexity removed I can get things done much much quicker and in a more uniform and modular way than before. Not to mention it performs better. So I'm fine with this complex black box that just sits there and does its thing. And to the OP - thanks. This is quite a feat.


You literally said, "complexity is not my problem". You are the problem.

This is how projects end up with millions of lines of black box dependencies. This is why `node_modules` folders that are hundreds of megabytes exist.

Take a look at benchmarks [0] and tell me, if any framework performs faster than vanilla JS. They probably are faster than vanilla code that you'd be able to write on your own, but that says more about your abilities than the performance of frameworks.

[0] http://www.stefankrause.net/js-frameworks-benchmark6/webdriv...


I disagree with you here. The complexity of my app is my problem. The complexity of how to render some stuff into the screen is not. I don't have the time to deal with both. As far as bloated node_modules - I agree and I will always opt for my own version instead of some trivial npm that has one function in it. But some things I don't have time to deal with. I've done work with All-In Javascript frameworks where you have to submit to the framework, and work within it fully. React essentially eliminated this for me. I don't need a framework beyond React as a view library and perhaps redux to manage state. I can then pick and choose what to bring in as 3rd party because it saves me time and what to implement myself. I've also done a good deal of Vanilla JS which has its place for smaller projects. And more often than not, those smaller projects grow beyond "Vanilla".

Doing my own thing is of course possible and in many cases is fast to get something up. But doing it correct and proper takes a lot of time and attention. When I'm trying to get a project going - time is not on my side, but I still want it done correct and proper. If someone comes in and does a complex part of my app correctly, I'd use it. Its NOT a problem.

Edit: By the way, taking a snippet of a line from what I said and quoting it without its context does not make for good discussion.


>The complexity of how to render some stuff into the screen is not [my problem].

But it is. You are depending on some complex third party code to do your job, how you want to punt responsibility to someone else is irrelevant. Web developers aren't owning up to the sorry state of front-end web development, because everyone says "it's not my problem", ask Facebook/Google/whatever.

Correct and proper have little meaning if at all in web development, they're usually dictated by the biggest companies and most popular bloggers. Moreover, these definitions are constantly in flux (no pun intended). Nobody cares if your web app correctly follows the proper conventions of your framework. Front-end web developers seem to focus more on navel-gazing about the "developer experience" than results.


But you're missing a context here. My context. I run two companies and contract on top. I also have a life. If any Big Company (tm) wants to give me a good solid presentation layer blackbox I'll take it and say thank you. I could develop my own presentation layer/frameword du jour/library/toolkit/whatever. But WHY would I do that when its already done. And those who did it do it full time as their day job, paid by said Big Company (tm). So i'll ride that train and use their blackbox and focus my energies where they are needed - in domain specific business logic that actually generates revenue.

I'm having fun doing it but i'm not doing it for fun.


> You are depending on some complex third party code to do your job

Yes. It's called a web browser.

The additional complexity of react is a drop in the bucket compared to the complexity of the undertlying platform.


Haha so true. I keep forgetting that... I take browsers for granted sometimes.


Minimalist, modern web browsers exist. A good example of this is surf [0], which is based on WebKit and is <50kb of C. That's less than half the size of React source. It obviously doesn't have all the features that Firefox or Chrome might have, but demonstrates that browsers don't have to be bloated.

[0] http://surf.suckless.org/


I would rather the complexity live in a third party library with an extremely simple public interface than have it live in multiple 1000 LOC of vanilla JavaScript that's laid out however whoever wrote it felt that day. You couldn't pay me to do frontend without React - the developer experience is absolutely terrible.


It is a dogma that React has an "extremely simple" public interface. It's got two different flavors of "components", "lifecycle hooks", "synthetic events", "prop types", and more that I'm missing.

Why do you assume that vanilla JS code is terrible? Is it because the average developer can not be trusted to write competent code without the conventions of a framework? If one cannot write competent code without being completely dependent on frameworks, I wouldn't trust them to write code at all.


>They probably are faster than vanilla code that you'd be able to write on your own, but that says more about your abilities than the performance of frameworks.

I won't be able to write efficient vanilla code for something even slightly more complicated than this benchmark, and I wrote one of the fastest virtual dom implementations out there, so what you expect from an average web developer?


I'm not saying, "don't use an abstraction on top of vanilla DOM code".

Better performance just isn't a valid reason to use a DOM abstraction, it's a non-argument.


Performance was never the only reason. In fact its the last reason on the list. Development speed and efficiency and the modularity of it all is what sold me on React.


That post doesn't benchmark how a team of developer worth together, or how you manage all your code.

The speed of a for-loop is only a part of what makes a codebase 'fast'.


The current state of front-end web development isn't a mess, it's actually the opposite. I would argue it is bleeding edge. If you look at it from an engineering perspective (inside-out), it's probably not the best. But if you're looking at the quickest way to deliver value you to your customers, it is unmatched. Every other application development stack other than front-end development requires compile, build and deployment steps. With front-end development, you can literally reach billions of customers whenever you decide to do so. The only requirement is a somewhat modern browser. The current state of front-end development is amazing.


I agree that React introduces way too much complexity.

From a quick look at your approach, I have one concern:

    <template id="product">
     <h1 class="name"></h1>
     ...
You seem to use classnames as variable names. What if some other template has a "name" variable too? What if a stylesheet uses it?

I prefer simple placeholders. Instead of:

     <h1 class="name"></h1>
I would use:

     <h1>{{NAME}}</h1>


Using class names was just an example, people may get the wrong impression that has anything to do with the variable name. It could have been made more explicit, but I wanted to be as terse as possible:

    <h1 class="name" data-bind="name"></h1>
It was also a design goal not to introduce a templating syntax, so `{{}}` brackets are out of the question.


I see now, that the bindObject() function takes a mapper from data to DOM.

There are two downsides to this:

1) You have to define twice where the data is displayed. Once in the template and then again in the mapper.

2) <div>{{NAME}}</div> explicitly tells the reader "The name goes here". In your solution one would have to look it up in the mapper to be sure what goes where.


I'm well aware that there must be an element and a selector for that element. But this is exactly how CSS works as well, it's separation of concerns. Only recently have inline styles become trendy, much to my dismay.

The total absence of templating syntax is a deliberate decision. It enables one to start from an HTML mock-up or static page, and build interactivity on top of that without changing any HTML.


    this is exactly how CSS works as well
I beg to differ. There is no mapping needed for CSS. CSS works by once defining where the style shall go:

    <div class=city></div>
And once what the style is:

    .city {color: blue; font-family: arial;}
Similar, template syntax once defines where the data shall go:

    <div class=city>{{NAME}} has {{POPULATION}} residents</div>
And once, what the data is:

    city={name: "New York", population: 8491000}
Neither need additional mapping.


I'm not sure I understand what you mean by additional mapping.

Here's all that's needed in the template:

    <div class="city"><span class="name"></span> has <span class="population"></span> residents</div>
And the mapping would be:

   [ 'city': [ '.city', { name: '.name', population: '.population' } ] ]
If you don't want to manually define a mapping, you could do it automatically by assuming that some attribute like `data-bind` corresponds to a binding, but Simulacra.js doesn't make assumptions like that.


    you could do it automatically by assuming that some
    attribute like `data-bind` corresponds to a binding
Yes, that could be done. That would mean to extend Simulacra. Or do it outside of it.

To me personally, <div>{{NAME}}</div> is easier to read and reason about. Also, it enables you to do stuff like

    <div>{{CITY}} has {{POPULATION}} residents</div> 
Which is much shorter then

    <div><span data-bind="city"></span> has <span data-bind="population"></span> residents</div>
You can also do other useful stuff. For example:

    <div class="{{STATUS}}">{{MACHINE}}</div>
And then style different statuses via CSS.


Sorry, but avoiding templating syntax was really a hard design goal. It may not be a tool for everyone.

The reason is that every templating language I've used either is or becomes a Turing-complete language by itself.


What would force you to make your own templating language turing complete?


Well, actually it looks like (IMHO) there are too many abstractions levels, in fact - I omit many of them on the scheme, and it's still complex. But if we think why that happened, it's because of multiple platforms supports mostly (native, server rendering, etc), each "sensitive for platform" part of logic requires at least module with interfaces, modules with implementation per each platform, module-injector for exact implementation and so on..


> looking at this giant UML diagram

It's not an UML diagram. Looks more like an ad-hoc flow chart (unless I forgot a specific type of UML diagram that looks like this).


I think it's a UML activity diagram, which is in fact a flow chart.


I was taught UML activity diagrams were high-level representations, while this is a (summarized) flow chart of code paths (which makes it quite big in comparison to what would be its high-level UML counterpart).

UML is supposed to be an architectural diagramming standard. What's the point of diagramming in UML the actual code paths?

E.g.: you'd never have object shapes or function calls in an UML activity diagram.

This is just an ad-hoc flow chart AFAICT.


I've read the first few pages, and am really appreciating the level of detail this goes into.

Fantastic work and a great resource for people wanting to dive into React's internals.


I wish the code we write write everyday carried enough semantic meaning in it for such visualizations to emerge naturally from it.

Great work by the author nonetheless.


This is helpful to me because I want to learn how to explain (complex) systems.

Incidentally, this complexity is what led me to build my own little vdom utility <https://github.com/hyperapp/hyperapp>.

I'll be drawing inspiration from this chart to explain it.


At this point I'm sure I and others sound like a broken record, but if you're new and just jumping into frontend component-based frameworks, please don't start with React.

There are simpler ways to get reasonably fast re-usable components on your project that introduce less accidental complexity.

Carefully consider which thing you actually need:

- A view library that uses components as the main building block (this usually means you already have other concerns like data modeling and routing taken care of)

- A full SPA framework (which people often get from the react ecosystem, i.e. React + Reflux/Redux/etc + React-Router)

Based on which one you need, there are other simpler (in the case of view libraries), and more coherent (in the case of full framework) choices.


React is a view framework, and knowing the internals of React is a completely unnecessary set of knowledge for the majority of developers using it to build products with.


As with anything, the longer you use a library, the more you must know at least some of it's internals to use it efficiently/axiomatically/well. Even something small like the class/className attribute thing is an implementation detail that leaked through, which will bite and likely confuse a beginner for 3 seconds if they didn't throughly read the docs.

Other libraries don't have that problem (because they didn't accept that trade-off in that fashion).

IMO Libraries that beginners should be shown should not be ES2015-in-every-example, and introducing transpiled DSLs for generating DOM elements.


I still love knockout. A simple view layer on top of whatever other architecture you want. Has worked really well for me for years.


Yep! One of my favorites (I didn't mention it because I didn't want to make it seem like I was just trying to push people towards another framework).

KO also has components now, and they work super great. Also, while bigger frameworks like Ember (which I love) are just starting to figure out and cement how they work with engines (dynamically loaded chunks of your ember app), KO supported async loading of components with RequireJS so long ago.


Perhaps you're right, but it would be useful if you mentioned those other choices here.


Sorry I actually purposefully didn't mention them because I didn't want it to seem like I was just trying to push my own favorite choice.

Here are some options:

Component libraries -------------------

1) KnockoutJS (just data-binding, quite possibly the simplest I've seen)

2) Vue.JS (More complex, but one of the best sets of docs I've seen, fits in with the DOM model extremely well, few hacks, though I would have loved a simpler data-binding system)

3) Mithril.JS (super small, super fast, very simple. Transpilation tradeoff, it makes you just write the DOM as a JS function with elements like `m('div',[...])`. Have yet to use this one for a large project, but will very soon. Also has a little bit more support for the other thing you might need for a Single Page App.

Full fledged frameworks -----------------------

1) Ember (has been around a super long time, changes fast which is good and bad, and is great for large projects because it has a solid set of conventions)


Thanks for coming back some days later to answer my question!


No problem! Apologize for the delay I didn't see the responses till much later. There are more obviously lots more options, but those are my go-tos for now (I try to kick the tires on new libraries/frameworks as often as I can).


I don't know how long it will take, but I'd bet that within a few years everyone will be hating on React like they hate on jQuery now.

"Seriously dude, you're still using React? That slow, bloated pig that creates a call stack 75 frames deep to change the label text of a button? Sheesh, get with the times, and use _____.js! It rocks!"


Fantastic. Thank you so much for this.



fixed, but it's still nothing there. I work on a big scheme for Fiber, it's far from 'ready'...


This is super cool, thanks, I'm eagerly waiting for comparison with fiber.


Detail. A+


Nice work, but some parts make as much sense as Lorem ipsum text. One of my favorites so far:

> An instance of what should be created (03)? Component… right, but which one? Well, it’s a good point. No, not <ExampleApplication /> that’s 100% :) We actually should instantiate some internal class. Let’s check out the next scheme at first.


thanks, fixed that.


Wow, you really spent a lot of time of this, but why? What's the purpose? How do React shenanigans can help me to be a better developer?


You don't learn anything by studying other architectures?


For even more fun, compare with inferno


FWIW a React lead said Inferno is how they would've designed React if they had to do it from scratch, and it's author joined Facebook to push React efforts forward.


So does that mean inferno is both theoretically better and already dead? :(


Hehe. I think it's Open Source at play: X publishes an innovative method, Y iterates with a cleaner version benefiting from lessons-learnt, X says "awesome, let's join forces!" and they live together happily thereafter. Inferno passed over to another lead who's pushing it forward.

IMO this is a good outcome: there is some marginal value in yet another "React-like but faster" library, but the same energy could help a lot more people if applied directly to the source of the madness.


"Inferno 1.0 is really well written. It's how I would've rewritten React. I'd recommend reading its source to learn." - reading the source is much more effective than reading an article written by someone who read the source code.


What are you doing on HN when you could be off reading source code?


I don't think that your question makes any sense. I read both of HN and the source code.


And people can read both the article and the source code.


this's the answer.


This is very specific architecture for a very specific product. I really don't think that I can learn anything from all these UML diagrams. I was just wondering what the author had in mind.


Still not really a UML diagram. It's a flow chart. Of course if javascript programmers encapsulated things with actual objects then maybe UML would be applicable.


flow chart != UML activity diagram?




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

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

Search: