Deku: How we built our functional alternative to React
segment.com
segment.com
I feel a little disappointed to be honest. Because as I was reading, I was expecting to read that you somehow had created a dom-diffing algorithm and matching library that was more performant than React.js, but really it just came down to the fact you didn't like how React.js looks. I was rooting for you from the beginning, expecting to see someone had created something superior to the much hyped React, but it didn't happen.
I don't want to hate on what you've done, looking through the code reveals that you put some considerable effort into Deku, but it makes me wonder if that effort could have been spent on perhaps learning the inner-workings of React.js and adapting it to your needs in its own fork. But having said that, Deku to me only has a few slight differences to React.js, the way components are built in Deku in comparison to React.js doesn't appear to be that dramatically different.
I don't want this comment to come across as yet another cynical HN commenter, but I just cannot see anything comprehensively different to existing solutions. I hate seeing talented development hours going to waste that could have been used to make an already existing project better.
Even if the performance was at React's level, a first pass at Deku shows it as much preferable to React in terms of coder experience.
This framework is genuinely different from React in how you use it. I know several JS programmers who prefer functional style, yet choose to incorporate React-style classes because React is really good at what it does. This gives them an alternative.
The components built with Deku will be different in programming style. And that's really, really significant.
Also check out mercury:
https://github.com/Raynos/mercury
Or better yet, fork mercury and modify the index.js file and package.json. It's a bunch of libraries masquarading as a framework (which is awesome because it means it's modular instead of monolithic)
They didn't go to waste. They made Deku and learned a lot along the way. Just because something exists, doesn't mean you can't build your own. And not everything has an immediate, positive outcome.
I wrote my own MP3 Player back when Winamp really whipped the llama's ass. That got my name in a local newspaper in India, which ended up being the small boost I needed for the Consul General to grant me a Student Visa to come to the US. A few years later, a fan of my MP3 Player messaged me and we became good friends. I interviewed for a job in Florida and ended up staying at his place for the weekend. A few years later, while I continued to work at the job in Florida, my friend and I built a scheduling webapp that made it to the front page of Wired during SXSW.
An incredibly long list of positive things that happened in my life, I can track back to spending a week or two writing that MP3 player in my youth. If you ask me, I'd do it all over again. So I'm glad they build Deku, regardless of how it compares to React.
There may or may not be value to other potential users or even to the employer though and these seem to be the only perspectives addressed by commenters.
If the company's resources could have been better spent elsewhere than that is the company's (and its stakeholders') problem. Please stop discouraging others from creating and sharing because you don't find the creation better or worthwhile right this instant.
If Deku looks solid enough I might consider using it. And hopefully it can influence React too.
- size/complexity: React is a monolith that can't be digested by just skimming a couple small files
- API surface area: less room for major semver bumps
- modularity: React devs seem to fear dependencies
- versioning: React encourages the use of peer dependencies which is truly going to be a nightmare in 2 years with hundreds of UI modules across different conflicting React versions
- no singletons: React can only be required once, otherwise bats will fly out of your computer. This is compounded by the versioning issue.
- style: React uses and encourages a different programming paradigm
I was watching a video posted this morning (how NYT uses Go) and the dev was mentioning how challenging their system used to be with different languages - Python, PHP, Java and Groovy ... so they decided to redo major chunks in Go. Seriously?
I don't pretend to have the answer ... stopping to innovate isn't going to cut it. But I increasingly feel that as a tech worker, I'm on a train careening towards a ravine without a bridge. But hey ... lets go faster and it'll be a fun ride!
What "shelf life"? If the library works for what you app needs it to do, there is no use by date.
Valid reason for a rewrite, especially considering the quality of one or two of those languages. A language can look and run OK when used for a script calling system code, but when those scripts are glued together and become the system, all sorts of problems can manifest. It's only sensible someone there looked at the sit and planned out a replacement.
To the new-to-JS programmers out here, I'd recommend waiting until a framework reaches a certain level of maturity. React is not just about the core library itself, it is also about the tooling and ecosystem. For example, you can use React dev tools in Chrome. You are more likely to find how-tos and documentation if you're using React. React Native might help with sharing code if native mobile is in your plans.
Like the documentation says, what this framework really gives you is the ability to skip the OO-style coding that React mandates, and use just functions and modules.
Really? You found that it was better to write everything from scratch instead of modifying mercury for your use (thus making use of the very good virtual-dom library)? Do you know that the whole mercury source code[1] is only 126 lines of code?
Perhaps you should also know that your library usage examples, in the end, look just like mercury usage examples.
https://github.com/Raynos/mercury/blob/master/dist/mercury.j...
mercury is lean, it's an weekend's read at 2.5kloc. (virtual-dom is 1.1kloc, an evening's read.)
[1] https://ripplejs.github.io [2] https://news.ycombinator.com/item?id=7609816
The original plan was to make a virtual dom plugin for ripple but it wasn't really possible with the way the worked behind the scenes.
The only cogent reason offered for writing yet another front end framework ...
https://medium.com/@tastejs/yet-another-framework-syndrome-y...
The best reason is: Not bound to Facebook License and Patents.
Mercury is a collection of libraries together which can be used as a framework. The most comparable subcomponent of mercury to deku is virtual-dom. Comparing virtual-dom and deku is pretty simple: v-d is not "component based" and has no internal state management.
Note that this isn't mixing just any JS, it's only presentational javascript. Either you're using some templating language like Handlebars or Jinja/Django's or Angular's HTML attribute data binding, or lots-of-jquery-selectors-tied-directly-to-the-html, you still need some sort of view logic to build your DOM.
Don't get me wrong, I've never really used React/JSX in depth enough, and I'm not overly enthusiastic about all these 'HTML' tags in my JS. But lets not pretend this is any worse than the current approach of $('.modal').append(document.createElement('button'))
I think it is very different than the spaghetti pages found in jsps and php pages of yore, and the emphasis on component is a big part of why.
I think part of the problem is how you think about it. You're not writing some HTML and then some Javascript to manipulate it. Conceptually, you're writing a Javascript function to create a chunk of HTML.
I personally lean towards logic interpolation (Handlebars, AngularJS), but both have their potentials for abuse. I don't know enough about JSX to say one way or the other what good practices are enforced and what bad practices are available.
Maybe for a static website, it doesn't feel right. But for a webapp it feels much better than before for me.
I hated it (a lot) before I tried it out. You could just put the render function in a separate file since it's just a function and then it's basically the same as a template anyway
Because transpilers.
Introducing multiline string comments to ES6 (python syntax) would have been a better option.
""" <div> <p> {{ hello_world }} </p </div> """
jsx`<div><p>${hello_world}</p></div>`
I don't know why it'd be a better option. You're moving the time/cost of parsing client side and preventing minification. If you're going to do a build time parse, I don't understand what the extra quoting buys you.I personally find:
<div>Hello {this.props.name}</div>
To be more elegant than: React.createElement("div", null, "Hello ", this.props.name)
Of course react allows you to use whichever you prefer.Unless you know LISP, then you understand code is data.
JSX is a far cry from how Lisp does things. You get all of the nastiness of the redundant typing involved with hand-writing HTML mixed in with your JavaScript, plus the addition of another compilation step in your build!
I like Mithril's virtual DOM API[0] much more. It's really pleasing to use, but of course not as good as SXML in Lisp because JavaScript doesn't have macros or quasiquote.
Having extensively used nested function call (like MochiKit.DOM [2]) and nested JSON-ML-ish array (like dombuilder [3]) variants of DOM builders in the past, JSX's syntax is a lot more friendly to write and maintain.
[1] http://facebook.github.io/jsx/ [2] http://mochi.github.io/mochikit/doc/html/MochiKit/DOM.html [3] https://github.com/creationix/dombuilder
export let Button = {
render({props, state}) {
return <button>{props.text}</button>
}
} /** @jsx element */
export let Button = {
render({props, state}) {
return <button>{props.text}</button>
}
}
[1] http://babeljs.io/repl1) export and let are part of ES6 2) <button> is JSX, which is uses by Facebook's React but can also be used with Deku.
If you run that through babel, it turns it into valid ES5 Javascript which will run in any modern browser:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var Button = {
render: function render(_ref) {
var props = _ref.props;
var state = _ref.state;
return React.createElement(
"button",
null,
props.text
);
}
};
exports.Button = Button;
(Note: By default Babel translates JSX into React.createElement calls; the Deku docs cover the one line config changed needed to make it us Deku element calls instead.)Immutability and lazy eval are both really well implemented with OOP interfaces even though I consider both functional concepts.
I read this recently: semantics != syntax.
https://github.com/muut/riotjs/blob/master/demo/todo.js
vs
https://github.com/segmentio/deku/blob/master/examples/todo/...
Does look like riotjs might be re-factored in some interesting ways, if they move it to ES6 though.