I wanted to do this back for my Electron Adventures series, but Imba 2 doesn't work well with Electron due to some bundler configuration issues.
History of JavaScript frameworks
So, here's some opinionated history of JavaScript frameworks. There's been 3 generations:
The first generation was the jQuery generation. Everything was either based on storing state directly in the DOM like jQuery or D3, or trying to use Model-View-Controller pattern, with view and controller being very often built on top of jQuery, and model often having some custom half-assed OO system as JavaScript never provided enough functionality out of the box. Some notable frameworks of that generations were Backbone and Angular 1. Notable languages were pre-ES6 JavaScript, and CoffeeScript.
I think it's fair to say that jQuery was and still is amazing at sprinkling a bit of extra functionality on top of a mostly-static site, with very little code, but neither DOM-state nor MVC approaches work very well for more complex sites. It's still alive and well in many niches, for example testing tools, scrappers etc. are basically all jQuery-style.
Second generation was the React generation. It dropped DOM-state and MVC concepts completely, and instead organized code in a tree of Components. Every component handling its rendering, behavior, and sometimes also styling, and communicating only with parent and children. This generation embraced ES6 JavaScript with extensions like JSX, and bundlers like Webpack. Strangely despite ES6 having a reasonable OO sytem, there's a lot of custom OO systems in this generation as well. React Hooks, Redux and so on, are all basically custom OO systems. Notable frameworks of that generation were (various iterations of) React and Vue.
And currently we're entering third generation, which so far looks like Svelte generation. It's still Component based, but unlike previous generation where reactivity was partial (dependencies need to be declared manually), runtime-managed, and required a lot of boilerplate; this generation's reactivity is more complete (dependencies are automatically inferred), compiled, and low-boilerplate. The main frameworks of this generation so far are Svelte and Imba, but since this is the generation we're currently entering, there could be a lot more.
This generation usually more fully embraces making each component handle its styling, something React generation was divided on, and jQuery generation never did.
Imba
Imba framework was created for Scrimba, a very futuristic interactive education website.
The biggest problem with Imba is that Imba 1 to Imba 2 transition is a total rewrite, Imba 2 has been in alpha for over two years, and Imba 1 is not getting updates, so there are some issues related to bundlers it uses and latest node version.
Imba is based on a custom variant of CoffeeScript, which is not a very popular choice now, and Imba 1's language, Imba 2's, and original CoffeeScript are not even that close to each other.
Creating a new App
Let's create a new Imba app with npx imba create counter
. It asks a bunch of questions, but you can just accept the default.
Let's take a look at initial file:
global css html
ff:sans
tag app
<self>
<header>
<svg[w:200px h:auto] src='./logo.svg'>
<p> "Edit {<code> "app/client.imba"} and save to reload"
<a href="https://imba.io"> "Learn Imba"
imba.mount <app>
The first and super annoying thing is that it uses tabs, set to 4 space width, instead of 2 spaces like every other web tech. Back in Imba 1 both worked, but now only tabs work. That's terrible for all kinds of reasons, one of them being how bad these look when pasted into blog posts (that's why I convert it all to 2 spaces for the blog). I hope they see the light and add support for standard 2 spaces at some point.
Anyway, there's crazy much going on here:
- it's CoffeeScript variant, so indentation is significant
-
tag app
defines componentapp
, which behind the scenes creates a web componentapp-tag
- Imda 2 is based on web components -
imba.mount <app>
mounts componentapp
to the DOM, as we didn't specify target, it does it directly inside the<body>
- Imba handles CSS too, global, element scoped, or inline
- Imba does a lot of Tailwind-style CSS shortcuts, like
ff:sans
expands tofont-family: var(--font-sans,system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
-
w:200px h:auto
expands to much less surprisingwidth: 200px; height: auto;
- HTML is builtin sort of like with JSX, but instead of explicitly closing tags it uses indentation
- inside HTML things are code by default, so you need to do
"Learn Imba"
not just plainLearn Imba
if you want to insert a string - string interpolation with
"{}"
, because obviously every language has different string interpolation syntax
As you can see, Imba 2 is a big language. It's not a limited framework that just does one thing well like jQuery or React or Tailwind, Imba tries to be complete solution for the frontend.
Counter App
OK, let's build a simple counter app.
global css body
min-height: 100vh
d: flex
justify-content: center
align-items: center
text-align: center
tag app
prop count = 0
<self>
<header>
<button @click=count++> "Click me"
<p> "Clicked {count} times"
imba.mount <app>
What's going on:
-
global css body
is just "how to center in CSS", I don't know all the shortcuts, so I used long ones except ford
-
prop count = 0
defines property and its initial value -
<button @click=count++> "Click me"
is a simple inline clicke handler - as with all third generation frameworks, we don't need to do any manual dependency tracking, so no
this.setState
or such
Coming next
So this is the basics of Imba 2. Over the next few episodes we'll try to build a few toy apps in Imba 2, and then we'll try some other techs that slipped through the cracks.
Top comments (2)
Where would Elm fall in this classification?
I never used Elm, but it looks like gen 1 MVC, just with a lot more types, and horrendous interop with JavaScript ecosystem. Just looking at how to parse JSON in Elm makes me cringe.
If someone really needs static types on the frontend, TypeScript (with React or Svelte) is the way to go. I don't particularly like it, but they did a decent job for the goals they had.