Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Using shadow DOM, HTML comments to make a React-like view without JSX (github.com/i5ik)
4 points by graderjs on Sept 27, 2021 | hide | past | favorite | 1 comment



Hello Humans of HN

This is BANG!. It's a new framework made from old parts and old ideas. I originally developed the idea for a custom Custom Element framework back in 2014, with Shadow DOM v0, and implemented it for an Electron app. I fell in love with organizing my UI into little style-encapsulated widgets. It drastically improved my productivity. The code was lost, or I deleted it, but the main thing was the lack of cross-browser support for Shadow DOM v0--I couldn't throw my weight behind something and pour my heart and soul into building things based on half-baked technology that didn't have standard support across the browsers. I just couldn't. So I waited.

In the intervening years I had a need for another front-end framework. I disliked React for its not-quite-HTML-not-quite-JavaScript JSX syntax, and complexity seemingly for the sake of complexity. I also disliked the need to add a long and growing list of dependencies, as well as a transpiler and what I considered other build detritus just to build some nice views, dirtying and complicating and another clean and simple project. When you added a new tool, then you needed more new tools, to help you debug and manage the tool you just added.

I knew there had to be a better way. I loved the pure view as a function of state idea of React, and I loved the idea of having stuff declared obviously in the HTML. I just wanted real HTML, and real JavaScript. And I knew I could achieve it--I thought I could achieve it--using regular ES6 template literals and template tag functions. And I could. So I build brutal.js in 2018, because I needed a framework I enjoyed working with. And I wanted to take a stance against the unnecessary complexity of other frameworks. It resonated and clocked up ~ 500 stars in pretty short order. And I built TodoMVC in it, and submitted a PR to that project. But they rejected it, then hastily changed their rules, saying something like, "We should only allow PRs from legitimate and popular frameworks, say, at least 5,000 stars". And it hurt--because I knew I had something good, but people weren't interested unless it was "famous". At that point I thought about doing a benchmark between Brutal and React, and trying to prove it was better by showing performance, or iterating toward such. But I concluded this idea would fail as well. It was the same ideas as BETA vs VHS. People weren't interested in better technology. They were interested in what the fad was. Sure, better is a relative term. For me, it's all about what makes me productive. But in many ways, Brutal.JS was better -- simpler, smaller, faster, and it had minimal DOM diffing without VDOM overhead, instead using granular updates. That's not what mattered to people, they wanted scale. And trust. Social proof. I understood people wanted something to trust, because their business relied on a website, and so the website tech had to be shiny and big. That made sense...but I couldn't understand engineers going along with that. To me it seemed the world had gone crazy. I decided it was necessity and economics that made people pick substandard tech.

So...I stopped caring about the competitive aspect of building frameworks, and just focused on what originally motivated me: improving my own productivity. I used Brutal (by then known by other names, now known as VanillaView, henceforth "VV") in production facing apps and it really worked. Really well. I noticed some niggles here and there, but I left them because I had other things to do. The framework did what I hoped it would do. Why I created it. It got out of my way so I could build stuff. So I was happy.

Then when I had some more time, I started thinking that I'd like to make those improvements. But I felt like trying something new. So I picked up Web Components, did some research, and began re-writing my 2014 framework in Shadow DOM v1. Somehow I remembered the main ideas and had no trouble implementing them. They were good ideas: a standard base class, a way to declare then use components, organizing each component into its own directory with 3 files defining it: markup.html, style.css and script.js. This method really worked for me. It was how I liked to work. It maximized my productivity.

But then I got to thinking: I really like how React has these custom void tags. You know--those self-closing tags (like <input> etc) but custom? I really, really liked that. That had been one of the things that I'd wanted to improve about VV; but at the time I'd decided that the extra parsing required to do so would be too much of a perf and maintenance hit. So I backed off. But this time was different. I just felt, there must be some way I can do this with HTML. So I started thinking, and I realized that HTML comments could encapsulate a set of almost arbitrary text. So... comments would do. I tried out the syntax in a bit of pseudo code and I decided I didn't mind the leading bang (!) character at all. In fact it highlighted something; was different--it spoke to me. And I never used syntax highlighting, and coded all my work in vim, so the lack of shiny support for my new syntax didn't phase me one bit. I iterated a bit on the parser code to transform comments into custom elements, and came up with something efficient using MutationObservers (that also needed to be attached to every new shadow root created). But again, it worked. I was stoked. Really happy. I was getting somewhere.

Then I decided, as cool as the syntax was about this, as cool and as useful as the work organization, the flow of the work was for me, to use this framework. I wanted to make it better. I wanted minimal diffs. And I wanted templating that was simpler than using <slot> elements in the Shadow DOM (which anyway would not make sense with my self-closing bang-tags). So...I merged, VV and this custom element framework, and in the process, created something new, that was a merger of my original v0 custom element framework from 2014, with my min-diffs, React-like-but-not-react JS template tag function framework from 2018, with some new ideas about adding things that I'd wanted all along: being able to include a descendent component with just a single HTML tag, rather than, as I had done in VV, using a ${} template slot, and a JS function call to the view.

So it was an epic ~10 days of work during the Mid-Autumn festival in Asia that brought me, and now you, this great epic new framework. I'm happy with it. It works for me. And I'm not sharing it here to compete with React. I'm sharing it here because maybe it can provide value for you too. Maybe you don't want to use it, but you get some ideas. Or maybe you do want to use it. Either way, that's why I'm putting it here. For you.

Also, check out the 7 GUIs (well 6 so far): https://i5ik.github.io/_____/7guis/




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

Search: