18 ms·
Building a front end framework – Reactivity, composability with no dependencies
- pkphilip 3y agoVery interesting. I think this explains a lot of the magic that happens under the surface in the frontend frameworks. I quite like the approach you are using to avoid a build step and also zero dependencies.
- revskill 3y agoThis is good progress. I hate that i can't do progressive enhancement on pure html form with Frontend Framework. Example, RoR already provides powerful good library like SimpleForm. Now i want to turn this html form into a React form, how ?
- oblib 3y agoThis is certainly new to me and something I'm going to play with a bit. Thank you for sharing this here.
- icemelt8 3y ago[dead]
- grncdr 3y agoThis is extremely similar to https://jhuddle.github.io/ponys/ https://jhuddle.github.io/ponys/ which I've been using quite happily. The `data-mark="foo"` convention is interesting, similar in spirit to ng:bind or knockout attributes.
- joncfoo 3y agoThis is really neat! I'm going to take it for a spin in a simple CRUD internal app.
- dxchester 3y agoNice writeup. We're working on a framework with similar goals, here: https://github.com/frameable/el https://github.com/frameable/el Reactivity, composability, templates, etc with no dependencies, in ~150 SLOC.
- mtlynch 3y agoThis is great! I've been looking for a framework with exactly these goals. I've been using vanilla JS and custom elements and feeling like I'm writing too much boilerplate, but all the frameworks I've tried are too heavyweight.
- spankalee 3y agoHave you tried Lit yet? It gives you a reactive base class and declarative templates. Plain JS and no build step (or you can use TypeScript).
- mtlynch 3y agoI played with it a little bit when you told me a few months ago it supports buildless.[0] The thing that dissuaded me is that it seems like it forces me to write my template HTML in strings, so I lose VS Code syntax highlighting and Prettier auto-formatting. I tried looking for VS Code / Prettier plugins but didn't see anything. Is there a way in Lit to write the templates in regular HTML rather than a string? [0] https://news.ycombinator.com/item?id=34828992 https://news.ycombinator.com/item?id=34828992
- spankalee 3y agoThe lit-plugin in for VS Code offers syntax highlighting, jumpt-to-definition, etc: https://marketplace.visualstudio.com/items?itemName=runem.lit-plugin https://marketplace.visualstudio.com/items?itemName=runem.li... Prettier already supports HTML in html`` strings, likewise, CSS. > Is there a way in Lit to write the templates in regular HTML rather than a string? This would require a compiler. You would need to load the HTML into the JS module graph and JS can't do that yet, though there is a proposal for it: https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md https://github.com/WICG/webcomponents/blob/gh-pages/proposal... Template in HTML also have the problem of the data not being in scope as it is in JS, and there not being an expression language. So you ned up having to re-implement a lot of JS embedded into the HTML syntax, which then preferences a compiler-based approach to make fast. It turns out to be a lot simpler to embed HTML in JS.
- hbroek 3y agoEnjoy the process of building your framework. I had similar goals when I started my no tooling / no dependencies Reactive framework https://reken.dev https://reken.dev, 2 years ago. And I loved every bit of it. My most complicated problems were reactive DOM elements based on nested loops and recursive components. Even though Reken does pretty much what I need and grew to 7kb compressed, I am not 100% happy with the scope of the application state, and it is simple but sometimes confusing. Perhaps your proxy approach can help me here.... I'll have to think about it more.
- 18al 3y ago> My most complicated problems were reactive DOM elements based on nested loops and recursive components Agreed, I've tried solving it by setting an attribute `sb-mark` which allows syncing just the branch of DOM elements that maps to that particular key in the reactive object. This removes the need for VDOM diffing, but unless I use a `MutationObserver` external updates to marked branches will probably mess it up. Haven't yet tested it for recursive components, it should work for nested loops. > and it is simple but sometimes confusing I understand what you mean, my approach has the aforementioned `sb-mark` attribute/directive which syncs primitives, lists, and objects. I've started feeling that the convenience of having just one attribute to remember is supplanted by the confusion of its implications not being immediately apparent from context.
- hbroek 3y ago> This removes the need for VDOM diffing, but unless I use a `MutationObserver` external updates to marked branches will probably mess it up. Similar in Reken. It controls all the DOM; DOM updates outside Reken will get stuff out of sync. After a model change, all managed DOM gets directly updated by a generated controller. It does check the DOM first if a textContent or attribute change is necessary. Most DOM state checks are cheap. Another optimization is that all hidden DOM trees get skipped; Great in SPA apps with multiple pages.
- lelanthran 3y agoYour arrays and buttons example appears broken - after the first item is added to the todo list, typing new items in the input field leaves the add button looking disabled (although it works when you click it). I think it only gets enabled when focus leaves the input field.
- datadeft 3y agoWhy do we need a frontend framework? I am genuinely interested. The last project we used SSR and the sire ended up fast and snappy using a lot less energy than the previous similar project we used a JS based framework and we had all the functionality we needed.
- whstl 3y agoProjects that don't need a lot of interactivity after rendering definitely don't need one and you can get away with rendering everything in the backend. Other projects need some additional features that must be implemented in the frontend, but still don't need more than vanilla JS or jQuery. Others might need more complex components, such as datepickers, carousels, interactive charts, interactive tables, accordions. But even those can be consumed from third-party components without a framework. A middle ground is writing your own encapsulated components. However there are more complex apps that do benefit from frameworks. It's often because they have a lot of custom components and a framework really helps; and/or because they're not really divided into pages in a traditional web way, so rendering on the backend is significantly harder; and/or they have a lot of shared state between multiple areas of the screen, and not refreshing is easy than caching or re-fetching. All those among other reasons. Slack Web can benefit from this. Your daily CRUD not so much. Whether people are using the right tools for each job is up for debate. And sometimes you'll have incorrect requirements. But there are definitely reasons to use more complex/flexible tools.
- _heimdall 3y agoThey were extremely useful before browsers had certain features, like web components of the Proxy api mentioned in the article. Today the argument is usually based on highly complex apps, think complex dashboards accessible behind a login or browser-based apps for recording a podcast. Those are reasonable uses for client-side frameworks - the problem is they are often used for much more basic sites that just need a mobile menu, accordion component, or a dialog modal. All of these can either use entirely browser native HTML/CSS or easily built in JS without any dependencies.
- muspimerol 3y agoI think the common argument is "complex interactivity". If you have sufficiently complex custom client-side interactivity (e.g. sending, receiving, manipulating and displaying data in the DOM without constantly reloading the page) then something like React or Vue is much easier and more maintainable than a bunch of custom JS. Logic for mutating and displaying data can also live on the backend and use SSR, but it has to live somewhere. I think people like SPAs because you can draw a convenient boundary at the server level by exposing a JSON API, and folks working in HTML, CSS and JS like the component model offered by frontend frameworks (I know I do). There's also something to be said for consistency. When I walk into a React or Vue app, I can figure out what's going on and build on top of it quickly. Even if they are using a mish-mash of libraries (as JS apps do) the majority of the time you will see similar libraries and patterns used. All that said, there are many monstrosities built upon SPA frameworks with poor performance that would likely provide better user experience if they were using SSR. But there were also many SSR monstrosities built before SPAs were in vogue.
- lolive 3y agoYet another people denying React Hooks has won...
- petilon 3y agoVery thin frameworks can avoid the complexities of React and hooks and useEffect and whatnot. Here's an app written with a 500-line "framework", notice how readable and maintainable it is: https://github.com/wisercoder/eureka https://github.com/wisercoder/eureka
- djbusby 3y agoLess Framework and more Library it feels like. Also, wondering if there are other tools for searching code and other internal Corp stuff on external services (GitHub/Lab, Google Drives, etc)
- klysm 3y agoNew front end frameworks that claim leaps in simplicity feel like the violate some kind of no free lunch principle to me. If they’re that simple, then I’m willing to bet they make some use cases very difficult or impossible
- duxup 3y agoI feel like the only things that provide “ leaps in simplicity” as far as web dev goes are basic css frameworks. Generally they really can save a lot of time / needed structure.
- klysm 3y agoSure but they make certain things very hard or impossible, usually as things get more dynamic. But CSS has gotten a lot more dynamic capability in recent years.
- capableweb 3y agoI've found that if they brag about how easy it is to get started, it usually ends up messy relatively quickly. On the other hand, if they brag about being easy to order when you have a lot of code, it's usually a bit harder to get started with. It's like you get to chose one of "get started quickly" or "remain quick enough on the medium/long term"
- bitL 3y agoNot always, some can hit the sweet spot of being simple in all phases of development and quick to learn. They are super rare though and their lessons are forgotten; industry often standardizes on inferior things with better marketing.
- balder1991 3y ago[deleted]
- karpierz 3y ago
- dclowd9901 3y ago> The second main reason is the ability to define a component and reuse it without having to redefine it every time we need to use it. This is called composability. Uhm, this isn’t strictly composability. Its reusability. Composability is distinct in that you’re architecting or designing components to be composed with one another. That is, they only know what they need to know and isolate domain. Also, their composition interface is the same as their output interface. A likely outcome is reusable components, but it’s not the goal necessarily.
- ttfkam 3y agoThey literally just described Svelte with that headline. Front end framework: check Reactivity: $check Composability: check No dependencies: once compiled, check And pretty sure Svelte (or Qwik or Solid or even React) will perform better than the "dependency-free" custom components. The open secret in the front end world is that custom components as baked into browsers is slower and a major pain in the ass as an API. That's why it wasn't adopted widely and why it will likely never be adopted widely. The funny thing about stories like these is that once you write the first general use code that isn't based on your specific task, you've created a dependency. Only this dependency isn't improved and maintained by a community or company; its maintenance is handled by you and your team. Maybe you take it on because the benefits outweigh the costs for your team. You improve and refine "just a few functions". Other folks like what you've done and ask to use it. Now they have a dependency on the "no dependencies" framework. Eventually you have to give it a name, and it gets popular. A few years later, a developer decides they doesn't want any dependencies in their front end code anymore…
- _heimdall 3y agoKind of bending definitions to say svelte doesn't have any dependencies once compiled. Svelte itself is a dependency, and though complex and bundled there are svelte utilities included in the app that aren't code directly written by the user. Anecdotally, if also be very interested to see any example of a production Svelte project that doesn't pull in any other dependencies. The article also calls out no build step, though it's not in the title. That's an important factor for the kind of project that isn't updated regularly and needs to work without any fuss after a year or two of going stale. I'm a big fan of svelte by the way, been using it since pre-release 2.0 and still reach for it whenever I need a more complex state management or don't have the time to roll my own animation trigger utilities.
- ttfkam 3y agoFair points.
- hbroek 3y agoI love Svelte for all these reasons. But in the end, was turned off by the required tooling.
- aabbcc1241 3y agoI'm experiencing the trade off between simplicity and expressiveness for a lightweight frontend library that doesn't involve VDOM. On one hand, a library [1] can be very concise (update dom from object, with looping and nesting supported). On another hand, a library [2] can be very flexible and reactive (update dom from dom events). However, when double-binding (a.k.a. bi-directional binding) is required (update dom from object and update object from dom), it seems more complex than I would consider it lightweight. When double-binding is preferred, I'd rather go for angular / vue. Still exploring alternatives. [1] https://github.com/beenotung/data-template https://github.com/beenotung/data-template [2] https://github.com/beenotung/dom-proxy https://github.com/beenotung/dom-proxy
- adparadox 3y agoNice write-up, I look forward to seeing how Strawberry progresses. I keep a list of JS front end frameworks where no build step is required at https://unsuckjs.com/ https://unsuckjs.com/. I'll add this there (and a few of the others mentioned in the comments here).
- aabbcc1241 3y agoWould you also add these js library to the list? They don't require build step as well. https://github.com/beenotung/html-template-lite https://github.com/beenotung/html-template-lite https://github.com/beenotung/data-template https://github.com/beenotung/data-template https://github.com/beenotung/dom-proxy https://github.com/beenotung/dom-proxy
- adparadox 3y agoI added `dom-proxy` because that looked like the closest to a complete solution from a quick skim. Let me know if you want to swap for another one, though.
- aabbcc1241 3y agodom-proxy is the most recent work, I'm glad it stands out to you
- spankalee 3y agoLit 2.x is compatible with IE11, btw. We're actually removing that in the upcoming 3.0 branch though.
- adparadox 3y agoThanks for the correction. Just updated it to be accurate... for now. :)
- imbnwa 3y agoAs someone who started out in this profession in their early 30s, it was made clear very quickly, both by observation and shared wisdom, that it was completely possible to go one's entire career never getting below the level of gluing business code together with the adhesive of some framework, i.e. never learning how to design a system or think from the 'bottom' of a solution. While its arguably more accessible than ever, you can quickly find yourself swimming in a shallow pool if you're not careful where your first job is, unless you have the free time and comportment to swim towards the deeper end on your own. And the larger magnitude that this occurs at, the greater the stranglehold of most devs to some well-funded framework and tooling. So I applaud reminders like this that ask to just take a step back from time-to-time and maybe provide ourselves a new opportunity before reaching for $BIG_FRAMEWORK when the project is a few views w/ some buttons and an input on them. There has to be some balance between the utter pragmatism and curiosity and exploration that builds skills to have a healthy demo of devs. I routinely see this second-hand classist complaint about 'JavaScript devs ruining software' (particularly w/ Electron in hand, even though the most used Electron apps are probably worked on by high-tier devs) but really the source of that concern is the market desiring that devs be more or less replaceable for the most part and the skillsets follow that. You can't break that without some disruption to the Framework-Industrial Complex.
- lloydatkinson 3y agoLost me at web components. What a miserable DX and inconsistent mess that is.
- spankalee 3y agoWhat's inconsistent about them?
- es7 3y agoOn a recent project, I’ve just been using JS template strings and .innerHTML all over the place. I don’t necessarily recommend it, but it’s been a good reminder to me that most of the value React provides me is literally just html-in-JS. In many cases the complexity that comes from React effects and state is unnecessary, and directly mutating DOM nodes is sometimes a lot less painful. Sometimes.
- wbobeirne 3y agoThis definitely works until you hit one of a few cases I can think of: * Adding animations to elements. By blowing away the DOM and inserting new elements each time, you'll trigger any css `animation` for new elements entering. * Stale data. If your template isn't re-run when some data changes for whatever reason, you'll continue to render the old data. You've got to manage the lifecycle of state updates yourself. * To counter that, you might just re-run your templates when _anything_ changes. This works until you have a significant amount of data, then performance starts to become an issue. This won't come up for many cases though, so for simpler apps it's definitely more than enough!
- pier25 3y agoPlease don't make websites dark mode only. This is terrible for accessibility. I have astigmatism and can't read more than a few paragraphs. https://medium.com/@h_locke/why-dark-mode-causes-more-accessibility-issues-than-it-solves-d2f8359bb46a https://medium.com/@h_locke/why-dark-mode-causes-more-access... If the issue is not wanting to spend a bit of effort to implement prefers-color-scheme then light mode is a much better default option.
- vjerancrnjak 3y agoI do not have astigmatism (or at least I think I don’t) but I notice that the rows of white letters stay burned in my vision, the contrast was so high it’s as if I am staring at small strong light sources. So I prefer black letters on light background.
- geraldwhen 3y agoMaybe this is why I cannot read dark mode websites at all. Even coworkers with dark mode themes on their IDE are completely inscrutable to me.
- earthling8118 3y agoI have astigmatism with the opposite effects. I wish more sites had dark modes. I have to use dark reader to ensure I can have a dark page but that doesn't always work.
- pier25 3y agoDo you use your devices in a well lit room?
- gloosx 3y agoI think a lot of stuff is taken wrongly in this article. First of all, React.js is a library that just provides a handful of hooks. "magical HTML and JavaScript" code is called JSX, and that is transpiled by Babel into not-so-magical nested function walls. Imperatively applying mutations to an application state inside a proxy object setter is, in fact, proactive and not reactive. Reactive implies that the renderers are pure declarative functions that are derived from data, so changing the data would result in a different renderer output based on a composition of these pure functions. So, in the end, React.js is just a library that brings a pure functional renderer to the web, and you even need a separate library, called react-dom, in order to manipulate the DOM itself with the outputs of React function. If you want to approach something similar to React, try to abstract away from DOM and HTML, and think in terms of a single pure data function, which returns a tree that can be then traversed into a set of UI elements.