Hacker News new | past | comments | ask | show | jobs | submit login
Stimulus: A modest JavaScript framework for the HTML you already have (stimulusjs.org)
163 points by milesf on Feb 23, 2018 | hide | past | web | favorite | 62 comments

I don't mean to knock the effort they've put in here, but this looks like all of the hand-rolled "frameworks" I saw my friends in the agency / consulting space made when they said angular 1 was "too heavy"... right down to the 'data-controller' attribute binding that everyone seemed to independently come up with.

Is there anything actually novel here? These types of things always seemed to run into composition issues (controllers inside of controllers) in terms of communication and what not. The net result was invariably far less appealing than, say, angular 1 or vue or non-SPA React.

Isn't the fact that you've seen a bunch of people already hand-roll this a good indication that there's a need for something like this, so no-one else needs to hand-roll it anymore?

It doesn't need to be novel right? It just needs to be helpful.

I tried to address that gently in my second paragraph. Every one of those were abandoned. The most complete one's developer said "what the hell was I doing?" onve he finally gave angular 1 a shot.

Plenty of people have hand rolled crypto too. "Lots of people do it" doesn't always point to an actual gap in the available tools.

Honestly I don't know why I'd want Stimulus over regular old web components if I wasn't going to use a whole library like React. It doesn't look like it adds much beyond what web components already give you.

data- comes out of HTML5 but jQuery was one of the first libraries to touch it.

It’s likely a significant fraction of people who jumped to the same solutions had some prior exposure to jquery.

With 30KB in size, this framework might be something I can integrate into my websites to get a nice look-and-feel while preserving usability when script blockers are active.

Personally, when I work on projects I tend to develop a pure HTML+CSS solution first and then bolt on JS if needed, so this kind of stuff might make me more comfortable with writing proper webapps since it's still just basically "bolt JS on HTML".

30KB? That's a lot, this is not minified and Gzip'ed is it?

Well, I just opened the script in firefox and checked the network tab in the dev console. It's 26KB gzip and 31KB after decompression.

Which, IMO isn't too bad, I keep my pages under 100KB. If I throw out a picture for an older project, I can easily get back those 30KB to stay under 100KB.

stimulus.umd.js is ~5.3KB gzip'd

>It's 26KB gzip and 31KB after decompression.

Yeah so no. There is no way gzip could only compress 16% of utf8 data.

As another comment mentions, there is a gzip'd variant available that comes under 6 KB.

Previous discussion: https://news.ycombinator.com/item?id=16052105

I've been using Stimulus + Turoblinks for my current side project and I love it. Nice and simple way to add a bit of interactivity to existing HTML on your page.

*Turbolinks, copy/pasted that for Google and didn't find anything relevant.

Edit: thanks, I found it, I was just pointing out to the typo so other people don't get confused.

Turbolinks is a feature in Rails. See for example https://github.com/turbolinks/turbolinks

Is there anyway to use turbolinks with a java backend? Or is it only specific to rails?

You can. Here's a blog post from somebody who uses it with an Elixir backend.


Turbolinks also works really well for static sites because all you have to do is drop in the Javascript and use it.

Allow me plug something. If you just want to "AJAXify" a few links and forms you could try the splice-into behavior from this repo:


It has no server-side dependencies and should be easy enough to use. But it doesn't use push history, which limits its usefulness for more extensive use cases.

I don't think Turbolinks is a good idea from a usability standpoint. Too many UIs have a similar bar at the top, and they mean different things: a browser's loading bar, a website's loading bar, a website's read-progress, etc. I think it increases the user's cognitive load (at least for this user) to figure out which kind of bar it is and why the top of the page is animating.

Turbolinks also makes websites appear extremely slow when on slow connections. It's much more frustrating to sit there with a loading bar hovering at 20-30% than to see a spinner.

As a VanilaJS advocate, I love it.

The manual even describes how to use just a plain <script> inclusion, instead of the build tool of the day.

But...tons of the nontrivial JavaScript projects I use describes a plain <script> inclusion. So I don't quite understand the plaudit here.

Doing so is not a great idea, because build tools solve real and extant problems, but they're very common.

A lot of tools solve real and extant problems, but that doesn't mean they should always be used.

Pity that the end result is always having bower, webpack, npm, yarn, gulp, yeoman installed.

Really painful when JavaScript is only used on the browser and the frontend files need to be integrated into the backend infrastructure written in a more sane language.

Why would a project have both npm and yarn, or bower, webpack and gulp?

