Show HN: Imba – I have spent 7 years creating a programming language for the web
My name is Sindre, and I am the CTO of Scrimba (YC S20). For the last 7 years, I have written all my web apps in a full-stack programming language called Imba. It compiles to JavaScript and its main goal is to make web developers more productive.
I just launched a major overhaul of Imba, so I wanted to share it here on HN, in case anyone are interested in learning more about it. It is very opinionated, so some of you might not like it, but I would love to hear anyones feedback regardless. Constructive criticism appreciated!
The backstory:
Imba initially started in 2012 as an effort to bring the elegance and conciseness of Ruby into the browser, and also because I felt that JavaScript and the DOM should be more tightly coupled together. Over the years, I have taken inspiration from React/JSX, and also Tailwind.
Since 2013, I have built several business-critical apps in Imba, so this is not a toy project or an academic exercise, it is extracted from a real project trying to solve real problems. Today, we are currently a small but passionate community of devs who use Imba all over the world.
The nitty-gritty details:
As mentioned, Imba compiles to JavaScript, and it works on both the frontend and backend. The quickest way to get a feeling of how it works is by checking out this video: https://www.youtube.com/watch?v=8XS5q9xhaMc
Alternatively, here is a list of the main benefits of the language:
* Clean syntax with built-in tags and inline styles
* Imba's Memoized DOM approach is *an order of magnitude* faster than Virtual DOMs (Vue, React). Learn more here: https://www.freecodecamp.org/news/the-virtual-dom-is-slow-me...
* Imba works with Node and the npm ecosystem, and integrates tightly with both JS and TypeScript
* Blazing-fast dev/build tools based on esbuild
Each of the benefits above are explained more thoroughly in our docs here, so please check it out if any of the above points spark your interest: https://imba.io
With this version I feel that I am very close to my vision for what Imba should be. In other words; it is finally ready for public consumption. I'd wholeheartedly advice you to look into it and give it a whirl if you are interested in web development :)
Hope you like it, and please share any feedback you might have in the comments!
PS! We're also hiring Imba developers at Scrimba - see https://jobs.scrimba.com/. We don't expect you to be a seasoned Imba developer, but we expect you to pick it up fast :)
354 comments
[ 5.2 ms ] story [ 288 ms ] threadDoes imba also have native app framework too?
Repo: https://github.com/imba/imba
Docs: https://imba.io/language/introduction
Video: https://www.youtube.com/watch?v=8XS5q9xhaMc
Article: https://dev.to/somebee/imba-a-javascript-alternative-for-inc...
Site: https://imba.io
Discord: https://discord.gg/mkcbkRw
Twitter: https://twitter.com/imbajs
I find it less of a new language and more of a JS preprocessor, removing lots of the cruft and integrating XML-tags and CSS in a very neat way.
What I miss:
1) I feel the web is shifting to more type checking. TS, Elm, Kotlin.js... I personally also prefer more typesafety, especially if the project grows in LOC/team size.
2) Compared to JSX, Imba does a much better job in integrating adjacent technologies. Though I much prefer these to be integrated in an eDSL fashion. For example how Elm does HTML templating (in Elm) or Kotlinx.html[1].
Just taste i guess. Good luck with yr project!
[1]: https://github.com/Kotlin/kotlinx.html
So the first thing I did here is look up the docs and see how variables are declared. Aaarghh.. "let" and "const" again :)
The more often a construct is used in a language, the shorter I like it to be.
It groups variable definitions mentally by having them all the same length if they are "var", "let" and "con".
It would often make the code look more uniform which is more beautiful in my eyes. Example:
https://github.com/facebook/react/blob/cae635054e17a6f107a39...
I would prefer the lines 226 and 227 to start with "con" and "let". It would make the code visually more appealing to me.
I’m sympathetic to wanting code to have good aesthetics. If I was writing those lines I probably would have daydreamed for 5 minutes thinking of new names for map and record so that the equal signs would line up.
"const" seems clearer to me. "con" seems very open to misinterpretation: could mean many things.
Are there any advantages to "con" over "const"?
I'm no particular JS fan, but 'const' is much clearer, it's a complete syllable, just like 'var' or 'func'. Yes 'fun' is used, but I think that's awkward for the same reason.
The 'const' nomenclature is an abomination before science and human progress. However, given the prior art, I don't think we can hold it against a new/emerging language.
Anders, help us! Do the right thing. You are the only one who can.
(Of course, 'const' could be grandfathered and still work forever. Right-minded people, please upvote this obviously-right person at least back to a neutral #000.)
If I had my druthers, I think I would choose "var" and "def" to declare mutable and immutable variables, respectively.
Edit: After thinking about it some more, I think I prefer "const" over "con", but "def" over both.Triple even! In French it's the equivalent of "cunt".
Hey BTW, is a JS "const" really constant, or can it (like in some other languages) be changed after all? Because if it can, then it isn't really const but more of a con...
It's constant for things like numbers, but if you declare an array const, the only const things is the reference, the array can still mutate. con might be a good name for that.
I have programmed in a couple languages where every single keyword was in Spanish: Logo and some flavours of Visual Basic.
Either everything is in English, or everything is in Spanish. There's no middle ground with mixed keywords.
'Var' and 'def' both sound good to me.
If js was made with types then the syntax `any x` (yeah lose the colon too, who gives a shit) is suficient to express that x is a variable, then `number x` could mean variable of type number, and `const number x` could mean constant of type number.
[constant variable name] = value
is not the right thing?
From a first look, I love the dimension types and the tags which compile down to native web components.
Hope good things for this.
Is there a clear separation between those two parts? Could someone take just the language without the framework and use it for something that's not web related?
I checked out https://github.com/imba/typescript-imba-plugin for a bit and I'm still quite lost. Love to learn more!
Also, what is the cross-file refactorings in the tooling? Thanks!
We essentially do the type-checking by compiling the files to js with jsdoc annotations, and for some features we also generate `.d.ts` files (see https://dev.to/somebee/global-type-augmentations-with-automa...). There is still a lot of work to be done on the integration. There are bugs and missing featyres, and the type-checking only happens in the tooling atm. The compiler could not care less about your types.
Since it is developed as a ts language plugin, references to imba files (like goto definition etc) works from ts/js files (you can include imba files in js/ts), and renaming methods / files works across all ts/js/imba files in your project.
I took a cursory look at the docs and it looks like async/await is pretty much directly analogous to how it works in JS, with the difference that you don't need to mark functions as async in order to use the await keyword. Does this mean that if you use await in any function then any other function calling it will have to be refactored to add an await keyword, just like you have to refactor any call sites in JS if you make a function async?
I remember seeing someone here on HN showcasing a language where they did the opposite, making it so that await is implicit, so calling fetch or anything async doesn't require an additional keyword, and functions don't need to be refactored just to sprinkle async/await everywhere. I'll see if I can find that language again, but it seems to me there may be some idea sharing between the two that could perhaps yield some amazing features...
I run into subtle bugs all the time due to missing awaits, it's incredibly frustrating.
[1]: https://hyperscript.org/posts/2021-04-06-aysnc-transparency-...
If you use TS, ESLint's `no-floating-promises` rule (or the equivalent in other linters) is _such_ a requirement
Probably a dumb idea but I would use it personally.
But you gather them by using:
`await Promise.allSettled([promise1, promise2, promise3])`
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
I worked with guys that started after async/await.
The new guys just think of everything like it's synchronous. They don't understand Promises. They never look at code and think "I can run this in parallel with Promise.all and a reducer". They just await each thing one at a time.
So, I'm not sure the async/await annotations are really helping us when devs just use them like decorations that just have to be there for it to work.
and its async transparency in particular:
https://hyperscript.org/docs/#async
hyperscript isn't a general, full-stack programming language though, it's focused on pure front end stuff, sort of a modern jQuery replacement.
Also -- wow those Nordics are super productive programmers/coders/developers/open-sorcerers (Sindre Aarsaether & Sindre Sorhus & Linus Torvalds & ...<please insert other names below to educate me>...) -- could it maybe have something to do with: The low GNI, the high HDI and the great weather for coding? (cold, blistery, bleak, focused, electrons-and-light universe is only outlet in a desolate landscape)? I have been to Oslo. The architecture is great.
PS - I use my own memoized DOM with minimal/granular updates in my own quirky framework (https://github.com/i5ik/vanillaview)
PPS - BTW memoized DOM is a great term of art. I perhaps shall be using it from now.
CONGRATULATIONS, SIR!
PPPS - Also what you are doing with Scrimba is so incredible. And GOOD. You are such a fuqing genius. Wow!
Bjarne Stroustrup, Anders Hejlsberg.
-- MVC and DCI, invented by:
Trygve Reenskaug - https://en.wikipedia.org/wiki/Trygve_Reenskaug
-- Simula language, invented by:
Ole-Johan Dahl
Kristen Nygaard
https://en.wikipedia.org/wiki/Simula
Simula: first OO-language, introduced objects, classes, inheritance and subclasses, virtual procedures, coroutines, and discrete event simulation, and inspired languages such as Smalltalk, Java and C++.
I had the impression "tightly coupled with TS" would mean type checking.
That's sad.
So, if you split by technology, you don't have the code belonging to one feature in one place.
I think what you were going for is the idea that, beyond a trivial application, the visual appearance stuff is always going to be tied to some app logic or business logic or state or whatever word we want to use.
And that's very true regardless of what framework or language we choose.
That situation most likely requires HTML (DOM) generation in the browser, which can only happen in JavaScript.
So, I reiterate, the HTML is generated by JS in these interactive modules.
You could generate the HTML on the server and then use jQuery to toggle elements… or just create full-JS components that take care of everything, giving some input data, instead of separating the HTML from the JS.
I guess if I were to rationalize my position, I'd say it's because I have a hard time finding related things when they're separate. If a button or "a" tag have a special click handler, I want to know when looking at it. If it just has classes, then I don't know if that are for style or if they're for behavior. I know there are some conventions out there where you prefix classes with "js-" etc, but if you just use "onclick" then it's obvious and you don't need a convention.
> I have a hard time finding related things when they're separate.
Store them in the same directory?
I agree on the events/business logic that they make sense to couple with the template code.
At best you will achieved a few smaller files. At worst you make working within the system a real pain.
For files where the logic, structure, and styling fits on a single page - yeah, splitting it into separate files doesn't make much sense.
> At worst you make working within the system a real pain.
That's what I don't understand - what pain? That it's better not to work with it using nano or notepad? It simply looks like a pain I would never experience, and I'm wondering if I'm right.
Exactly! By putting everything into one file, you give the reader the option of splitting their view if they want, or looking at the file all in one pane; with multiple files, you have to have each file open independently. Editors give pretty nice ways of navigating to specific functions/methods/points within a file these days, so traversing a large file is not really an issue IME.
Personally, I don't understand the fascination with splitting everything into super small files; given the large number of files I generally have open in my editor, I'd rather look at one file with 1k lines of code than 3 files with 100-500 each. With separate files, if I'm trying to debug something that touches three different components, I need to have 9 files open instead of just 3.
The differences between my and your environments mean that our preferred workflows differ, too, because what can be problematic for you can be easy for me, and vice versa.
That being said, I also don't advocate "splitting everything into super small files". Splitting a file that is less than a "page or two" (I see 61 lines of code on one page, so less than 120 loc) is a mistake and should be done only in special circumstances, while files that grew larger than 500 loc should be refactored if it makes sense. Files over 1k loc have to be split. That's the policy we use at work, and I think it results in a pretty nice and easy to navigate code bases.
Back to the editors, though: as long as the codebase uses a convention - any convention - consistently, you can make it nice to work with, by altering your environment to match the convention. This is where the more configurable and easier to script editors win big time - if there's something in the codebase you don't like, and can't change, you can script it out of sight and out of mind easily. Coming from such an editor, I personally don't have a strong opinion on how the codebase should be structured (which includes the lenghts of files) - I do have some preferences, but I'm not very attached to them. That's just to signal that I'm not the one of people "fascinated" with splitting files for the sake of it :)
If your convention involves using the same name throughout different files (e.g. every component has a `styles` object), this becomes cumbersome to do. (Arguably, that's a problem with the convention, but sometimes you don't have control over this...)
Other than that, I mostly agree with you and fully admit that it's a matter of preference and highly dependent on your workflow; I was just trying to point out that a single file is generally easier to navigate with an out-of-the-box experience in most editors. I also agree with your stance on when to split files, with a small caveat: even when splitting something into multiple files, I still tend to group them by their high-level function as opposed to by "type". In other words, I would rather split a helper component into its own file with its own styling in the same file, rather than split all of the styling into its own file. (Of course, sometimes you really do have 800 lines of styles, in which case they probably need to be in their own file regardless.)
> That being said, I also don't advocate "splitting everything into super small files".
That's great! :) I see this too often in frontend web development, though: people will go out of their way to keep their files as small as possible to an irrational degree—almost as if they are trying to ensure that you can view every file in its entirety without scrolling.
Actual workflows diverge significantly from the above. It's a matter of cohesion. Yes, co-locating each of the files (and only these files) in a single "component" directory can help ease navigation and discovery, but most of the time it's just easier to keep everything as cohesive as possible.
Some practical reasons for separate files, off the top of my head:
In-lining JS, and CSS means enabling unsafe-eval, which can open up XSS vulnerabilities if you use any content from users or gathered from a source you don't control. You could also do the unsafe-hashes, but that's kind of a pain.
If you're not making a SPA, it would not be fun to copy the CSS to all of your files.
If you do not couple your CSS to your site, you can reuse it across many sites and have the same style. Say if you have separate site for your blog, but want it to look the same as your main site.
If you're working on a team splitting things up into separate files will avoid some merge conflicts.
Chances are they will not be updated all at the same time, so caching would speed up page load times, as the user would only have to download the changed files
The gist is that folder-by-feature is generally preferrable because it requires less context switching (in the literal sense of jumping between multiple different far away folders and scanning each for the thing you're looking for)
Single file components force you to organize code in a folder-by-feature structure, to a large extent. You can use folder-by-feature structure alongside with separation of technologies, it's just not that common to see it because the tooling to support it is not quite as optimized.
[0] https://softwareengineering.stackexchange.com/questions/3385...
Angular is a pretty good example of this. The HTML, CSS, unit tests, and code are all in separate files, but they have the same base name and are grouped together in the same place.
Web app dev has started focusing on single, separate, reusable components instead of trying to design everything on the page at once.
Often, in these components, the HTML, CSS, and JS is still separated, but now (theoretically) you can plug that component in anywhere (even a different app) and, as long as you feed it the right data, it should just work.
Replying to you because this is the shortest expression of this sentiment, expressed in many different comments:
No, it's not because of components. It's because of emulation of components by means of precompilation or JS execution. First-class components are available already, there's no reason to continue to emulate them, unless you need backward compatibility, or have another goal other than separating components.
It's also not about "components" in the meaning of "widgets" - reusable bits of content+view+behavior - because these can be trivially made with standard HTML + CSS + jQuery plugin. It was done since before the DHTML was a thing (hello <iframe>!).
Instead, it's all about web apps, how they achieve responsiveness, and the fact that the more the framework knows about the content (including how it should look in all its states), the easier it is to optimize it consistently. I get that, it's ok for web apps, and it gets better the more nice syntax you throw at the problem (up to a point, as usual), because once you have enough of syntax extensions to replicate the important features of HTML and CSS, you can go absolutely nuts on the actually generated code and nobody would care.
On the other hand, using web app frameworks to write web pages is bad - do you really need to optimize for responsiveness if almost everything you see on the page has exactly one (or two, with hover) state? The same is probably true for languages designed for web apps: using them to write web pages can be tedious and more trouble than it's worth.
TLDR: it's because ~components~ web apps.
And even then you will definitely run into issues such as "in this particular case this particular tab will look like this".
While the web was mostly leaf components (text, articles, images, links) this separation kinda worked. The moment you move into app territory, there are not that many things that are reusable and benefit from separation, because your UI is directly dependent on business logic and vice versa. And because every screen in your app is a unique view into a unique part of your functionality.
This should, ideally, be as short and sweet as possible. In reality, like you say, the two ideas (visual + biz logic) will always be married in any non-trival application.
In other words, you are likely to need too many customizations even to leaf components to be able to use someone else's.
If you are actually using components, that isn’t much of an issue.
In a time when you’d be returning a whole document every single time, it might make sense to say ‘style this one document with this one stylesheet’, and even more so in a time when HTMl was still more or less semantic (e.g. an actual document).
There's also some nice stuff with modern tooling, where CSS is global by nature but writing it with your JS allows for the platform to automatically namespace your CSS, making styling behavior much more consistent.
Separately it also often makes sense to style things not just based on the HTML produced but also based on data stored in JS; writing your CSS with your components allows for a greater level of dynamic styles (which, to be fair, if you can achieve with pure static CSS is preferable, but it's not always the case).
Really? HTML is already heavy on syntax, and the whole point of SGML-style angle-bracket markup is to invisibly structure text hierarchically and sneak in rendering properties or other "metadata" not rendered to the user, via attributes. In which universe, then, has it ever made sense to write
rather than in a document representation language? Let alone today's CSS atrocities. Mind, I'm not talking about CSS' out-of-control layout model complexity, but inventing a new syntax (or a thousand microsyntaxes really) on top of already syntax-heavy markup.If you think about it, CSS appears to have gotten these ninja super-powers because HTML was locked in a decade-long stagnation while W3C was busy with XML, RDF, and whatnot. Then again, in the last decade using <div>s for nearly everything was frowned upon, so with the precedent set in the decade before, CSS just had to re-order, re-place, re-arrange ad absurdum without any discernible mental discipline. Or, maybe the CSS WG people just couldn't stop.
The end effect is that CSS isn't approachable for even seasoned graphic artists let alone laymen; another effect being browser complexity resulting in monopolies.
A false separation-of-concerns narrative has ruined many languages and approaches (such as enterprise OOP); for the web it was particularly idiotic given it's founded on composable documents.
JS? Once it was out there, evolution of HTML and declarative UIs basically stalled because there wasn't anything you couldn't do using JS. Nevertheless, CSS had also grown into outlandish complexity. Basically, the "web stack" of today is what any standardization effort should've avoided.
I also made SnackUI to solve the last problems of fully inline styles: namely to make them work 100% between React Native and Web, to make them extract to atomic CSS on web automatically, to optimize even conditionals into CSS, and finally to make media queries and themes work the same between Native/Web. We’re launching a very large app with it here in not long, and I absolutely love how clear it is to work on.
https://github.com/snackui/snackui
Most of these "new" frameworks are more because someone wanted to scratch an itch or solve a specific problem they had, and frontend code simply lends itself well to being open sourced. If you don't like the new js tools that are made, just ignore them.
This is so true. CSS has become a multi-headed Hydra whose parts appear completely unrelated to each other. I've been a developer and designer for more than 20 years and I have no idea what the parameter names and orders are for position, versus grids, versus float, etc. It's parameter soup. Who said the hardest part of programming is naming things? The CSS folks didn't get the memo.
To do any real work with CSS means you have memorize a bunch of conflicting weirdness and/or keep a reference page open at all times. The idea of CSS frameworks to simplify or fix this doesn't work because, in order to write or debug what you create in those frameworks, you must know regular old CSS!
It's turtles all the way down.
I agree with CSS being complicated, but this statement is true for pretty much everything. Not a day goes by I don’t close 20+ reference tabs at the end of the day, not counting what I closed throughout the day. It’s simply impossible to be a polyglot and not use references.
Who said the hardest part of programming is naming things? Some people do a better job than others. CSS is really wildly inconsistent within in itself. Is it another case of worse is better? Ugh. Probably.
What I’ll forever complain about (as a front end developer) is that there’s no distinction between a document and an app. You can start from a blog post and turn it into a rocket just by throwing more JS at it.
I think only Google can fix it at this point:
- come up with a better alternative for apps
- reward websites that are content-only (or are guaranteed to support Reader view)
Now you could start to have simple documents and a powerful app platform.
Unfortunately this is hard to do as most developers will call bloody murder. So let’s enjoy CSS for the next hundred years, shall we?
Our designer wouldn't have been able to deal with HTML markup within the JS files in React. Having the HTML and (S)CSS separated out made life much easier for him in Angular.
(edit: Naturally downvoted due to being slightly critical of React on HN. Which happens every time.)
You are being critical of separation choices. To which I am curious why embedding the CSS and HTML inside a Javascript file makes any difference to the designer? In practice, we often see slightly different syntax to accommodate, but I cannot imagine that is a true barrier. The CSS and HTML (or their slightly modified equivalents) are still logically separated from the rest of the logic in the file.
He has no idea about how the TypeScript/JavaScript files work. He doesn't really have to touch them, unless to maybe see what extra data the component model contains if he wanted to dig deeper and display other things.
If the designer was handed an HTML page with <style> tags embedded, I cannot imagine he would fall down unable to figure out where the CSS is, and this is not much different.
In olden days, the DOM was treated like something shared. This could lead to a single DOM elements receiving changes from all over the place: Multiple CSS selectors would include it and apply style rules, and multiple JavaScript scripts might select and manipulate it. Spitting the CSS/HTML/JavaScript into multiple files just makes it harder to know what's doing what.
The new frameworks are built around the idea that when we need to manipulate or style a DOM element then it should be isolated from the rest of the DOM, and so should the CSS and JavaScript that do the manipulating. In other words, what we often call "components".
For convenience, we often group these three things into the same file, or into small files sharing the same directory.
Reasoning about them much simpler, because each one is like a tiny HTML document with just a few DOM elements. No need to review hundreds of CSS selectors or JavaScript event handlers, because everything is together in one small package.
Granted, some UI frameworks do add a lot of redundant code to maximise component independence, then offer JS-based or class-based theming to keep development DRY.
It handles CSS by letting you define it in within an individual component (file) but also import a style from another file. That way, your shared styles are in one place and only the overrides or extra styles needed for a special component are in its file.
I think it's wonderful!
Not to denigrate this project in any way, but most or all of its goals are already met by Lit[0]. Instead of a new language, it uses regular TS and regular CSS.
[0] http://lit.dev
But to me, there's a parallel to be made between both the newer trends of components and micro-services, and the old idea of Object Oriented Programming. In all cases, you get sold on the idea that everything should be cut down into tiny pieces.
Theoretically the separation of concerns has tons of merits, but in practice there are a lot of rough edges when those separate pieces have to interact with each others.
And the tradeoffs may not always be worth it when your project isn't on the scale of those large companies (it very rarely is).
The key though is that componentization is useful when you find yourself writing the same code over and over again. That's where DRY steps in and says yeah this should be its own component.
This is one reason monoliths are great as an app structure, because they let you be as DRY as possible and have as few seams as possible (making a component within a monolith doesn't create an external dependency, no seam). Additionally, there are options nowadays (ruby on jets for example) that let you have a monolith repo structure but each controller endpoint gets deployed as a separate lambda. So you get to have your cake and eat it too.
The analogy really does work fairly well at every level of software engineering, from frontend components to backend services.
Intuitively you may not want too much, until you find out that maybe you could have needed a bit more because of the repetitiveness. So frameworks that give you the option to gradually increase it when you need are the best. And when the documentation follows those patterns it's really great (I'd put Vue in that category).
Usually the thinking was, while it may not make sense, it will someday when my project grows, so let's adopt it right away. And for years I would have said that was a decent advice. Nowadays I think that with some of the more extreme scales behind some of those trends though, it's not always as clear cut.
I also think most people are quite bad at organizing CSS, so I'm personally thankful for this change even though I love a well organized simple CSS/HTML site. It means less projects I inherit are rabbit warrens of legacy CSS to unravel.
In my experience it's much more important to modularize/capsulate/segmentate by groupings of business logic then by groupings of implementation details.
Applying this to web applications (not simple text focused websites) this would mean that its preferable to have everything (HTML+JS+CSS) related to a specific widget (e.g. counter) in one place, instead of splitting it into many parts sprinkled across many files potentially in different folders. Similarly you also would e.g. want the CSS to be encapsulated as to the component as far as possible.
Its a bit of a different matter for classical html documents where the HTML made sense without JS or CSS and both where thinks you added "on top" to "just make it a bit nicer" but this isn't the think anymore for modern webapps (and many fancy websites).
Also if you work in a situation where you have many huge teams working on the same UI at the same time touching the same logical component (but normally different aspects of it) then having a more clear segregation can also make sense, but >99% of all companies are not ever in that situation.
This is also for example a major critic I have with react, it splits one logical unit across different files making it much harder to reason about it for the benefit of adding a bit more decoupling which isn't needed by >99% of dev teams.
Because the horizontal way separates the concern the wrong way, or more precisely, the non-scalable way.
The idea is the same way that backend architectures are migrating from layered architectures to microservice or DDD alike architectures.
HTML, CSS, JavaScript separation of concern: 3 layers. Layered architectures: presentation, application, domain, infrastructure etc. There's only O(1) number of layers, so it's not scalable enough for modern applications. You can came up with more layers, but it's still O(1) and would be more strechy, despite the business and codespace are growing fast. People will struggle because everytime they change one layer, they have to find the corresponding other layers of code - it starts to defeat the purpose of separation where it should help people not caring other layers when modifying code.
A more critical separation of concern is to have O(n) separation: you can different domains like products, inventory, sellers, account managment, custommer support etc. If your business continue to grow, you could have more of them. And more importantly, it's much easier to separate teams into pizza-sized teams than layered separation.
Don't get me wrong, layered architectures are still useful. In fact, most of the DDD implementations are layered. But there's mental overhead when you introduce separation. Communities like React and Vue decide that it makes sense to merge layers in Front-end for local reasoning over separation, and accoding to my experience it works well (because I find it's very common to modify HTML, JavaScript, and CSS at the same time before I even started to use React).
When all three of these things have to care very directly about eachother, separating them makes less sense.
https://adamwathan.me/css-utility-classes-and-separation-of-...
I'm impressed!
A course for learning Imba on scrimba, which was made using Imba to make people learn Imba.
https://i.imgur.com/k35ObtV.jpg
"fz" is the typical shorthand used for font-size (at least by Emmet-style autocompleters). "fs" is used for font-style instead.
I.e //app.js ...
//my-todo.js ....
One small note to the author: the “We are hiring” at the very top, on mobile, is a bit broken. It appears on three lines. It looks great in mobile landscape, but not in mobile portrait mode.
What's not cool is to fork Imba, remove the attribution to the original author and pass it off as your own code.
Quite often after reading their doc I just don't understand what result I should expect. Also the whole documentation simply lacks sane navigation. It's almost impossible to find anything there without google.
In 50% of cases this is how it works for me (exaggerated):
Question: how do I sum two integers?
Expected Answer: You should use SUM(). The result of the function is the sum of two integers. Examples:
2 + 2 = 4
2 + (-2) = 0
-1 + (-1) = -2
Answer from Elastic docs: Well, you should execute this query agains this API, which will launch X subroutines in Elastic engine and the final result will be the result of of the aggregation of function defined by the Ex with En+1 being your query's body field Y with respect to url query param N.
FWIW, my experience reflects GP that people really appreciate someone who takes the time to teach/help others. YMMV.
I never had a really successful OSS project but I have a few friends who had or were maintainers of successful projects.
One got poached by FB, another one is a contractor at a higher than average rate.
Also, you can write open source software in big tech companies and even be paid to do it (React core team is a good example). TC39 folks spending time moving the Ecmascript standard forward is another example of staff/principal engineers doing citizenship-oriented work in order to get recognition for impact at FANG L6+. Being snarky about it doesn't change the fact that these sorts of symbiosis exist.
Also, the software quality is high. This used to be the case for Apple and windows sdks. Not anymore.. now it’s “read the code“ or stack overflow
EDIT: ah - butter smooth in edge (and presumably chrome too), but laggy in firefox.
It's really bad with Hardware Accel turned off, but it's still a bit laggier with it on compared to chrome/edge.
I have a low spec PC, and it is running just fine.
Maybe some extension slows down your Firefox? I don't use an anti-ads and anti-spam extension, I deal with that via hosts file.
1. https://www.youtube.com/watch?v=Gzj723LkRJY
This lets you choose from multiple frameworks - comparing svelte against a few react variations, what I saw was that svelte was always fastest, but usually by a factor less than 2 (any react was 1.x times slower than the svelte).
The imba vs react numbers (from the article at https://www.freecodecamp.org/news/the-virtual-dom-is-slow-me...) shows a 30-40x speed difference.
And when you benchmark the speed of creating 10000 dom elements in an instant, less than 5% of the time should really be spent inside the framework one is supposed to test.
I stand by my claim in the mentioned article that tiny changes to a larger dom tree is a far better indicator of real world performance than anything else. Here Imba is really orders of magnitudes faster than react.
The last time I tested it, Imba was more than 10x faster than Svelte as well, but I'm not proficient enough in Svelte to claim that as a fact, and I have tremendous respect for Rich Harris and everything he's done with Svelte and other libraries.
FWIW, my initial impression of imba is that it's very impressive. I do think you rightly point out that, at this point, it may still be hard to leave larger ecosystems of react/vue/etc. DOM/UI speed of the project's JS toolkit generally has not been any meaningful impact in the projects I've worked on in the last several years - the data size and audience and app space just don't really call for it. However... as my needs change, imba will be something I'll revisit. Thank you.
Maybe you're the exception among your peers or something, but I'd wager you're wrong. Benchmark or no benchmark, imba.io and the site for Scrimba are way snappy. In contrast, when I find myself having to derp around on a landing page or a UI made with React or contemporary frameworks, I can feel the bloat. Is it possible that being elbow deep in this stuff has dulled your senses?
I was just saying that for the majority of LOB apps I'm working on, whether a table of 2000 entries renders in .2 seconds or .3 seconds has no meaningful impact on the client projects I'm working on. Even though it's a 50% slowdown, or 33% speed up, depending on how you measure, that speed difference has no impact on these projects. If we got up to 20000 entries, and we were hitting 2sec vs 3sec, that might be noticeable and something to address.
And I'm not sure where you got that I got that you were saying that.
What I am saying is a direct challenge to what you wrote—no need to repeat yourself. I'm saying, positively, that the common standards in React projects produce bloat that is perceptible—in cases I had in mind, FWIW, that are even more trivial/lightweight, by comparison, than the example of 2000 entries you're relating here.
That you consider a threshold on the order of 2 seconds as beginning to be worthy of something that might need to be addressed is significant. It reveals a fundamental difference in our expectations of software. That "no impact" 0.3 seconds figure is already itself eons in CPU time.
(This isn't generic anti-JS, anti-Web sentiment, by the way. In the early days of developer.mozilla.org—up until 2008 or so—I poured a lot of effort working on the JS documentation to make sure high quality docs would be available to a wide audience, so that even more people might pick up JS, which wasn't taken very seriously at the time. That's also, though, why I bristle at the state of React and frontend development—it has sowed the idea that JS, or maybe just software in general, has to be inherently slow and bloated. The average modern Web project on modern mid-range hardware is more top-heavy and perceptibly less snappy than the Electron-style applications like Netscape, Firefox, etc. from 15 years ago, which ran unJITted on sub-Ghz machines.)
That.
Yes, it's eons. I get that. But the time/effort required to make modifications to be faster isn't something that my some of my clients - with limited budgets - are asking for.
Some are, and they care about speed. Typically there's lower hanging fruit in server side query optimization, reduced payload sizes, etc. But I'm sure you already know that.
I agree with most of your closing paragraph too, btw.
Are the two strategies as similar as they sound, or am I misunderstanding something?
On benchmarking: I went through the same concerns and ended up building a little benchmarking tool for a simple reactive UI library I'm working on. It's not super user-friendly yet but doing a good job of profiling tasks.
You can write custom benchmarks by clearly separating pre-setup work than relying on ready-made benchmarks (a bit of a pain initially, but helps a lot to fine-tune at unit-level going forward).
It uses Chrome DevTools Protocol(CDP) through Puppeteer and allows to analyze execution durations separately (Scripting, Layout, Paint, etc). Plus, it saves raw JSON profiling data, so you could import & examine it visually on DevTools Performance Tab's Timeline.
Think it will be helpful: https://github.com/dumijay/pfreak This is how the results look like: https://caldom.org/benchmark/
As described in your second link, that benchmark is timing something a bit different – and we don't know how well Svelte would perform on it (I'm guessing fairly similarly, since the overall approach seems similar. But there's no way to know without measuring.)
Some "frameworks" achieve good numbers there by being utterly unusable in real life, others miss the spirit of the benchmark completely (e.g. submitting a non-keyed implementation as keyed thereby gaining an unfair/misleading advantage), and as somebee said, the benchmark itself largely measures repaint time (and does so in a less than ideal way, by using setTimeout macro queue as a proxy for repaint time measurement, in band, instead of instrumenting performance via CDP). It lacks rigor in many ways (the most blatant was that initially it considered keyed and non-keyed implementations on par, but there are other issues such as putting a lot of weight into DOM creation compared to e.g. array diff, or as somebee said, not measuring low repaint load diffs)
IMHO, it only has two things going for it: a) it has a lot of frameworks listed b) it does at least attempt to measure repaint times unlike other benchmarks that only measure JS time (which has become somewhat irrelevant since V8 et al now offload repaints out of the JS thread)