8 ms·
In search of the perfect JavaScript framework
- carsongross 12y agoMy theory is that, for much of the web, the perfect javascript framework is no javascript framework. Get rid of all the abstraction, local state, dependency injection, symbol management and so on. Take HTML/HTTP seriously and think about REST in terms of HTML rather than JSON. That's intercooler.js: http://intercoolerjs.org http://intercoolerjs.org Here's an image I tweeted trying to explain how to get there mentally: https://pbs.twimg.com/media/B9QNU-ZCQAECP-K.png:large https://pbs.twimg.com/media/B9QNU-ZCQAECP-K.png:large Yes, it's a simple model. And no, it doesn't work for every app. But many apps would be infinitely simpler and more usable in a browser by using this approach, and almost all apps have some part of them that would be simpler to implement using it.
- logn 12y agoYou lost me at "That's intercooler.js"
- nawitus 12y agoHow about using Web Components? They seem to solve most of the problems that JavaScript frameworks try to solve.
- talwai 12y agoThis, I like. I'm interested in seeing a progression towards client-side code assembled around libraries like intercooler.js rather than frameworks. I'd like to be able to pick and choose libraries to handle DI, routing, templating, HTTP et cetera in a manner that allows me to tweak/override as needed. I'm fine with foregoing the prescriptive structure that a framework like AngularJS lends to an app - structure is something you will spend time thinking about framework or not, and enough tools exist to let you write modular client-side code without being prescriptive
- ahoge 12y ago"No framework"... so here is a framework. Uh hu. Anyhow, move that "use strict;" line into the IIFE. If it's global, you can't merge that file with other files. Some of the code out there breaks in strict mode. That's why it isn't enabled by default.
- carsongross 12y agoWell, it's a library, not a framework: you can use it for as much or as little of your app as you like with as little as a single attribute declaration doing something useful for you. On "use strict", my understanding was that it applies per script: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... Strict mode applies to entire scripts or to individual functions. Am I misunderstanding?
- Stratoscope 12y agoMany sites have a build process that concatenates multiple JavaScript files into one. If they concatenate other scripts after yours, your "use strict" will apply to all of them. Since the rest of your script is already enclosed inside a single function, simply move the "use strict" a few lines down so it is the first line in that function. Then it will only apply to your own code.
- ahoge 12y ago> Well, it's a library, not a framework: you can use it for as much or as little of your app as you like with as little as a single attribute declaration doing something useful for you. If it has an entry point, it's not a library, it's an application. If said application does basically nothing on its own and you're supposed to extend it, it's a framework. http://en.wikipedia.org/wiki/Software_framework http://en.wikipedia.org/wiki/Software_framework Pay close attention to the 4 bullet points in the first section. > On "use strict", my understanding was that it applies per script Yes. However, when you merge scripts, there is only one script at the end. The site you linked to also mentions this problem. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode#Strict_mode_for_scripts https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... "This syntax has a trap that has already bitten a major site: it isn't possible to blindly concatenate non-conflicting scripts. [...] It is thus recommended that you enable strict mode on a function-by-function basis [...]"
- failed_ideas 12y agoI'll be honest, I'd be much more receptive to you doing a show hn over pimping the framework in the comments of every js post.
- carsongross 12y agoFair enough.
- untog 12y agoGet rid of all the abstraction, local state, dependency injection, symbol management and so on. Take HTML/HTTP seriously You can't just say "remove local state and use HTTP instead" - people didn't invent local state from nowhere, it has a lot of advantages to relying on an HTTP call for everything you do. Particularly when you're scaling out widely or when you're dealing with mobile devices.
- _asummers 12y agoOr when dealing with some of the offline features of HTML5. Those are literally impossible to do without some local state.
- weego 12y agoThe irony of suggesting a framework that abuses html attributes in templates to wire up massively abstracted behaviour as a response to someone tearing into the obsession of JavaScript devs with over-abstraction. You do appear to be overly keen on pimping it, but it looks kinda unnecessary.
- juliangregorian 12y agoIt's not really abuse in an HTML5 paradigm, attributes are meant to be extensible and semantic.
- oneeyedpigeon 12y agoWhy not actually use the mechanism that html5 allows for (i.e. data-* attributes) rather than making up your own, that it doesn't?
- juliangregorian 12y agoJust guessing: (1) it's not actually "data" and this provides more meaningful cues, (2) it provides a bit of namespacing so as to not step on the end developer's own data-attributes, (3) turns out that it doesn't actually break anywhere after all, as proven by many JS frameworks at this point. I tried briefly to track some standards down for you, but I know this gets discussed at length on the Angular mailing lists if you really care for the nitty gritty.
- thirdsun 12y agoAs a developer that recently made the transition from FileMaker, which is very user-friendly but limiting, to Rails, I love the new possibilities and the fact that Rails provides nearly everything I need and comes with established best practices, but I'm always a little helpless when interactivity (without reloading the page) is required. The apps I'm working on (internal, business apps) mostly work perfectly fine with a document-based approach and most features can be integrated as simple CRUD actions, but from time to time I need just a little interactivity - like in a classic scenario of an order with several line items that needs to calculate and display totals in a form as soon as the input changes. It's that simple, no need for a framework, even most libraries feel overblown for that use case. I looked at various data-binding javascript libraries, but they all seem like targeting much bigger problems than mine. So I resort to classic jquery, data attributes and ajax calls, but it feels very messy, like a hack not intended to work that way. It may be the fact that I'm new to this but it feels as if I'm missing something very obvious whenever I have to deal with that kind of very basic interactivity and dynamic. It's a simple form that temporarily needs to calculate and process inputs until the user saves the record and solving this seems way too complicated and messy. Are there any options for those simple cases and apps that otherwise would do just fine with a document-based architecture?
- fastball 12y agoI found that my experience with Dart seems to meet those criteria nicely. https://www.dartlang.org/ https://www.dartlang.org/
- rapind 12y agoYou might want to play with React and it's ilk. It's basically a framework for only the view, and it's pretty easy to reason about once you wrap your head around it. You're just asking for calculated fields on change events right? jQuery is fine for this too, but can become painful to use and organize once you have a lot of DOM manipulations. React only starts to get complicated once you dive into the Routing + Data Fetching + Flux stuff IMO. React on it's own if you don't need any of that is pretty simple.
- lastofus 12y agoI found Knockout to be a great middle ground for when "I can do this in jQuery, but it's gona be messy" and "I'm building a SPA". It hits the sweet spot between easy learning curve, abstraction, and interacting with the DOM nicely. Sadly, it's not as hip as React/Angular/Ember these days.
- zak_mc_kracken 12y ago> Get rid of all the abstraction, local state, dependency injection, symbol management and so on. Take HTML/HTTP seriously and think about REST in terms of HTML rather than JSON. So basically go back to writing Javascript like we were doing ten years ago? No thanks. I was there, it was hell, I hated every second of it. The Javascript framework scene is very chaotic today but it's exciting, a lot of new concepts and approaches are being discovered on a weekly basis. A lot of them won't pan out but some will, and they will make writing Javascript even more fun than it is today. And one thing I know for sure: it's hell of a lot more fun to write Javascript today than it was ten years ago.
- padolsey 12y agoI get your point but, for me, it was more fun back then. There was more to hack on; heck, you could craft your own selector engine and people would use it. Awesome. Now, seemingly, all there is to do is build yet another CRUD application with whatever framework is hottest.
- mercer 12y agoI'd say not having to worry about 'crafting your own selector engine' and stuff like that leaves you free to spend you creativity on things that are a bit higher on the abstraction ladder. Yes, it makes things that once required creativity more boring, but shouldn't that be cause for excitement that you can now be creative about other things?
- beat 12y agoIt's a thought-provoking article, but I would also like to see something about React in it. It seems to me that React is a very pragmatic way to get around the global complexity-driven performance issues with DOM manipulation. When we're coding, we're optimizing for a couple of different things, really. First is real-world performance (represented by slowpoke DOM manipulation). Second is programmer performance (represented by inappropriate abstractions). A lot of things we can do in Javascript to make programming less difficult and complex result in poor real-world performance, and vice versa. But what do I know? I'm not by any stretch of the imagination a Javascript expert.
- wwweston 12y ago> Abstraction is dangerous True statement. Of course, it's more or less true, depending on how much the abstraction you're using leaks. Few (if any) abstractions completely encapsulate complexity, almost all will leak. But there's a range. Some abstractions elegantly cover a modular portion of your problem space and do it so well you only rarely have to think about what's going on under the hood (and will even produce effective clues as to what's going wrong when something does go wrong). Some abstractions awkwardly cover only part of a modular portion of your problem space, require a high intellectual down payment to even start to use, have gotcha cases that chew up performance or even break things, and require continual attention to what's going on just to keep development going. Most are probably in between. I think this is what JWZ is talking about in his famous "now you have two problems" assessment of regular expressions. I don't read him as saying "regular expressions suck," I read him as saying anything but tools from the high end of the abstraction quality spectrum means now you have two problems: (1) the problem you started with (2) the problem of keeping the model/details of how the tool works in your head. Regular expressions are arguably in the (maybe high) middle of the spectrum -- they may not cover your case well (ahem, markup) and they can send your program's performance to hell or even halt it if you don't know what you're doing. Now, they're also broadly useful enough in all kinds of development that the benefits go up with the costs and so they're probably worth investing in anyway, as part of a suite of other parsing tools/techniques. So I'm not bringing the topic up to bash them. But to take us back to the topic, I might be bringing it up to question the ROI of popular JS frameworks, which, as far as I can tell, are generally not at the the high end of the abstraction quality spectrum, don't have the broad usefulness of regular expressions to recommend them, and may not even survive longer than a handful of years.
- ef4 12y agoNo, it's not a true statement. It's fundamentally wrong. Because if abstraction is dangerous, we should all be laying out transistors by hand instead of writing code. People get so comfortable with their familiar abstractions that they forget they're still abstractions. Taking the article as an example, even his "less abstracted" examples are absurdly abstract, and I doubt anybody here can really say for sure how they work completely, underneath all the abstractions. That's a good thing, because it lets us get things done and express ideas in hardware-independent ways.
- drawkbox 12y agoAs long as your javascript framework is a micro framework and not a monolithic one, the abstraction does not make the project foggy. Building the core and then using micro frameworks or components like react, jquery, etc leads to less walls as swapping is easier as time progresses. You don't want to be caught high and dry stuck in years of monolithic to cleanup when the fad dies and at that point having abstracted away everything you need to know. Outside of javascript, .NET WebForms and Drupal are classic examples of too much abstraction in monolithic fashion (those poor bastards stuck there - dead man walking), Angular might be another. The whole time you spent building addendums and machinations to a framework, not building the core of what needs to be known. If the framework changes everything you do and abstracts core logic or the systems you are building doing things without you being aware, it might be easy to start 90% but there are gonna be problems and eventually walls and walls against you. The only thing that should be monolithic and the base is programming languages and platforms. Everything else should be micro components or messaging.
- danabramov 12y ago>We want to apply values to variables and get the DOM updated. The popular two-way data binding should not be a feature, but a must-have core functionality. Strongly disagree. I find one-way bindings and one-way data flow much easier to reason about. A little less boilerplate code is not worth mental overhead, cascading updates and hunting down the source of wrong data in my experience. What is important is not updating the DOM from the code and instead describing it with a pure function. React, Cycle, Mithril, Mercury do it, and it's time we get used to this. This is the real timesaver, not two-way bindings. `Object.observe` is the wrong way to approach this problem. If you own the data, why invent a complex approach to watch it, if you could update it in a centralized fashion in the first place? Here is a great presentation on that topic: http://markdalgleish.github.io/presentation-a-state-of-change-object-observe/ http://markdalgleish.github.io/presentation-a-state-of-chang.... I strongly suggest you read it ("Space" to switch slides) if these ideas are still alien to you. Even Angular is abandoning two-way bindings. http://victorsavkin.com/post/110170125256/change-detection-in-angular-2 http://victorsavkin.com/post/110170125256/change-detection-i... I, for one, welcome our new immutable overlords.
- joshontheweb 12y agoAlso, data bindings assume you are working with a DOM which isn't always the case. If you make a video game using canvas built-in data bindings just get in the way.
- sombremesa 12y agoEven when you are working with DOM, if you are on a device with limited capabilities (e.g. mobile devices), depending on the number of elements on the screen the bindings can cause the DOM to take a long time to render. Normally not a huge issue, but it helps put AngularJS + Phonegap in an even worse position than before against native apps.
- nilliams 12y agoYep the Ember team also seem to have come to the same conclusion on 2-way bindings. My dumb takeaway is something like '2-way bindings demo well but are rarely what you actually want in real apps'. I think (not 100% sure) Tom & Yehuda (of Ember) talk about how they became disenfranchised with 2-way bindings in their recent Changelog podcast episode on Ember 2 [1]. [1] http://thechangelog.com/131/ http://thechangelog.com/131/
- deleted 12y ago[deleted]
- acdlite 12y agoBad abstractions are dangerous. Good abstractions are empowering. cough React Native cough
- rhapsodyv 12y agoI LOVE ExtJS!
- djabatt 12y agoWhere does react.js fall in this discussion? Or does it? Just reading a lot about react.js this week.
- mark_l_watson 12y agoA difficult article to write - I would not have tried. There are so many good alternatives and choice depends on the application and available skill sets. I spent time today working in Clojurescript which wraps the Closure library. In the last month I have used Ember.js, Clojure with hiccup, and meteor.js. I really like all of these tools and frameworks. I used to use GWT a lot, and almost committed to Dart. So many good choices.
- akrymski 12y agoOne super simple framework is https://github.com/techlayer/espresso.js/ https://github.com/techlayer/espresso.js/ It's a bastard child of React and Backbone.
- thekingshorses 12y agoI like the direction author is going. I have used similar methodology designing my applications (for mobile), simple, micro libraries, one way data binding. http://hn.premii.com/ http://hn.premii.com/ http://reddit.premii.com/ http://reddit.premii.com/ * I have bunch of helper functions (UI and non-UI). Each function define in its own file and independent (easy to unit test). Personal library like jQuery but not a jQuery replacement. * App is route based. One route to many controllers. Each controller is a page/screen on mobile. * There is only one model (API) that interface with 3rd party library. API layer talks to 3rd party library to get data or gets data from server directly, caches data, etc. Provides sync (Cached data) and async (Cached data or fresh from server) interface to controllers. * There is a app class or I call it a page manager. Responsible for managing pages like ordering, loading, unloading etc (Kind of big and complex 200+ lines of logic). - Decides which page to animate in which direction on mobile (Loading new page or going back). - Order of pages (Back button) - Passes events to its controllers - Decides which pages to keep in DOM, and which to remove. --- If you go from homepage to comments to profile page, all pages are in DOM. --- When you go back to comments page from profile page, profile page will be destroyed and controller will be notified. Same happens when you go from comments to home page. --- If you go to same comments page again, it will be loaded as a new page. * Controller: - Each controller may have multiple CSS and templates - Controller uses its template to render - Using sync API to get data to renders page. - If sync API returns no data, renders empty page with loading, and makes async API call. - Controller are idle when transitioning (animating) from one page to another on mobile. (Very important for smooth animation) - Simple but fat controllers - Controller handles events, UI logic - Self cleaning so that browser can collect garbage when necessary I package app using node/gulp. Anything that is not specific to page/app related, it becomes part of a helper library. Each app has its own model (Data layer), and controllers. I use micro templates, precompile using node for faster performance.
- rorykoehein 12y agoI use hn.premii.com all the time. One of the best mobile web apps I have used. Any chance of open sourcing it? Would love to see how you solved some of these problems in detail.
- mercer 12y ago
- closetnerd 12y agoThis article reminds me quite a bit about Vuejs. Its got an interface similar to Backbone but with the addition of two way data binding while also allowing you to define web components style tags, attributes.
- hippich 12y agoI yet to find "perfect" JS framework. I bet, it will never happen. Nevertheless, I have a favor to ask any framework developer out there - please, make it disassemblable and usable piece by piece outside of framework. OP was right - sometimes i find some aspect of framework nice, but more often than not it is monolith part of the whole framework, which as a whole I dislike. ps: current combination it seems to fit my mind workflow is Backbone (models + collections) + Ractive.js (Views) + Machina.js (for routing and defining "controllers"/states.) Although I am looking to use something else besides Machina.js in next project, as I want to have hierarchy now. And since it is all loosely coupled, I can replace parts.
- jbeja 12y agoThe perfect JS framework won't exist until 2079.
- deleted 12y ago[deleted]
- ef4 12y ago> "Abstraction is dangerous" The fact that Javascript people keep saying this with a straight face is getting really absurd. You do realize Javascript is also just an abstraction, right? And that the browsers that run it also abstractions, and the operating systems, and the kernels, and even the hardware itself has multiple layers of abstraction? "Abstraction is dangerous" is just fundamentally wrong. Abstraction is the only way we get anything done. What you really mean to say is that bad abstractions are bad. But stated so clearly, it becomes obvious that it's a tautology. Well-designed abstractions that leak as little as possible are essential to everything we do. This stuff matters, because instead of having stupid arguments over "how much" abstraction we want (which really boils down to 99 layers vs 100 layers) we should be debating exactly what abstractions we want.
- juliangregorian 12y ago"Black boxes are dangerous" is maybe a more precise way of expressing the concept. I don't think the author literally believes you must be writing machine code.
- ef4 12y agoIf black boxes are dangerous then you really should be writing machine code. Which is absurd of course, and demonstrates that black boxes are a very good thing. Javascript itself is a black box. It would totally suck if you had to know how it's implemented inside to use it.
- kristopolous 12y agoOk let me try. Bad abstractions are bad. Additional complexity without additional functionality, increased dependencies without increasing stability, poor documentation and buggy implementations; strongly coupled things which have no business being coupled and overt assumptions on what kind of application you are writing and how you ought to structure it. They have fundamentals which don't interact with anything else - events that won't be caught, arrays that use their own iterator, etc. They decide to suppress language features like console logging and replace it using different names. You never learn this by reading the outdated documentation but by startling discoveries 45 minutes into what ought to have been a 15 second bug. And let's not get started on how utterly useless the call stack or object inspector becomes. They presume there are fewer coherent approaches to programming in a language then there actually are so they shoehorn you into writing things in one specific poorly documented, buggy, highly complex, inappropriate, monolithic, and fragile way. One of the main arguments for the abstraction approach is that they assist average programmers like a golfing handicap. But the reality is that the quality of the programmers work remains the same - but now with the abuse and misuse of the language AND a convoluted abstraction. You are far worse off. The historical problem is that these things despite all of these clear flaws become immensely popular - each one for about 6 months. And then your business critical application gets locked in. Locked in to the hottest framework from 5 years ago. Awesome btw, I tweet about my hatred of this specific topic here: https://twitter.com/frameworkhater https://twitter.com/frameworkhater ... I think a proper manifesto may be in order.
- itsbits 12y agoI don't agree with DOM event handling: setting events at every node comes with a cost. And I think you forgot to mention the performance issues with that approach and so now a days almost all frameworks prefer to event delegation. I think author except in 1,2 points didn't bother to take side with performance aspects.
- mperret 12y agoI like the structure of google closure, thoughts?
- jcoffland 12y agoVue.js meets most if not all the criteria outlined in this article. I've been have great luck with vue.js after a nightmare of fighting with writing a big SPA in Angular.
- iEchoic 12y agoThe Knockout example in this article is a bit strange - Knockout is not a framework (it is explicit about this) - but besides that, Knockout components actually do allow the "framework" to decide when things are instantiated.
- RehnoLindeque 12y ago> We all like simple tools. Complexity kills. It makes our work difficult and gives us much steeper learning curve. Programmers need to know how things work. Otherwise, they feel insecure. If we work with a complex system, then we have a big gap between “I am using it” and “I know how it works”. One answer to this problem of opaqueness in abstractions is having a well defined denotational semantics. This makes it clear that something can work in one way & only one way (without the need to dive into library internals). I feel that Elm is doing a pretty good job of tackling this for GUIs and signals.
- mathgeek 12y agoI was slightly disappointed that this didn't point to a 404.
- tel 12y agoThe whole "abstraction is dangerous" spiel is so wrong (imo) that I don't even know how to respond to anything that follows. The primary complaint appears to be that abstraction eliminates your ability to operationally trace the meaning of a program. This is true, but sacrificing operational denotations only hurts if you replace it with nothing else—and abstractions of general purpose languages are almost always more interpretable than the operational denotation of the base language itself! Of course, there are always places for poor abstractions. I am not talking about these. Abstractions which are intentionally opaque, have confusing action-at-a-distance, etc---you're bringing down the name of abstraction in general. "Leaky" is insufficiently demeaning. A good abstraction will have its own semantics. These can be equational, denotational, operational, what-have-you but, essentially, these semantics must be easier/simpler/more relevant than the semantics of the base language they're embedded in. Otherwise why abstract? So what does React give you? It gives you, more or less, a value-based compositional semantics. Components have some "living" nature (an operational semantics w.r.t. to state) but they're mostly defined by their static nature. Because you can build whole applications thinking only about the static, compositional nature of components you can take massive advantage of this abstraction. Ultimately, you do not want operational semantics for React. This is what gives us React Native, background rendering, and probably what will lead to sensible animations (in time). To define operational semantics, especially ones which have to look like or (worse) be identical to those of Javascript, would destroy almost all possibility of extension. At the cost of making things more complex and harder to reason about. All so that you can just stick to "obvious" Javascript base operations.
- fiatjaf 12y agoI don't think people use frameworks and abstractions because they have a smoothier learning curve, or because they are simpler, but because of DRY. After repeating the same pattern twice, the programmer turns it into a module and abstracts it. After having a lot of modules, the programmer packages them all in a framework. This is good for the author of those modules and the framework, because he understand them, but not always for the outsider who just looks at the complete framework and don't know what's inside.