Easy, each library is its own little world of dependencies, with the author favoring a different build tool, so simple npm install or npm serve might require all of them to satisfy all the dependencies build scripts.

I think you're confusing something. You don't "build" dependencies, you consume them as pre-built modules.

As a package author you use whatever you want (rollup, webpack, gulp, grunt, ...), but you will most likely publish to npm, because bower is dead.

As a consumer you use npm or yarn, it doesn't matter, and a tool that handles modules, probably webpack. Even if you'd use something else (rollup & parcel come to mind), it doesn't matter, they will all treat your dependency the same.

EDIT: Yeah i just saw you're referring to Polymer. I take it back, everything you said applies. But then again, people probably want to suffer when they use it. Though very few actually do use it. I just don't think it's a good example to make to describe web dev in general. Rather Google was the only one that missed the train it seems, they worked in the opposite direction.

Is that a real world scenario or something you can imagine but haven't actually done?

If you want a real world scenario, here is one

Polymer starter kit


- npm

- bower

- polymer-cli

Doing a polymer test requires downloading and installing Web Component Tester, which then requires:

- npm

- grunt

- gulp

- bower


Polymer is indeed ridiculous. But there's a reason it's not used that often.

My relatively standard project (using React) needs just Yarn and Webpack. It's got quite some dependencies, but I've never run into those being insufficient.

This has a lot of similarities to intercooler.js http://intercoolerjs.org/ which I really enjoy when I don't need a full SPA type experience.

Can anyone with experience of Stimulus suggest why I'd pick it over intercooler?

I’m not very informed about intercooler, but from the examples it seems to focus on AJAX requests. Stimulus is more about DOM manipulation, things you would’ve used jQuery for (except $.ajax and related). Toggle classes to show/hide things, move things around (mostly also just by toggling classes these days), create/duplicate elements, stuff like that. Stimulus also does some AJAX, but I can easily imagine these two work together in one page for different elements.

If you already use the rails ecosystem and the mental models associated with it, this is a library which will likely feel intuitive to you and fit neatly with the rest.

The ability to think effortlessly about code has value.

I like it a lot, but I'm always afraid that I'll end up running into limitations of the framework if whatever I'm doing happens to grow in scope in a way I hadn't planned for. I tend to be bad at planning ahead for side projects, but who can blame me, they're side projects.

Anyway, just stopping by to say that Vue has struck a good balance for me. Peppering in {{template values}} in existing HTML works really well, and when things start to get more complex I can easily break my dom out into components.

Have it exactly the same way, and especially the vue components are nice to have. It seems like Stimulus would be a good fit for small applications, but as soon it becomes a medium size project it would be to complex to maintain.

From what I've read from DHH, Stimulus was extracted from real world usage in Basecamp which I think is safe to say a lot bigger than a small project.

They didn't just "invent" the library in hopes it would work for someone. It's what they run in production on one of the most long running SAAS apps on the internet.

I love Vue as well. The problem is that I haven’t found a good way to fit Vue in with an existing Rails app without it resorting to JavaScript hell. Stimulus looks interesting because it already fits in with Turbolinks.

When you say JS hell I'm assuming you mean because Rails wants to be your JS bundler? Why not just have rails output a div with an ID? And then use a separate bundler such as webpack to generate a JS bundle?

At the end of the day Vue-cli or create-react-app ultimately just generates static assets. Adding your statically built SPA into a Rails app should be no harder than adding jQuery. Rails should not need to know about webpack & vice versa. The key is to build components not a full fledged SPA. Pick either Rails or Vue router. If the former, Vue is just a component/view library, don't treat it like a framework.

Of course, Rails 5.1+ supports webpacker better too, which I believe is recommended/intended for use with stimulus+Rails too (to get the es6 in the example, for instance).

This is good at first look. Because it seems to be straightforward and carefully design. I like the aesthetic and choice of using data attributes being part of the HTML standard as directives to apply the framework.

One criticism I have relates to The syntax for denoting action methods. Did you agonize over the choice of syntax uses hash and implication? E.g.

All the same this careful choice shows the effort you put into the framework . I’m just not sure this particular choice is to my taste nor works with regard to being consistent with the rest of the syntactic choices you have made.

Interested to hear thoughts of others in a discussion about this.

I think the ”hello#greet” part is there to be consistent with Rails route mapping.

As a standalone syntax choice, it makes little sense. But for a RoR developer, it’s obvious.

Cool, thanks for that :)

