
Hyperapp – A tiny framework for building web interfaces - Al0neStar
https://hyperapp.dev/
======
PufPufPuf
I have tried Hyperapp some time ago. It's usable for small apps, but the lack
of ecosystem makes it unfit for anything larger -- as is usual for all niché
JS frameworks.

Funnily, the "ecosystem" page contains just Lorem Ipsum
([https://hyperapp.dev/ecosystem](https://hyperapp.dev/ecosystem)) and the
Awesome Hyperapp section for V2 is almost empty
([https://github.com/jorgebucaran/awesome-
hyperapp](https://github.com/jorgebucaran/awesome-hyperapp))

~~~
foobarbecue
Is niché a portmanteau of niche and cliché?

~~~
bigblind
No, it's niche with a French accent

~~~
sqrt17
Fun fact: niche is a French word that doesn't have an accent. So niché is the
heavy metal ümlaut version.

------
mr0010110fixit
So I have extensively used hyperapp (1 and 2) for hybrid mobile applications
that run the cab of big rigs. We actually won best in show this year at
Freight Waves for our two apps.

These are medium/larger apps, with lots of functionality, need to hook into
native device features (done with ionic capacitor, and custom plugins), and
need to be fast, robust, and flexible. Hyperapp has allowed all of those
things.

Hyperapp can and will work, with larger applications, but hyperapp does not
have super strict "guide rails" like other more popular frameworks do, so its
up to you to design, and implement a clean code base. It ships with minimum
overhead, and you can either roll features you need, or see if someone in the
community has created them.

I have worked with angular (1,2,4,6) and react for quite a few projects, and I
actually work faster, and end up with a better end product using hyperapp. Its
an amazing little framework. Sure, not having stricter guide rails you can
write very poor apps in hyperapp, it will let you do stuff poorly, but if you
play to its strengths, and get comfortable with it, it really shines.

~~~
keb_
Hey there, really happy to hear of the success you've had with Hyperapp. I've
played with Hyperapp v1 in the past for small toy projects, and it was
relatively easy to become productive with. I'm wondering if you have any open
toy projects or boilerplate you could share for v2, as I'm looking to jump
back on it when I get the chance, and would love to see what a scalable
project skeleton looks like.

~~~
mr0010110fixit
I do not have anything that is open as of now (but about to start a new
project soon)

I would check out [https://medium.com/hyperapp/a-walk-through-
hyperapp-2-b1f642...](https://medium.com/hyperapp/a-walk-through-
hyperapp-2-b1f642fca172)

to get your toes wet though, good resource, also feel fee to join the hyperapp
slack [https://hyperappjs.herokuapp.com/](https://hyperappjs.herokuapp.com/)
nice community and super helpful.

------
mrozbarry
Bit of a Hyperapp fanboy here, so bare with me.

First, I think Hyperapp can make both small and big applications, opposed to
u/PufPufPuf's opinion. A lot of people have this opinion because they are more
familiar with v1's wired-in actions, which can become quite unruly. In the
latest version, actions are decoupled, and can be organized/extracted however
you see fit.

I've made a handful of applications in both v1 and the current released
Hyperapp, and they work very well. If you want to see the latest Hyperapp in
action, you can check these out:

\- A timer for mob programming:
[https://github.com/mrozbarry/mobtime](https://github.com/mrozbarry/mobtime)

\- A canvas game, using Hyperapp for dom/state:
[https://github.com/mrozbarry/smash](https://github.com/mrozbarry/smash)

\- A router for Hyperapp: [https://github.com/mrozbarry/hyperapp-
router](https://github.com/mrozbarry/hyperapp-router)

I have a handful of older youtube videos regarding v1, you can check them out
here:

\- Intro to Hyperapp (v1):
[https://youtu.be/uWIyjI8nkz0](https://youtu.be/uWIyjI8nkz0)

\- Hyperapp (v1) forms and localstorage:
[https://youtu.be/qpt6aaMxm1E](https://youtu.be/qpt6aaMxm1E)

\- Unit testing hyperapps (v1): [https://youtu.be/5wvPUj--
HaA](https://youtu.be/5wvPUj--HaA)

Note, they are outdated, but there isn't much on youtube about Hyperapp in
general.

One thing to keep in mind is the naming. A lot of people talk about "Hyperapp"
as the first version, and "v2" as the current version, but this is wrong. It's
more like "v1" (legacy) and "Hyperapp" (current). It gets confusing, because
not everyone is on the same page with that, but this the the naming Jorge
(primary author/creator of Hyperapp) has mentioned several times.

~~~
franciscop
> "A lot of people have this opinion because they are more familiar with v1's
> wired-in actions, which can become quite unruly."

u/PufPufPuf only mentions the lack of ecosystem, nothing about the wired-in
actions/etc, so it's odd that you defend v1 vs v2 instead of the lack of
ecosystem here. This should probably have been a reply to that thread as well
because otherwise it's two very unrelated comments in the list.

~~~
mrozbarry
Yeah, I should have split things into a reply and a separate thread for the
other stuff. That said, I didn't have any comment on the ecosystem - there's
definitely a lack of userland things for Hyperapp, and that's for a number of
reasons, the biggest being the latest is still in a bit of a transition period
from v1, and as a community we didn't think someone would be posting about
Hyperapp and make it to the top of hacker news. That really put us on the spot
to try and get on here and explain the state of Hyperapp since we're probably
more in a release candidate/late-beta situation rather than a full blown
release.

------
Shish2k
Been using this for a while and loving it - it feels like functional
programming for GUIs (“describe what you want the end result to look like, and
the framework makes it happen” as opposed to “describe what steps to
execute”).

I’m pretty sure a lot of frameworks have similar mindsets, but Hyperapp is the
one that I found works with the fewest headaches :P (as opposed to eg React,
where I spent hours simply trying to untangle the knot of thousands of
dependencies before I could get step 1 of the quickstart tutorial to
compile...)

As an example of how trivial problems require trivial code:

[https://github.com/shish/divetools2/blob/master/src/screens/...](https://github.com/shish/divetools2/blob/master/src/screens/mod.tsx)

[https://scuba.shish.io/#screen=MaxOperatingDepth](https://scuba.shish.io/#screen=MaxOperatingDepth)

------
ptu
I'm a big re-frame fan from the Clojurescript world so this all looks rather
familiar. For me it's a great framework and worth learning Clojurescript for.

Seeing the h() function makes me realise how much I miss Hiccup syntax for
HTML and your component tree, especially with editor support for parens it's a
joy. But it looks nicer than JSX.

I'm going to give Hyperapp a try, I like the small size aspect especially, and
familiarity of the overall architecture, my fear is that if you're going off-
piste enough to avoid the React/Angular well trodden track on an app, you
might as well go the whole way and use Re-frame which is very pragmatic, with
JS interop it's possible to do pretty much anything you want. And whilst the
type system and compiler of Elm is nice, the slightly more 'infamous' parts of
restrictions to JS extensions make it more limited in the real world.

------
beders
Someone got inspired by re-frame, I see :) I like the approach. Wondering if
there's a way to get ever closer to hiccup (without having to resort to JSX)

Also, letting the framework decide if a function inside the markup should be
called or not gives opportunity for more optimizations that go beyond VDOM
diffing. That would require an even more declarative approach.

i.e. [h1, {}, [MyComponent, {}]]

vs.

h("h1", {}, MyComponent({}))

If the framework figures out that MyComponent wasn't changed, it can re-use
the VDOM nodes.

~~~
jorgebucaran
Yep, there's a feature called Lazy (will be renamed to memo for the official
release) that allows you to do just that! :)

------
queuep
Haven't been using react because of the JSX, but is this really where we are
heading? [https://hyperapp.dev/tutorial#rendering-to-the-
dom](https://hyperapp.dev/tutorial#rendering-to-the-dom)

Looks like som obfuscated JS-code..

~~~
raziel2p
Mithril was doing this exact thing before React became big - it's what we're
moving away from (with JSX), not where we're heading.

~~~
pjmlp
Going back to PHP and ASP you mean.

~~~
marcosdumay
Text templates are the technology for web development. They are so much better
than anything else that there's no comparison.

There are some bad templates implementation, and some good ones. The original
PHP and ASP are bad. But that doesn't mean templates are bad.

~~~
pjmlp
Text templates are a good idea, placing them into the middle of JavaScript
code, not really.

~~~
enobrev
I absolutely disagree, but I also feel it's unfortunate that HTML, CSS, and
SQL aren't first-class citizens in most languages. It's strange to treat
things backed by entire standards bodies and with fully developed ASTs as
plain-text.

It seems unnecessarily limiting, and I'm not sure why; For the sake of
history? "Division of Concerns"? How is it that using libraries meant for
string manipulation upon a standardized format not a concern in and of itself?

The reason JSX, Mithril, PHP's template tags, ASP, Mustache, Twig, etc, exist
is because we want to generate HTML - a language that has been standardized
for decades - so why are we still playing around with string manipulation
tools?

~~~
marcosdumay
It's an evolutionary constraint. Text templates are initially much more useful
than HTML and CSS ones, so people adopt the first, despite a bigger potential
usefulness of the later.

The tendency for SQL is even weirder, it's for replacing it with languages
that are much less useful for querying data.

------
dang
If curious see also

2018
[https://news.ycombinator.com/item?id=17126670](https://news.ycombinator.com/item?id=17126670)

2017
[https://news.ycombinator.com/item?id=15467819](https://news.ycombinator.com/item?id=15467819)

2017
[https://news.ycombinator.com/item?id=15264053](https://news.ycombinator.com/item?id=15264053)

2017
[https://news.ycombinator.com/item?id=15178535](https://news.ycombinator.com/item?id=15178535)

2017
[https://news.ycombinator.com/item?id=14629414](https://news.ycombinator.com/item?id=14629414)

------
bshimmin
In the tutorial it says: "In this tutorial we'll stick with `h` to keep it
simple and close to the metal." I'm pretty sure they put that in there just to
aggravate the HN crowd.

~~~
jorgebucaran
There's a a JSX-like ttl for Hyperapp too, check it out:

[https://github.com/zaceno/hyperlit](https://github.com/zaceno/hyperlit)

------
davydog187
Just use [https://preactjs.com/](https://preactjs.com/) and call it a day

~~~
ggregoire
What are the caveats? Why doesn't everybody use preact instead of react?

~~~
davydog187
There’s not many. I used it for several years on theoutline.com and it was
great

------
czechdeveloper
I love it, but I actually stuck with version 1, which was way more intuitive
for me.

Just a side note, I'm not fulltime front-end, so keeping up with modern
frameworks is out of my capacity.

It's great for smart components to my standard multi-paged systems, but I used
it even for small PWA applications.

~~~
hellcow
I resisted the change to v2 for a long time. In the end I found that v2's
state management is much better, so it might be worth a look for that alone.

~~~
czechdeveloper
I read about it but it just did not click as V1 did. Also I will not rewrite
old code just for sake of change and I want all system to be on same framework
if possible. I may actually do my own fork where only difference will be
passing root state and root actions in addition to partial ones, which will
fix great amount of issues I have.

~~~
hellcow
Agreed.

The lack of lifecycle events in v2 complicates things a great deal for
seemingly no reason. Subscriptions and Events are similar enough that they
could have become a single thing, instead of having two highly similar but
not-quite-the-same things to grok. The tuple syntax it uses is very strange
coming from v1.

I wish I could call it a strict upgrade instead of saying "some things are
worse, but other things are better."

~~~
jorgebucaran
It's my fault for not fully understanding the functional universe I was
getting into when I first started working on Hyperapp. The latest Hyperapp is
more strict, but it's all in good measure. Lifecycle events are impure, that's
why they're no-good.

I can tell you that Hyperapp is not for everyone. If you want to write pure,
immutable, functional JavaScript and think hard about client side app
architecture (unidirectional state management, controlled side effects,
toggleable subscriptions), then you'll love it. I also suggest looking at Elm
while you're at it.

If you are looking for a more accommodating, meet-in-the-middle kind of
approach where you can mix programming styles, you might be better served by,
say, P/React.

~~~
_old_dude_
If we talk about functional API, did you consider providing a push method,
like with a Promise, to express the updating of an effect or a subscription ?

(the function 'update' in the code below)

    
    
      app({
        init: 0,
        view: state =>
          h("div", {}, [
            h("h1", {}, state),
            h("button", { onclick: (state, event, update) => {
              window.setTimeout(() => update(state => state - 1), 1000);
            } }, "subtract"),
            h("button", { onclick: state => state + 1 }, "add")
          ]),
        node: document.getElementById("app")
      })

~~~
jorgebucaran
We built it into the framework, if you happen to be familiar with Elm, this
should make sense right away, but here's how you'd write something like that
using Hyperapp:

    
    
        import { h, app } from "hyperapp"
        import { delay } from "@hyperapp/time"
    
        const Decrement = (state) => state - 1
    
        app({
          init: 0,
          view: (state) =>
            h("div", {}, [
              h("h1", {}, state),
              h("button", {
                  onclick: (state/*, event*/) => [state, delay(100, Decrement)],
                }, "subtract"
              ),
              h("button", { onclick: (state) => state + 1 }, "add"),
            ]),
          node: document.getElementById("app"),
        })
    
    

See how you never actually called setTimeout as that would be a side effect.

Instead, we have "controlled effects" in Hyperapp. This `delay` function
doesn't even call setTimeout itself, but return an object that tells Hyperapp
how. Just like how `h("button")` or `<button>` with JSX doesn't actually
create a button, but an object representation of it.

Finally this part: [state, delay(100, Decrement)], only placed here for
convenience (as you'll usually want that in its own action) is how you tell
Hyperapp to do the effect when the button is clicked. This is the same (model
Cmd) continuation pattern used in Elm.

~~~
_old_dude_
I'm familiar with Elm but i think the model of Hyperapp is better than the
[state command] pattern. This is how i see Hyperapp, the event part of
Hyperapp is not about commands, it's about transition functions, functions
that takes a before state and returns an after state. Hyperapp doesn't let the
user to control the state by itself.

But there is worst, the problem with the pattern [state command] is that it
doesn't work well with async method, because at the time the command is
called, the state which is passed alongside the command and the state
maintained by Hyperapp may be different.

With your example, the issue is that Decrement may be called on a previous
state and not on the actual state.

The idea of the updater is to provide the function that takes the transition
function as parameter, so delay will be written that way

    
    
      function delay(updater, timeout, fun) {
        window.setTimeout(() => updater(fun), timeout);
      }
    

If you want to decrement the state after a delay using the state at that time

    
    
      h("button", {
        onclick: (state, _, updater) => delay(updater, 100, Decrement),
        }, "subtract")
    

(from the Hyperapp perspective, the event listener return undefined so you
don't have to update the state at the time the event listener is called)

and if you want to decrement the state using the state at the time the user
click

    
    
      h("button", {
        onclick: (state, _, updater) => delay(updater, 100, _ => Decrement(state)),
        }, "subtract")
    

The other benefit is that because delay() takes an updater as first argument,
it's clear that the function delay does a side effect. Conceptually, the idea
is that instead of trying to hide the side effect, you make it clear to the
developer (more like Haskell does).

~~~
jorgebucaran
My example actually has no issues, but [here is an example][1] so you can
confirm that. I included the implementation of `delay` there as well so you
can also see what happens behind the scenes.

\---

So, in Hyperapp there are no async/await functions. Or Promises. Can't use
functions that create side effects. Can't use setTimeout, setInterval, new
Promise, fetch, add/removeEventListener, etc.

delay(100, Action) looks familiar to setTimeout, but it's just a function that
returns an object that tells Hyperapp what to do. It doesn't do anything by
itself. You can write your own delay function too if you want as long as you
give Hyperapp what it wants.

The state becoming stale is never an issue in Hyperapp, because you get a
fresh copy of it inside actions, which is the only place where you can
"update" the state.

[1]: [https://codesandbox.io/s/hyperapp-minimal-counter-with-
effec...](https://codesandbox.io/s/hyperapp-minimal-counter-with-effect-for-
hn-old-dude-evvm4?file=/src/index.js)

~~~
_old_dude_
Thanks for taking the time to explain me how it works. So you're right that
you can not use a previous state.

And if i want to get the dispatcher directly, i can write a helper function

    
    
      function effect(fun) {
        return state => [state, [dispatcher => fun(dispatcher)]]
      }
    

and use it to access to the dispatcher/updater

    
    
      h(
        "button",
        { onclick: effect(updater => setTimeout(() => updater(Decrement), 1000)) },
        "subtract"
      )
    

Thanks a lot !

~~~
jorgebucaran
Basically, yes!

In practice, we don't advocate users to reach out for dispatch, as Hyperapp
intends to provide all the fx/subscriptions building blocks you need to create
the right abstractions and stay within the safe, declarative side of things.

The reality is, though, that crafting these building blocks takes time and
thought, so we don't have them all yet. But people in the community have
created fx/sub libraries that are already available, see e.g. this one:
[https://github.com/okwolf/hyperapp-fx](https://github.com/okwolf/hyperapp-fx)
that

Cheers!

------
bharani_m
I've used this for building the browser extensions for my app [1].

It is simple, easy to understand and easy to reason with. However, I would
recommend this only for small apps. As soon as your app's features/complexity
increases, you end up writing a lot of biolerplate code that libraries like
Vue or Preact already handle you for.

[1] [https://www.emailthis.me](https://www.emailthis.me)

~~~
shash7
Your open source browser extension framework was really helpful to me a few
years ago!

~~~
bharani_m
Glad you found it useful.

I had sort of neglected it for a while, but during the course of the lockdown,
I have started working on a major rewrite - replacing Gulp with Webpack,
adding support for Edge, etc. Will release it soon :)

------
pgt
To me every JavaScript framework feels to me like it wants to reason about
components as data, ala Hiccup: [https://reagent-
project.github.io/](https://reagent-project.github.io/)

~~~
jorgebucaran
Reagent is amazing, thank you for sharing it.

------
wackget
Does modern web development just completely abandon the idea of "separation of
concerns"? Looks like content is freely mixed with markup and logic and
results in a horrible, difficult-to-read mess of code.

~~~
Kiro
There has never been any separation of concern in web development. Just
because you put your scripts, HTML and CSS in different files doesn't mean
they are separated.

~~~
wackget
Isn't that the definition of separated? If you want to edit content or markup,
you open the HTML file. If you want to edit business logic, open PHP or JS.
And so on.

~~~
ng12
Yeah but then your JavaScript spews out unholy tendrils that mutate the DOM
and dynamically add/remove CSS classes and style attributes. Separating
HTML/CSS/JS made a lot of sense for web sites but separating by component
makes more sense for web applications.

------
Glaeqen
It seems that scrolling is somewhat broken. Scroll position under one route
affects position in others.

~~~
drcongo
That was enough to make me not consider using Hyperapp.

~~~
jorgebucaran
Yeah, the site is a WIP, but that should be fixed soon when V2 is officially
out.

------
manx
How is it 2x faster than react? Where does this claim come from?

~~~
DigitalSea
A lot of other frameworks/libraries are faster than React. I know React used
to be touted as the fastest option, but the reality is that it isn't.

------
ancarda
Just shows a blank page without JavaScript. Does Hyperapp have any way to
render out an HTML fallback if JS doesn't load?

~~~
jorgebucaran
That's an issue with the site that'll be fixed when Hyperapp is officially
released.

------
shroom
Dang, I registered hyperapp domain because I thought it was a good name and
wanted to build something cool there. Like all side projects it’s not about
the idea but the execution. I’ll put this in my bin together with slackday
(Should have registered slack:)

On topic: This looks interesting and I Will be giving it a try. Well done!

~~~
jorgebucaran
Do you happen to own hyper.app?

------
nailer
React was made in 2013 and is pretty old at this point. How does Hyperapp
compare to current tech like Svelte?

~~~
jorgebucaran
This deserves a much better answer, but I'll just say this for now. Svelte is
declarative/imperative (but mostly imperative) and also not based on
functional principles. React is definitely more on the declarative side. And
Hyperapp is essentially Elm in JavaScript, so it's as
declarative/functional/immutable as the definition allows for.

Maybe the person that said Svelte was more declarative was only familiar with
an older incarnation of Hyperapp that wasn't completely based on functional
principles, or maybe they're using a more loose but inaccurate definition of
declarative (kind of like how people often say "theory" when they actually
mean "hypothesis").

~~~
RivieraKid
What do you think the advantages and disadvantages are? I remember briefly
looking into Hyperapp and mostly liking it, but still wasn't sure which JS
framework is the best choice (the other one I liked was Vue).

Some time after that I learned about Svelte and very quickly concluded that
this would be my choice, everything just feels right about it. For the record,
I've only done a small project in Svelte.

~~~
jorgebucaran
That's fine. If you're already happy with Svelte, I encourage you to explore
more with it. Try building a couple of non-trivial projects and keep learning
about your craft. If you're also into computer science, I recommend you look
into functional programming if you haven't done so yet. Then look at Svelte
again. Try React too. Check out Elm.

I can tell you that Hyperapp is not for everyone. If you want to write pure,
immutable, functional JavaScript and think hard about client side app
architecture (unidirectional state management, controlled side effects,
toggleable subscriptions), then you'll love it.

If you are looking for a more accommodating, meet-in-the-middle kind of
approach where you can mix programming styles, and don't want to think much
about those things I mentioned above, then React, Vue, Svelte are all great
choices.

V2 will be released in a few months, so do circle back to Hyperapp then to see
how you like it again.

~~~
onetom
what else is missing other than docs? in hope you won't remove the current
state, just because you don't consider it released yet :)

~~~
jorgebucaran
Finish the site and docs, merge the minimizations branch (has memory
performance improvements, and brings it down to 1690 bytes gzipped / 1528
bytes brotlified total), add tests, then we can officially proclaim V2.

Definitely not planning to remove the current state or anything haha.

------
schwartzworld
When last I checked, Hyperapp was basically the elm architecture implemented
in JS, a gateway drug.

~~~
k__
I had the impression it was the other way around.

People starting with Elm, love the idea, but not the ecosystem, and come back
to JS in the end.

That's how Redux was created.

------
recursive
I wish people would stop demonstrating new languages or frameworks using fonts
with ligatures.

"Surely, you couldn't use an actual arrow here... right?"

I find myself having to copy and paste the text to find out for sure.

------
wooolfgang
Love the website aesthetic!

------
ehutch79
This page does not inspire confidence in the framework.

I don't need a non-ui piece of software to have the slickest site... but no
lorem ipsum please.

~~~
jorgebucaran
I put it there, so I apologize for it. We were in the middle of a rewrite
while working towards the official V2 release and weren't expecting to be on
HN right now haha. Thanks for chipping in!

~~~
ehutch79
Ouch. that's rough.

I've seen some incidents before where backend frameworks were posted before
they had things like authentication ready.

------
loustak
What are the difference with Mithril.js? Both seems to embrace the same
philosophy in almost the same way. Or am I missing something?

~~~
jorgebucaran
They're similar, but Hyperapp is purely functional and more comparable to Elm.

------
oweiler
I love hyperapp! It has very few concepts to learn, and the source code is
less than 500 lines. Sadly its ecosystem is non-existant.

------
RyanGoosling
Just another transient DOM API abstraction library

~~~
WealthVsSurvive
Almost like the DOM Web API isn't useful for its intended purpose anymore and
should be replaced or built upon to avoid all this abstraction churn. Why is
simplicity the enemy of the Web APIs? Why is everything useful left to user-
defined dependencies? Are the spec creators even checking to see what their
code looks like when people have to cobble it together to create something
useful? I suspect they are NOT.

~~~
jorgebucaran
Hyperapp only makes sense if you want to write immutable, purely functional
SPAs in JavaScript. There's no Web API or native abstraction for that. And if
your site was only content, then I'd say why even bother with JavaScript.

~~~
WealthVsSurvive
Okay, so there's no Web API or native abstraction for what? Immutability?
There is, but it's somewhat semantically obtuse to express natively with
Object freezing, not even to mention some other variably-efficient jiggery-
pokery with proxies or something (or maybe there's a new language feature for
this that I've forgotten about, so many after all, or was it a proposal?).
Purely functional single-page application: oof, such a mouth-full. Can mean so
many things too. So this entire new abstraction is for a front-loaded SPA?

Maybe the Web should be reinvented, slightly at least. Maybe it would be a
good thing if Web Assembly in conjunction with HTTP3 or something akin to it
ate the whole beast, ecmascript and all.

~~~
jorgebucaran
Just saying "purely functional SPAs" was lazy, but it's usually enough to
convey what makes Hyperapp different from other frameworks like React, etc.
Let me try harder.

There's no native API for representing apps as finite-state-machines (Moore
style) [1]. Admittedly, we could do a better job at explaining why you should
care.

Hyperapp actions (Elm messages) correspond directly to FSM "events". Hyperapp
effects (Elm commands) correspond directly to FSM "actions". The "single-
global-state" corresponds to the fact that an FSM is always in just one of a
number of "states".

Hyperapp is FSM architecture for JavaScript apps.

It is also bundled with a VDOM implementation optimized for immutability,
e.g., you must derive your UI from the state, can't produce uncontrolled side
effects, and can't use traditional DOM events, instead you think of every UI
interaction as a state transition.

One more cool thing about Hyperapp is subscriptions. An abstraction to
toggeable event streams: think bidirectional effects, e.g., global
mouse/keyboard events, time, animation frames, geolocation.

[1]:
[https://en.wikipedia.org/wiki/Moore_machine](https://en.wikipedia.org/wiki/Moore_machine)

~~~
RyanGoosling
> can't use traditional DOM events

Wtf are you doing man?

~~~
jorgebucaran
Can't use DOM events to create side effects. What we do is define UI
interactions as state transitions. Transitions allow you to say [nextState,
myEffect] to update the state and create a "controlled" effect (just an object
representation of a side effect, very much like how VDOM uses objects to
represent DOM nodes). Effects in Hyperapp are the same as Elm commands.

------
jhardy54
Blank page when JS is disabled. :/

------
joelbluminator
How does this compare to Stimulus?

~~~
jorgebucaran
Stimulus is not so much concerned with rendering HTML. Hyperapp is almost
exclusively focused on rendering HTML and client side application architecture
(state management, controlled side effects, subscriptions).

It's more comparable to Elm than React, Vue, Angular, Svelte, etc., since it's
based on functional principles and you can only write pure, immutable code.

------
aabbcc1241
Now it looks like Elm

~~~
jorgebucaran
Exactly! And the latest version (which is not officially out yet) is even
closer to Elm that the first version ever was.

------
Nijikokun
Looks like mithril

------
jczhang
so.. a lighter react?

~~~
jorgebucaran
Preact would be the lighter React. Hyperapp is more comparable to Elm.

