• Many years ago I was using jQuery (as the web platform wasn’t uniform myself yet) and found myself frustrated with it. I wanted a better ability to reuse code patterns. I wanted to have loose coupling between different pieces of UI behavior.

    This is the bit that I find mostly missing from this analysis, though it touches on it a bit when it talks about React components as higher-level primitives. But to me, it’s not just about sharing components between developers, it’s also about the organization of an application.

    The “platform” doesn’t expose such concepts. It’s a grown set of pieces of APIs for a wide range of functionalities, and not everything is very consistent. When I want a reusable piece, I often need some kind of combination of these functionalities. The platform itself does not let me express this. Web components are a long-standing but not very successful attempt making it happen. Something like React, for all its flaws, does.

    We don’t typically tell people to “use the platform” when they want to draw graphics on the screen. It’s curious to consider why. We know that doing graphics requires a lot of different functionalities, from drawing pixels to mathematics to loading a file in a particular format. We know that there are plenty of options to do each. We know there are high level frameworks (like game engines) that take care of a lot of the things for you. How is the web browser different? I think this is because it inconsistently plays the roles of both higher level framework and providing low level functionality.


    score 1 · canonical

  • Because the “the platform” is not one thing, it is unpredictable in practice. If I customize the scroll bar in chrome, to make it wide enough so that users can see it, there is no indication to me that this will be ignored by Firefox.

    If I try to use a key derivation algorithm to create an asymmetric key pair , it will work in chrome , and again, there is no indication to me that it will fail in Firefox until i test it…

    So for any component which Must work (why put things in your app that don’t have to work?) We have to exhaustively research how every single platform implementation implements it.

    Sometimes its just easier to build it yourself than to do the research, other times, the platform is user-hostile in ways that we don’t like, or conflicts with design requirements, such as the user being able to see the scroll bar and grab it, or being able to generate an asymmetric key from something other than the webcrypto prng, such as from user input.


    score 1 · canonical

  • I think the article misdiagnoses why folks don’t use the platform.

    For Nolan’s <dialog> example, it’s a rare thing to be the first person on your team authoring a dialog. Someone’s already built it, battle tested it, and extended it with design requests over years. It doesn’t matter if it’s standard, more accessible, and simpler. You’re still duplicating a core component.

    Spend social capital. Get time to migrate the core dialog component. After a brief fight translating entrance animations, it’s a clean port. Merge! … Hyrum’s Law deals a critical hit. Dropdowns and tooltips break across the app because tethered windows fall behind the dialog layer. Another part of the app is crashing from a listener binding to a now-missing click backdrop someone used to hijack an exit flow. Part of the app you didn’t even know about is borked because 3 years ago that team’s designer pushed a new dialog theme, powered by hubris and selector soup of overrides that no longer match.

    None of this is hard, but it’s tedious and socially expensive. You just lost days to a change nobody* will notice.

    *except your boss

    I’ll assume Nolan’s intended audience is solo devs, design system maintainers, and folks working in greenfield projects. In that case <dialog> is perfect. There’s no baggage to fix. Yeet it.

    But <dialog> is a strawman. It’s one of the easiest components these days! (Infinite thanks to browser people for making that sentence possible.) Try it with tooltips or dropdowns. Even assuming your targets support Anchor Positioning, Popover API, and Interest Invokers, you’ll lose days studying the APIs and all the nuance of how tooltips are meant to behave. And like the royal order of adjectives, there’s a lot of nuance completely invisible until it’s missing or written wrong.

    If you power through, it still needs to be abstracted away from the platform. You don’t want teammates using @position-try to override flip conditions. At best, coworker Bob adds a prop out of frustration for having learned an obscure CSS paradigm just for your custom tooltip (grumble). At worst, they’ll actually use it and freeze you to that specific implementation.

    Assuming the tooltip works, now it’s time for the long tail of evolving scope and edge cases. The design team wants arrows on the tooltip. Users can’t select tooltip text because it disappears when their mouse leaves the trigger. There’s a bug where italicized text inherits into the tooltip…

    It wasn’t a waste; you get a prize at the end: whatever’s in your head and the undocumented equivalent of an abandoned npm package.


    I’ve done this before. I love the platform. But in a work context, the only pragmatic answer is to install a package and move on with OKRs.


    score 1 · canonical

  • It is bed time for me and I can rant about this at length, but I think a lot of people just genuinely have no clue what the platform can do, and because everyone else is doing it one way, there’s disincentive to bother learning. I’m constantly frustrated by bosses being like “sure you can do that but what about the rest of the team?” even when it is trivial. Or recently here on lobsters I said in a comment it is trivial to do an upvote form without js and several people came in to berate me cuz they couldn’t even believe such a thing was possible, much less trivial. If everyone else needs 100 lines of TypeScript to make a hyperlink, why should they believe I can do it with just <a href="url">?


    score 1 · canonical

        • Aye, this irks me because it came from a work project. The React guy wrote something like <div onClick={location.pushState(); location.href=something} class="text-underline yada yada yada"> and then user opened a bug report saying middle click doesn’t open links in new window and he added another few lines to the handler, then shift+click, then keyboard navigation… 100 lines is a bit of an exaggeration, but it added up fast. (and right click, open in new window still doesn’t work so it’d prolly be more than 100 if it tried to do all that too!)


          score 1 · canonical

  • Oh boy I have a lot of thoughts about this.

    Firstly, #usetheplatform is regarded as false a premise by many, because the “platform” they talk about is 90% controlled by Google and their most recent motivations, and usually “Works best in Google Chrome™” until their competitors are bullied into implementing those features as well.

    As a “React developer” I personally enjoy working at a higher abstraction level while building web UIs, and dropping down to the imperative browser APIs causes me to do a mental gear change. I would never want to mix this with business code, and containing it to a reusable component in the end looks the same as pulling a dependency from npm with much better testing and coverage, if I can find one.

    I think the IKEA effect can be reversed as well. If you can use something from npm, building it yourself instead is kind of fun and challenging. There are many npm packages that only exist to wrap a non-ergonomic browser API to adapt it to the React world. And I’ve seen many junior engineers (and agents) make the mistake of never bothering to check if this was already packaged on npm and roll their own version of it.

    React vs browser APIs being in different abstraction levels may not be obvious to everyone, so let me elaborate a bit further. React–and most of its modern alternatives–let me write and compose components declaratively, and you pass things directly using variables and import/exports. Web components, the cited platform alternative to React and its ilk, use string references as component names, and pollute a global namespace. That’s just the tip of the iceberg for me for never even considering web components.

    To set the record straight, even though the platform is controlled by an evil company, most of it is still great. I get excited by code that I get to delete thanks to the new browser feature! And I usually consider non-ergonomic web APIs as a compile target anyway and write my code at a higher abstraction level. I find npm to be a treasure trove if you know how to navigate it, but it’s still useful to take a few minutes to see how your dependencies work under the hood.

    #usetheplatform hashtag tries to make this picture black and white. There are horrendous web APIs that I wouldn’t touch with a ten foot pole, but I still use web APIs directly or indirectly, and I see it as my responsibility to keep up with the additions to see how I can make my code easier to maintain, more performant, and more accessible.


    score 1 · canonical

    • lobsters__nolan@crustaceanson.theshelf.topOPM
      link
      fedilink
      arrow-up
      1
      ·
      1 month ago

      I think it’s a fair point that “use the platform” originally came out of Chrome DevRel (at least, that’s where I first heard it). But I can’t recall any other browser vendors taking exception with it, and I imagine that the non-Google engineers working at the CSS Working Group would be delighted if more web devs used their stuff!

      One of the reasons I didn’t get into web components is that they’re a very touchy subject and not an obvious slam-dunk win like “replace 100 lines of JS with 1 line of CSS.” Also keep in mind that nobody (or very few) people in the web components space ever expected web components to replace frameworks entirely – there’s a reason that Lit, Fast, LWC, etc. are built on top of web components. So some of the “use the platform” marketing there was directed at framework authors themselves (React, Solid, Svelte, etc.), who I think had very reasonable gripes with the limitations of web components (SSR, accessibility, etc.). Anyway I had two entire posts on the topic, so no need to rehash it here. 😆


      score 1 · canonical

      • Until recently, I thought web components looked kinda cool, but were also impractical for real work because of the requirement to use javascript. The benefits they bring can mostly be done other ways too… like I have server side expansions around, can use delegated event handlers in the dhtml case, etc. What convinced me to finally try it again was a blog post (i don’t think from you but possible) here on lobsters that said use it without the shadow dom as a progressive enhancement hook.

        I just started playing with that on Friday and I’m already really happy with it - keep the server side expansion, then implement the same thing in javascript as well (both based on just three substitution rules from a template, my impl was about 100 lines in both D and Javascript), and put a little framework around concatenating stylesheets using the relatively new nesting stuff in css and… it is coming out really nice and I’m not sacrificing the nojs users. And actually, it enhances a bit even for them, because it makes the noscript bit a little easier to support - putting all the script-required bits in the attach element thing and allowing some <noscript> bits in my template does a nice bit of encapsulation.

        Like I said, only started playing on Friday, so too premature to delcare Mission Accomplished but I am really happy with it so far. I might even actually use the shadow dom sometimes now lol


        score 1 · canonical

    • As a user, I utterly despise react as the reason why every indivifual browser tab these days takes 20 seconds to load and hydrate, and then eats up good half a gig of memory while providing absolutely no value over a plain server-side-rendered html page.


      score 3 · canonical

        • That is no value. A web server that can render JSON can also render HTML. And if one builds a static JS website that needs no API to work it can also be static HTML instead. There is simply no HTML that is expensive to render on a web server, ever, a web server will never reach CPU load capacity off of rendering HTML.


          score 1 · canonical

  • I suspect there are a few more aspects:

    1. Many (most) developers are not power users and they don’t see the depth of what the platform provides and what they lose by rolling their own implementation. To give a few examples:
    • middle-clicking a link to open it in a new tab (doesn’t work with most JS-based “links”)
    • keyboard navigation (Alt+<letter> shortcuts in menus, tab order, typing in dropdowns,…)
    • consistency with other native controls
    • platform integration (password managers, accessibility tooling, navigation history,…)
    1. Especially on the web, some platform components are still somewhat broken (e.g., date pickers) or missing (e.g., why is there no browser component for an image gallery and instead every website has its own creatively broken half unusable version? same for rich text editing).

    score 1 · canonical

    • lobsters__nolan@crustaceanson.theshelf.topOPM
      link
      fedilink
      arrow-up
      1
      ·
      1 month ago

      It’s a good point, yeah. I think in my “dialog” example a common case would be that the JS developer builds something that works well enough for sighted mouse users and then completely ignores all the stuff you’re supposed to do for keyboard or screenreader users.

      I think some of it also comes from React component libraries not having the proper affordances/idioms to easily swap in a link for a button or vice versa. So you reach for a button to do a link’s job and then break a bunch of stuff like right-click, middle-click, etc.

      OTOH I’ve also seen cases where the React library did have the proper idioms, and the problem is that the developer didn’t know to use them! For example at my work we use Chakra UI which I’ve found has excellent accessibility, but only if you use it exactly as documented. (Arguably this is another case of “not understanding the platform.”)


      score 1 · canonical

      • Two comments… one, when people say like <select> looks wrong (something btw that isn’t the case anymore like it used to be), I point out that compromises are always made. Often, people compromise on the accessibility or nojs or whatever minority case instead of the visual bits the majority sees, but fact is they do compromise on requirements and sometimes you can convince them to shift which compromises they make in favor of using the platform instead of the alternatives.

        Second comment on links and buttons, it occurred to me a little while ago that every link is a button, but not every button is a link. Specifically, every link is conceptually a submit button on a little GET form, with action of the href url. I think it is kinda useful to realize this to help with a conceptual model (actually, why can’t you submit any form to a new window? they really should be more interchangeable than they currently are), but the link is also quite specialized out of the box and it is the specializations that give the attention to detail that makes a UI pleasant to use.

        I think my advice (and I want to write a tutorial someday, like web from first principles, but who has the time) would be to realize the general concept then go to the most specialized thing the platform offers that still fits, and then go ahead and specialize it a bit more with your css/script. When doing a thing, ask: What is it? What does it do? What does it look like? in that order and go from there. But “what is it?” is a kinda deep philosophical question that is easy to beget lol


        score 1 · canonical

  • Adopting a library is always easier than removing it. Every project that builds on an evolving platform needs a team that tracks libraries and in-house abstractions against new platform features to then remove the old cruft. But I bet most just don’t.


    score 1 · canonical

    • This is basically why at my previous company we never migrated to platform APIs. We spent years maintaining things for compatibility across browser vendors and it became a sunk cost fallacy.

      Plus, if it’s not 100% parity (which a lot of platform APIs are not) someone will complain and you’ll have trouble getting stuff into the codebase.


      score 1 · canonical

  • The platform is often all-or-nothing, so when the built-in behavior isn’t perfect - in all browsers - the devs are forced to reinvent the thing from scratch. The date picker is most hopeless of them all. Sometimes it’s due to some detail, like a weird line-height or small tap area, or animation that is too fast/slow/not in sync with some custom element.

    I also expect that devs who got burned by some buggy or non-customizable detail don’t even try to use the platform next time, and go for having full control from the start to avoid disappointments later.


    score 1 · canonical

    • The date picker is most hopeless of them all.

      Time input easily beat it for ages, although it’s a bit better now. I know one browser (old Edge?) always used 12 hour input regardless of locale. Firefox doesn’t give a dropdown, it just looks like a weird text field. On iOS it looks like a blank button until you tap it.


      score 1 · canonical