> export default class extends Controller {

I know it is vanilla ES6, but at some point it starts looking more like Java than JavaScript. The boilerplate necessary to convey a simple instruction is directly proportional to the averaged speed of everything else (authorship, maintenance, execution, testing, frequency of reuse, and so forth).

Do you mind expanding on what you mean? When I look at the instructions here, they seem pretty concise.

`export` -> exports the thing

`default` -> if you require from this module, this is the default

`class` -> class definition

`extends` -> speaks for itself

`Controller` class it's extending.

You could maybe rework it so you don't export it on the same line:


class Foo extends Controller {}

export default Foo


The parallel I see here to Java is the object orientation - which is a fair criticism. There are probably ways to execute on this using other mechanisms other than inheritance. But then, sub-classing to me still feels better than assigning the prototype via direct assignment.

Java has no concept of default, but otherwise `public class Foo extends Controller {}` would be pretty similar. It's not that the keywords are overly verbose for the purpose they express, it's that they relate more to "code bureaucracy" than to direct functionality.

In a language with fewer developers/smaller projects/fewer interdependent modules, there would be no need for exporting (no privacy, everything public by default), there would be no special syntax for extending a class (after all, you could just write it yourself if you need it), there might not even be any classes at all (again, you could just implement them if necessary).

But as languages mature, code bases start to grow, and every project depends on a web of dozens of slightly incompatible packages, people begin to realize that they need some mechanism to enforce order and to standardize on a single, officially blessed implementation of all those things you could just do yourself (and everyone did, with no regard for compatibility).

Then, when the language feels bogged down with the ceremony necessary for programming "at scale", someone decides to just throw all that baggage over board and develops a fresh scripting language, where the cycle begins anew.

I've never written any java code, but I really love the module systems inspired by it. I've been using this kind of packaging in both javascript and golang, and it actually feels way simpler than in ruby where I'll always end up with `Namespace1::Namespace2::Namespace3::klass` to deal with the global scope of everything.

We wrote a pretty similar (like similar enough its kinda creepy) library[1] a while back and it's really helped speed up our front end dev. I LOVE having params set in data attributes. Makes re-usable modules, like a modal[2] or autocomplete [3], way easier to implement.

[1] https://github.com/firstandthird/domodule [2] https://github.com/firstandthird/simple-domodal [3] https://github.com/firstandthird/complete

I did two other frameworks that are super similar, hooked up with dynamic loading of the code with webpack, and the older one RequireJS.

It's a super awesome pattern, that makes things super simple and it's super lightweight as well.

Unfortunately they get crazy bloated when we transpile them down for older ie. I believe we’re going to be using the new Babel stuff to hopefully easy that a bit. Ie 10 is still a sore spot though :/

We try to transtile as little as possible. And we do detect IE so that we can serve special bundles with special polyfills for that browser.

It's not perfect, but it's better for the newer browsers - they get something fact and neat, IE users get a slower one, but they would never get a really nice experience.

First of all this isnt just another JS framework, The Framework is designed to work better with Rails, it is crafty in terms of how the DSL is designed. DHH is definitely the master of Designing DSL's, look at Rails and Activerecord. This too is excellent DSL design. So no its not for JS People, JS has react and what not. This is mostly geared towards Rails people.

What's the advantage or disadvantage of using this when compared to something that works with Web Components like Polymer or stencil?

I agree with you that this is a worthwhile comparison to make, but would also point out that you could compare Web Components to any JS framework. When Web Components reach maturity (i.e. when support is baked into browsers and you don't have to fall back on using libraries like Polymer), they'll hopefully signal the end of JS frameworks as we know them, as it'll be easy to mix and match components from multiple sources. Until that time comes, I welcome JS frameworks like Stimulus that can (supposedly) be easily retrofitted onto existing websites, even if I'd prefer to see more activity around Web Components.

Support is now baked into most browsers for Web components! Also Polymer Lit-HTML and HyperHTML leverage JS Template Literals to natively update the DOM as fast or faster than virtual DOM using much less resource.

If you feel this is a lazy request please let me know, but could you point me to the source code for using native JS string templates to do Dom updating that achieve similar things to Virtual DOM?

https://github.com/Polymer/lit-html There are some unofficial (pre 1.0) benchmarks flowing around and it is VERY fast. Same goes for hyperHTML.

Works great, using it in my new notes app: https://github.com/notein/notein

I doubt it's any better than vuejs or preact.

Feels like backbone without the baggage.

one more frontend library !

Yet another js lib.. no thanks. There are plenty enough alternatives

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