Skip to content Skip to footer
0 items - $0.00 0

JavaScript Views, the Hard Way – A Pattern for Writing UI by voat

JavaScript Views, the Hard Way – A Pattern for Writing UI by voat

JavaScript Views, the Hard Way – A Pattern for Writing UI by voat

17 Comments

  • Post Author
    zffr
    Posted April 19, 2025 at 4:04 am

    The read me says this approach is extremely maintainable, but I’m not sure I agree.

    The design pattern is based on convention only. This means that a developer is free to stray from the convention whenever they want. In a complex app that many developers work on concurrently, it is very likely that at least one of them will stray from the convention at some point.

    In comparison, a class based UI framework like UIKit on iOS forces all developers to stick to using a standard set of APIs to customize views. IMO this makes code way more predictable and this also makes it much more maintainable.

  • Post Author
    atum47
    Posted April 19, 2025 at 4:11 am

    On my first official job after college I was working on making a web version of a Delphi software. The team was already on their third rewrite of the front end cause they had to change frameworks. I made the cass that we should write our own framework, so I prototyped FOS (the components I use on my website) to prove my point. The team (a bunch of mostly Delphi programmers) did not like my suggestion. Anyways, soon after that another company made me a better offer so I left. Years went by an I finally take a shot at another framework: tiny.js [1]. I've been using it in all my personal projects so far. I'm particular proud of the ColorPicker [2] component I wrote that I've used in two projects so far. As you can see, one can argue that tiny.js it's not a framework at all, just some wrapper functions that helps you create Functional components.

    1 – https://github.com/victorqribeiro/TinyJS

    2 – https://github.com/victorqribeiro/Chip8js/blob/master/js/Col…

  • Post Author
    lylejantzi3rd
    Posted April 19, 2025 at 4:31 am

    I came up with something similar recently, except it doesn't use template elements. It just uses functions and template literals. The function returns a string, which gets dumped into an existing element's innerHTML. Or, a new div element is created to dump it into. Re-rendering is pretty quick that way.

    A significant issue I have with writing code this way is that the functions nest and it becomes very difficult to make them compose in a sane way.

        function printPosts(posts) {
          let content = ""
    
          posts.forEach((post, i) => {
            content += printPost(post)
          })
    
          window.posts.innerHTML = content
        }
    
        function printPost(post) {
          return `
            <div class="post" data-guid="${post.guid}">
              <div>
                <img class="avatar" src="https://imghost.com${post.avatar.thumb}"/>
              </div>
              <div class="content">
                <div class="text-content">${post.parsed_text}</div>
                ${post?.image_urls?.length > 0 ? printImage(`https://imghost.com${post.image_urls[0].original}`) : ''}
                ${post?.url_preview ? `<hr/><div class="preview">${printPreview(post.url_preview)}</div>` : ''}
                ${post?.quote_data ? `<hr/><div class="quote">${printQuote(post.quote_data)}</div>` : ''}
                ${post?.filtered ? `<div>filtered by: <b>${post.filtered}</b></div>` : ''}
              </div>
            </div>
          `
        }

  • Post Author
    edflsafoiewq
    Posted April 19, 2025 at 4:40 am

    It appears to be exactly the kind of manual-update code that reactive view libraries exist to replace.

  • Post Author
    dullcrisp
    Posted April 19, 2025 at 5:23 am

    Why not use Web Components? Is it because they’re classes?

  • Post Author
    athrowaway3z
    Posted April 19, 2025 at 6:01 am

    This might be heresy to many JS devs, but I think 'state' variables are an anti-pattern.

    I use webcomponents and instead of adding state variables for 'flat' variable types I use the DOM element value/textContent/checked/etc as the only source of truth, adding setters and getters as required.

    So instead of:

      /* State variables */
      let name;
    
      /* DOM update functions */
      function setNameNode(value) {
        nameNode.textContent = value;
      }
    
      /* State update functions */
      function setName(value) {
        if(name !== value) {
          name = value;
          setNameNode(value);
        }
      }
    
    

    it would just be akin to:

      set name(name) { this.nameNode.textContent = name }
      get name() { return this.nameNode.textContent}
    
      /* or if the variable is used less than 3 times don't even add the set/get */ 
      setState({name}){
         this.querySelector('#name').textContent = name;
      }
    

    Its hard to describe in a short comment, but a lot of things go right naturally with very few lines of code.

    I've seen the history of this creating spaghetti, but now with WebComponents there is separation of objects + the adjacent HTML template, creating a granularity that its fusilli or macaroni.

  • Post Author
    triyambakam
    Posted April 19, 2025 at 6:03 am

    I like to prompt Claude to create artifacts in plain HTML, CSS and JS. I like the portability and hackability of these. React is too heavy for a lot of simple ideas even if reactivity is needed.

  • Post Author
    dsego
    Posted April 19, 2025 at 6:53 am

    This reminds me of the venerable backbone js library.
    https://backbonejs.org/#View

    There is also a github repo that has examples of MVC patterns adapted to the web platform.
    https://github.com/madhadron/mvc_for_the_web

  • Post Author
    hyfgfh
    Posted April 19, 2025 at 7:15 am

    [flagged]

  • Post Author
    yumaikas
    Posted April 19, 2025 at 7:18 am

    I've been working on https://deja-vu.junglecoder.com which is an attempt to build a JS toolkit for HTML-based doodads that shares some ideas with this.

    I don't quite have proper reactive/two-way data binds worked out, but grab/patch seem pretty nice as these things go. Also, the way this uses templates makes it very easy to move parts of the template around.

    It's also largely injection safe because it's using innerText or value unless told otherwise.

  • Post Author
    popcorncowboy
    Posted April 19, 2025 at 7:48 am

    …eschews abstractions…

  • Post Author
    admiralrohan
    Posted April 19, 2025 at 8:01 am

    Might be feasible with the advent of vibe coding. For frontend heavy applications can choose this route for performance reasons. Starred, will follow the project.

  • Post Author
    atoav
    Posted April 19, 2025 at 8:33 am

    I program for roughly two decades now and I never got warm with frontend frameworks. Maybe I am just a backend guy, but that can't be it since I am better in vanilla JS, CSS and HTML than most frontend people I have ever met.

    I just never understood why the overhead of those frameworks was worth it. Maybe that is because I am so strong with backends that I think most security-relevant interactions have to go through the server anyways, so I see JS more as something that adds clientside features to what should be a solid HTML- and CSS-base..

    This kind of guide is probably what I should look at to get it from first principles.

  • Post Author
    seumars
    Posted April 19, 2025 at 8:47 am

    It seems the "hard way" here is just avoiding frameworks. The real hard part of UI is in fact state management and the myriad of methods for handling state.

  • Post Author
    smarkov
    Posted April 19, 2025 at 8:55 am

    People like to hate on PHP, but PHP provides you with all the tools you need to write a fully working backend, where as JS provides you with half-assed solutions for writing frontend, which is why we have 1000 frameworks and we still can't agree on how to write frontend code. Seriously, we don't even have a convention for writing a simple reusable component with vanilla JS, everyone makes up their own thing. Web components were supposed to be that, but they're a good example of what I meant by "half-assed", because they're ugly, verbose, clunky, don't really solve the right problems, and nobody likes writing them.

  • Post Author
    wruza
    Posted April 19, 2025 at 9:07 am

    Something is wrong with web developers culture, cause even in framework-free vanilla mode they cannot get rid of data localization and welding the data and "component" trees together irrepairably.

    Rather than building a querySelector-able tree of elements to and monkey-patching mutiplexing nodes for syncing element counts, you invent the most bizarre ways to chain yourselves to the wall. For long time I couldn't understand what exactly drives this almost traumatic habit, and it's still a mystery.

    For the interested, this is the outline I count as non-bizarre:

    – make an html that draws your "form" with no values, but has ids/classes at the correct places

    – singular updates are trivial with querySelector; write a few generic setters for strings, numbers, dates, visibility, disability, e.g. setDate(sel, date)

    – sync array counts through cloning a child-template, which is d-hidden and locatable inside a querySelector-able container; make syncArray(array, parentSel, childSel) function

    – fill new and update existing children through "<parent> :nth-child(n) <name>"

    – update when your data changes

    Data can change arbitrarily, doesn't require passing back and forth in any form. All you have to do is to update parts of your element tree based on your projections about affected areas.

    And no, your forms are not so complex that you cannot track your changes or at least create functions that do the mass-ish work and update ui, so you don't have to. For all the forms you've done, the amount of work needed to ensure that updates are performed is amortized-comparable with all the learning cliffs you had to climb to turn updates into "automatic". Which itself is a lie basically, cause you still have to jump through hoops and know the pitfalls. The only difference is that rather than calling you inattentive, they now can call you stupid, cause you can't tell which useCrap section your code should go to.

  • Post Author
    epolanski
    Posted April 19, 2025 at 11:53 am

    I have been writing recently an application in plain "vanilla" TypeScript with vite, no rendering libraries, just old-style DOM manipulation and I have to say I more and more question front end "best" practices.

    I can't conclude it scales, whatever it means, but I can conclude that there are huge benefits performance-wise, it's fun, teaches you a lot, debugging is simple, understanding the architecture is trivial, you don't need a PhD into "insert this rendering/memoization/etc" technique.

    Templating is the thing I miss most, I'm writing a small vite plugin to handle it.

Leave a comment

In the Shadows of Innovation”

© 2025 HackTech.info. All Rights Reserved.

Sign Up to Our Newsletter

Be the first to know the latest updates

Whoops, you're not connected to Mailchimp. You need to enter a valid Mailchimp API key.