[HN Gopher] TodoMVC App Written in Vanilla JavaScript
       ___________________________________________________________________
        
       TodoMVC App Written in Vanilla JavaScript
        
       Author : marban
       Score  : 138 points
       Date   : 2022-05-07 11:38 UTC (11 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | cehrlich wrote:
       | I once wrote a Twitter clone in Vanilla JS, just for the sake of
       | it.
       | 
       | I'm glad we have frameworks.
        
       | Philip-J-Fry wrote:
       | The thing I enjoy about frameworks like React is the declarative
       | nature of the UIs.
       | 
       | I'd love to not be able to use them and to create complex UIs in
       | pure JavaScript but it always ends up being painful where you
       | spend more time optimising the rendering than doing any work.
       | 
       | In simple apps I will write UI in a functional matter in pure
       | JavaScript, regardless of the performance implications. But
       | bigger DOM means worse performance with this method.
       | 
       | When will we get to the point where we can tell the browser what
       | we want the DOM to look like and then the browser does the
       | diffing like a framework would?
        
         | ricardobeat wrote:
         | There's absolutely no way you'll have worse performance with
         | this vs React. The app is modifying the target elements
         | directly, not recreating the whole page with innerHTML. React
         | will do the same amount of work at a minimum, and that's
         | _after_ rebuilding the whole tree and diffing it.
         | 
         | The main bottleneck here are the synchronous localStorage calls
         | happening in the render path, they could be moved to a separate
         | timer.
        
           | Philip-J-Fry wrote:
           | I never suggested you'd have worse performance. But it's not
           | declarative, it's tedious.
           | 
           | Read my comment again.
        
           | grayrest wrote:
           | > There's absolutely no way you'll have worse performance
           | with this vs React.
           | 
           | It's normal to get much worse performance than React if you
           | layout thrash and it's very easy to layout thrash without
           | batched updates. There's overhead in the vdom but getting all
           | the updates batched tends to be a performance win in any
           | decent sized app. This was an active area of library
           | exploration/development in the 2008-2012 timeframe but the
           | only framework actively promoting it was Sencha IIRC.
        
           | toomim wrote:
           | One way React can be faster than hand-written code is by
           | batching all dom manipulation into animation frames.
        
             | ricardobeat wrote:
             | The rendering code here is already batched since everything
             | happens within a single render() call. And unless you're
             | using react fiber, its rendering is also synchronous.
        
             | sarchertech wrote:
             | Handwritten JS could also batch DOM manipulation (without
             | the need for virtual dom comparison).
        
               | SemanticStrengh wrote:
               | https://github.com/wilsonpage/fastdom
        
               | 1marc wrote:
               | Ooo fastdom looks great! Thanks for the link.
        
               | SemanticStrengh wrote:
               | https://www.youtube.com/watch?v=VKMw2it8dQY
        
           | chacham15 wrote:
           | It seems like you didnt actually look at the code because
           | thats exactly what its doing:
           | https://github.com/1Marc/todomvc-
           | vanillajs-2022/blob/main/js... it clears innerHTML there and
           | then rerenders the children
        
             | 1marc wrote:
             | I did this style to mimick modern framework code -- taking
             | the state (todos) and render the state of the world every
             | time. If the browser had a DOM diffing api this would be
             | more efficient and we would be there. So for a larger
             | project I might using something like Lit's html stand-alone
             | package or fastdom to get the DOM digging functionality
             | without much dependency code.
        
             | ricardobeat wrote:
             | You're right, I did a quick reading and thought it was
             | updating elements one by one.
             | 
             | I still suspect this might be faster than React anyway.
             | Would be interesting to try.
        
             | SemanticStrengh wrote:
             | Right but proper manual dom is generally faster than
             | optimized react code. That does not means that in general
             | manual dom code is proper.
        
         | kgbcia wrote:
         | i agree it's up to the browsers chromium , Safari , and Firefox
         | to do the diff. But we might need a new meta tag or change to
         | the Fetch API to tell them this html page should only update
         | the elements that are different.
         | 
         | Remember <meta http-equiv="refresh" content="5"> .
         | 
         | It was discouraged because the back button broke. If you're
         | developing a single page react app, I don't think you care
         | about the back button.
        
           | nkrisc wrote:
           | > If you're developing a single page react app, I don't think
           | you care about the back button.
           | 
           | Your users likely do, so you should too.
        
           | creakingstairs wrote:
           | > If you're developing a single page react app, I don't think
           | you care about the back button.
           | 
           | You should though. One easy way is to use react-router. e.g.
           | going to /profile renders the Profile component. Then
           | navigating to /dashboard renders the Dashboard component.
           | Pressing the back button will take you to /profile.
           | 
           | Another pet peeve of mine is people using internal react
           | state when they should just use path or query params to make
           | it transparent and easily sharable.
        
           | alserio wrote:
           | The primitives of fine grained reactive programming seem to
           | me more amenable to be implemented by the browser than react-
           | style whole world diffing
        
         | recursive wrote:
         | Cases where "UI should be a function of state" seem like a
         | small sliver of all use cases. Probably not worth the
         | complexity for implementing directly in the browser. And there
         | are plenty of conditions that just prohibit the pattern
         | entirely as far as I can tell. Things where referential
         | stability matters, like you have a contentEditable or allow
         | arbitrary edits on a canvas.
        
           | deergomoo wrote:
           | Personally I would argue that UI should _always_ be a
           | function of state. When it isn't, you open yourself up to all
           | sorts of inconsistencies and difficult edge cases. Of course,
           | it's not always that easy; having two sources for said UI
           | (the HTML document itself and the JavaScript within it)
           | certainly complicates matters.
        
         | mattgreenrocks wrote:
         | Echoes of Alan Kay's recent comment on how software devs are
         | way too concerned with the how the computer works to the
         | detriment of what the software is supposed to do.
        
           | ramesh31 wrote:
           | Yup. The reality is that programmer time is far far more
           | expensive than compute time. And as long as that's the case,
           | increasing levels of abstraction are our only hope at
           | building complex software.
        
           | emteycz wrote:
           | The battle is fought over performance and size, I think
           | that's exactly what the user wants.
        
             | vips7L wrote:
             | I don't think the typical user cares about size.
        
               | oblib wrote:
               | I agree. In over 20 years I've never had a single user
               | ask or complain about the size of the app. They have let
               | me know when there was something not working right
               | though.
        
               | 1marc wrote:
               | People definitely notice speed and performance. They
               | won't complain about it generally, sure... but there's
               | plenty of data and case studies on the fact that users
               | care https://nitropack.io/blog/post/web-performance-
               | matters-case-...
        
               | ramesh31 wrote:
               | >People definitely notice speed and performance.
               | 
               | There's sort of a "Maslow's Hierarchy of User Needs" that
               | exists in software though. So long as the user _can_ do
               | something, and their immediate needs are met, performance
               | concerns are just a small annoyance. And generally they
               | will continue to ask for more features rather than
               | performance improvements as long as the app remains
               | _usable_.
        
               | emteycz wrote:
               | Well then you've never seen poor people uninstalling apps
               | from their cheap smartphones because they need to install
               | and use a different one ;-) that you don't see it doesn't
               | mean it's not there
        
         | anonymoushn wrote:
         | it sounds sort of wild to expect there to be diffing! why do
         | you have to generate a whole copy of the stuff instead of just
         | telling the browser what changes to make? bonus: the existing
         | apis instead of one that don't exist yet.
        
           | Bilal_io wrote:
           | Diffing seems necessary when your UI gets complicated to the
           | level that a small change requires a full page re-render.
           | However, I don't think this is necessary for at least 95% of
           | the websites on the internet.
        
           | dymk wrote:
           | Diffing is exactly what you need to do (barring newer methods
           | like svelte) to figure out what to tell the browser to
           | change. The vdom tree is much faster to manipulate than DOM
           | nodes.
        
             | recursive wrote:
             | But you can't see those changes until the actual DOM
             | changes as well. It's only because of react's insistence
             | that mutation is evil that this became a problem. You could
             | just directly update the thing you wanted to and just skip
             | the whole diff thing.
        
               | dymk wrote:
               | No, the reason React has a VDOM is because the DOM is
               | slow to update, compared to manipulating javascript
               | objects. It's worthwhile to calculate the list of minimum
               | updates ahead of time rather than using the DOM as the
               | source of truth.
               | 
               | Not sure where you think mutation comes into play here,
               | that's an orthogonal concern--you can have an API that
               | mutates some internal representation of a VDOM, and it's
               | still faster than manipulating the DOM directly.
        
               | recursive wrote:
               | In order to achieve immutability, large chunks of state
               | have to be cloned whenever a single value changes. This
               | sometimes causes a whole new DOM node to be created
               | during reconciliation. React encourages you not to think
               | about it too much. But some nodes can't be replaced. Like
               | canvas or anything contentEditable. It's not orthogonal.
               | It's a direct consequence of the design philosophy.
        
           | Philip-J-Fry wrote:
           | Because it can be automated? Every app that doesn't do this
           | is just implementing the diff by hand, e.g. on this event
           | delete this element, update this element, add CSS class to
           | this element, etc. When the UI gets complicated you have to
           | maintain this all yourself and it's a pain. Multiple event
           | listeners between components to say something has happened.
           | 
           | It makes sense to be able to describe what you want to
           | achieve and to let the browser determine how to get there in
           | the most efficient way.
           | 
           | If the browser could do this it would make a tonne of JS code
           | so much simpler. There's a lot that goes into making sure
           | that there's no unnecessary DOM updates because it's just
           | slow.
           | 
           | I don't write assembly and move things between registers by
           | hand, I write a function and the compiler decides the most
           | efficient way of doing it. UI should be the same way, I say
           | what I want to happen and the browser decides how to get
           | there.
        
             | 5560675260 wrote:
             | > When the UI gets complicated you have to maintain this
             | all yourself and it's a pain
             | 
             | This is also something that can be automated by a
             | framework. Check out https://svelte.dev/blog/virtual-dom-
             | is-pure-overhead
        
               | Philip-J-Fry wrote:
               | Yes... but that's the exact argument I'm making here.
               | Unless you want to go through that pain, you need a
               | framework.
               | 
               | Whether that's Svelte without a VDOM or React with a
               | VDOM. The entire point of these frameworks is that you
               | can write complex UI in a declarative way. They both
               | exist because writing it declaratively in pure JS leads
               | to performance issues. But there's nothing stopping the
               | browser implementing something that does this
               | optimisation for you.
        
               | recursive wrote:
               | I find the "pain" to be drastically overstated. See this
               | HN post.
        
             | bobbylarrybobby wrote:
             | Yes, but there are ways to accomplish this automation
             | without diffing. Svelte does this by statically wiring up
             | the data dependencies in your app when it builds, and then
             | at runtime making exactly the changes to the DOM that it
             | needs to based on the information it had at build time. No
             | need to diff.
        
               | Philip-J-Fry wrote:
               | The point is that A) that's a framework and B) that
               | requires you to compile Svelte files.
               | 
               | If you want to write declarative UI in pure JS then you
               | need the browser to do these DOM optimisations for you,
               | and diffing the changes is the way to do that.
        
       | goldenkey wrote:
       | How do we get 31 comments but not a single one on why this
       | solution is subpar?
       | 
       | The entire TODO list is rendered anytime a single item is
       | changed/removed/added. The biggest thing frameworks give us is
       | fast, differential DOM updates.
       | 
       | Once browsers add differential update APIs, then we can kiss
       | React and all the other players goodbye :-)
        
         | taeric wrote:
         | I mean... You aren't wrong, but the amount of data that fits on
         | a typical page is usually such that the speed of a full refresh
         | probably shouldn't be that big of a deal.
        
         | timcavel wrote:
        
       | syspec wrote:
       | Wouldn't this have loads of memory leaks from never removing the
       | event listeners when the todo elements go away?
       | 
       | I think it hides the complexity by pretending that's not a
       | problem
        
         | realPubkey wrote:
         | Also it does not work properly when it is used in more then one
         | browser tab.
        
           | grabanski wrote:
           | Here's what it would look like to support that usecase:
           | https://github.com/1Marc/todomvc-
           | vanillajs-2022/commit/09979...
        
         | gherkinnn wrote:
         | The event listeners get cleaned up by the GC. At least in
         | modern browsers.
         | 
         | While events aren't explicitly mentioned, MDN offers an
         | insightful read:
         | 
         | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memo...
         | 
         | Alternately, one can use event delegation [0]. As does React
         | under the hood [1].
         | 
         | 0 - https://javascript.info/event-delegation
         | 
         | 1 -
         | https://reactjs.org/blog/2020/08/10/react-v17-rc.html#change...
        
       | rickstanley wrote:
       | Nice! I was going to suggest the usage of Trusted Types API [0]
       | to escape HTML [1], but support [2] for modern browsers is not
       | there yet, specifically for HTML.
       | 
       | 0: https://developer.mozilla.org/en-
       | US/docs/Web/API/Trusted_Typ...
       | 
       | 1: https://github.com/1Marc/todomvc-
       | vanillajs-2022/blob/1c31309...
       | 
       | 2: https://developer.mozilla.org/en-
       | US/docs/Web/API/TrustedHTML...
        
         | grabanski wrote:
         | Cool! I'll look into the API and consider adding it to this
         | implementation. Or happily would take a look at a PR for it.
        
           | randomfool wrote:
           | Seriously- just do the innerHTML assignment on li.innerHTML
           | omitting the title, followed up by a simple
           | li.querySelector().textContent = todo.title.
        
             | grabanski wrote:
             | How does this look? https://github.com/1Marc/todomvc-
             | vanillajs-2022/commit/d38e5...
        
       | arriu wrote:
       | For me, the biggest issue with using vanilla JS is the lack of
       | guardrails.
       | 
       | Before even considering something like this I'd want to see a
       | style guide and clear definition of where code should live.
       | Frameworks like React do that well. I can expect a random React
       | dev to mostly do similar things.
        
         | notduncansmith wrote:
         | > I can expect a random React dev to mostly do similar things.
         | 
         | This has not been my experience. Even experienced software devs
         | will differ stylistically, but intermediate devs often come up
         | with _very_ different ideas about how things ought to work. I
         | suspect this is due to wide variance in awareness of different
         | libraries /platform features/stylistic patterns/etc, a
         | consequence of being in a relatively unregulated industry.
         | 
         | I have worked for companies using React since 2014 and no 2
         | projects have had the same layout. My current and previous
         | employers have had the closest codebases, but only in terms of
         | directory structure, and even now the current one is changing
         | to become quite different (in a way I think is good, but only
         | time will tell).
        
       | yuzuquat wrote:
       | Hey! This is really awesome. I'm building my own SPA in vanilla
       | js, and I'm definitely stealing some ideas here. I think a lot of
       | people here see the resurgence of vanilla js as a repudiation of
       | their favorite framework. There's a definitely a time and a place
       | for both, and it's never bad to take a break and revisit the
       | basics
        
         | 1marc wrote:
         | Thank you! Agreed!
        
       | norswap wrote:
       | FWIW TodoMVC does list a vanilla JS implem:
       | https://todomvc.com/examples/vanillajs/
       | 
       | It's older though (seems to have been first written 6 years ago)
       | and has significantly more code.
        
       | wackget wrote:
       | Why is there HTML inside the JavaScript? Doesn't that defy the
       | entire point of the MVC pattern?
        
         | dymk wrote:
         | That's a misunderstanding of MVC - it's a design pattern that's
         | language agnostic, not a declaration that HTML needs to live
         | separately from JavaScript. The view logic in JS lives
         | separately from the model logic in JS lives separately from
         | controller etc.
        
         | pjmlp wrote:
         | React people think it doesn't, and apparently that is what
         | everyone should be using...
        
       | mrspeaker wrote:
       | I like the "const TodoStore = class extends EventTarget" idea to
       | trigger rendering... neat trick!
        
         | telagraphic wrote:
         | I noticed that, where does one even find EventTarget in the
         | docs/references? I feel a bit behind on built in apis...
        
       | xupybd wrote:
       | I'm impressed this took an hour and a half. Is this the kind of
       | timeframe someone should be able to throw something together in?
        
       | xdennis wrote:
       | Vanilla JavaScript feels like jQuery now. Doing this was quite
       | awkward in ECMAScript 3 and 5.
       | 
       | > App.$.filters.querySelectorAll('a').forEach(el =>
       | el.classList.remove('selected'));
        
       | oblak wrote:
        
         | [deleted]
        
       | ravenstine wrote:
       | Looks well made, code is pretty good, but why the archaic form of
       | JavaScript other than the import statements? There's a lot of
       | well supported syntactic sugar that would make it much easier on
       | the eye. I also wouldn't bother with the IIFE.
        
       | timcavel wrote:
        
       | qudat wrote:
       | Now add 500 more features and 10 engineers and see if it scales.
       | Hint: it doesn't. Sure you can make it work, but as someone who
       | regularly makes FE decisions for a team, I wouldn't want to
       | impose vanilla on them.
       | 
       | What I will say is it's tough. I don't like the idea of react at
       | this point. I like building products that don't need something
       | heavy like react/redux.
       | 
       | I recently launched https://lists.sh to scratch that no js itch.
       | It was a ton of fun and I want to chase that feeling.
       | 
       | But building a web app is what businesses want. And while you
       | could make vanilla js work, you'd be reinventing a lot of tooling
       | to get you there.
        
         | 1marc wrote:
         | With some patterns they can follow, vanilla js does indeed
         | scale so well that it becomes boring. There's no longer any
         | code to rewrite for the latest and greatest frameworks. No
         | dependencies to manage. It just becomes almost too easy at some
         | point, at least in my experience with many projects I've led.
         | 
         | I've made millions and millions for major brands, including my
         | own company, and customers go "wow how is your site so fast!!"
         | All. The. Time.
         | 
         | The biggest pressure I've found is from the engineers
         | themselves. Not all engineers like to go counter culture and
         | learn browser APIs and JavaScript. They would simply like to
         | use what everyone else is using. They tend to argue against
         | vanilla using canned arguments read off of framework websites
         | that don't apply much or aren't even problems in the actual
         | codebase.
         | 
         | :shrug:
        
         | BiteCode_dev wrote:
         | Also:
         | 
         | - add time constraints, where you need to implement widgets
         | that you could source from a JS framework ecosystem otherwise.
         | 
         | - in your 10 engineers, make it 5 juniors, 2 interns and 3
         | seniors comming from PHP, and make sure they write all the code
         | in the same style, follow a congruent architecture, can find
         | solutions to common problem, get easy onboarding, etc.
         | 
         | - request sub-routing, off-line mode, notifications, content
         | udpated by multiple users and so on.
         | 
         | - put a big table in there with 10000 rows and ask your team it
         | renders fast.
        
       | danielskogly wrote:
       | I wrote a TodoMVC App with React, Redux and SSR that works
       | without JS enabled in the browser a while back, for those
       | interested in that sort of thing :)
       | 
       | Demo: https://todo-react-redux-noscript.herokuapp.com/
       | 
       | Repo: https://github.com/wishy-gift/todo-react-redux-noscript/
       | 
       | Talk (updated framework): https://m.youtube.com/watch?v=3yY-
       | Z-X3xE4
       | 
       | Helpers to do your own stuff:
       | https://www.npmjs.com/package/@wishy-gift/noscript
        
       | Trufa wrote:
       | I'm sorry but this is not a fairly complex app. When things do
       | get more complex (and not even that much) is when you start
       | hitting problems. How would you reuse a "component"? Among many
       | other things.
       | 
       | I honestly don't know if that's the point of the author but I
       | would agree that many framework are too heavy, but honestly there
       | so many good compromises today that don't make you re-invent the
       | wheel and fix bugs that have been have been fixed millions of
       | times before.
       | 
       | Going against good abstractions as developers seems to go against
       | the most powerful tool we've got.
        
         | moffkalast wrote:
         | > How would you reuse a "component"?
         | 
         | Save the element template as a string and set innerhtml of a
         | div as that?
         | 
         | > compromises today that don't make you re-invent the wheel
         | 
         | Yeah but there's also no need to include jQuery and bog down
         | your site with piles of code you won't ever call just because
         | you don't know how to use the native api like a normal person.
         | React/Angular/whatever are just the latest fad of that mindset,
         | big team corporate ease of use aside.
        
           | wildrhythms wrote:
           | What happens when you need to update some deeply nested child
           | element without re-rendering the whole tree? Suddenly you
           | need some system of labeling the children, how to find them
           | in the dom, how to update them, how to keep them in sync with
           | the state... a vanilla JS solution becomes extremely unwieldy
           | as soon as you step out of the "global pointers to elements"
           | phase (what the project in the OP is). Lit-html is an example
           | of a tool that solves this problem in tiny package- less than
           | 1KB- and you can continue using string templates with that.
        
             | moffkalast wrote:
             | I mean speaking for myself, I mostly make robotics web apps
             | which isn't the most typical of web applications but the
             | times this sort of thing is needed are few and far between.
             | 
             | So yes, this pattern is helpful for solving that sort of
             | thing when it occurs (and if the use case is even
             | substantial enough to warrant it) and Lit looks like it
             | would fit that role reasonably well, but basing the entire
             | site on this principle as a full on framework seems a bit
             | ludicrous.
             | 
             | What html actually lacks is the option to include external
             | html part files, but there are lots of ways to do that
             | serverside that don't involve the stupid idea of putting
             | html into strings in js files for literally everything.
        
         | moreira wrote:
         | It's a good way for people to revisit the current status quo
         | and avoiding cargo cult. Frameworks are useful, but there's
         | definitely an element of cargo cutting going on in the JS
         | ecosystem whereby no matter what the requirements, you just
         | reach for React/Vue. We're getting to a point where almost
         | nothing that uses JS gets built without a frontend framework
         | (and all its weight) anymore.
         | 
         | One thing that's easy to notice from reading the code is that
         | so much of the code takes inspiration from the frameworks
         | themselves. How the code is organised - the state store, the
         | render function, the computed getters, the mutation methods,
         | it's all there. It's clean.
         | 
         | Perhaps the main benefit of frameworks is that they've taught a
         | whole generation of JS developers how to organise their code in
         | a way that can scale to bigger, more complex apps (vs. how easy
         | to make a mess of things in the jQuery days).
         | 
         | -
         | 
         | Having said that, I do agree with your point about things
         | getting more complex: This is a properly specced, easy to grasp
         | project. Throw in stakeholders and PMs needing to add
         | functionality and requirements changing, and this system might
         | start to struggle. Not to mention the cost of onboarding new
         | developers. I feel like that's the best thing about frameworks
         | in any language; when you jump into a new project you know more
         | or less how everything is organised and where things are
         | supposed to be, and you can get going fairly quickly.
        
           | mch82 wrote:
           | Building on your comment, frameworks have described
           | themselves as "polyfills". Polyfills used to be libraries
           | that added modern browser features to old browsers. Then,
           | Angular and React began using polyfills to add future
           | features to modern browsers. The intent was always
           | communicated as "some day we won't need this because it's
           | built in to HTML5 and when that happens your initial payload
           | will be smaller". Typescript has had similar effect on
           | JavaScript language features and syntax.
           | 
           | This rewrite of the Vanilla JS TodoMVC is a great
           | illustration of how far things have come.
        
       | ericsilly wrote:
       | My app CardBoard (https://www.cardboard.team/) is no-framework
       | vanilla js. This is a large-ish codebase with a lot of
       | functionality, and the same code is wrapped with apache cordova
       | for both iOS and Android apps. In 2022, browser-native
       | WebComponents (addresses encapsulation, code organization, and
       | re-use) with no frameworks is a hill I'd die on.
        
       | ghubcoder wrote:
       | I get this running it in chrome                 Uncaught
       | SyntaxError: Missing initializer in const declaration (at
       | helpers.js:4:14)
       | 
       | Installed and ran with:                 npm install       npm run
       | start
       | 
       | Any idea what went wrong...?
        
         | ricardobeat wrote:
         | The assignment (=) is missing from those const declarations,
         | except for the first one; I guess they were hastily converted
         | from function declarations to satisfy modern tastes.
        
           | grabanski wrote:
           | Oops, yeah I just accepted a pull request from the community
           | that broke my helpers module declarations. Just fixed it,
           | thanks for noticing!
        
       | gherkinnn wrote:
       | A good exercise, well executed.
       | 
       | While I would rather nail my bollocks to the ceiling than build a
       | vanilla application (in any stack), there's no denying the
       | benefit revisiting the basics.
        
       | krembanan wrote:
       | Yeah, that's exactly what I would imagine vanilla js code look
       | like, and I'm glad we moved on to frameworks. Just this small app
       | seems not so fun to maintain
        
         | blowski wrote:
         | Yep, it's a really nice demo for how to use JavaScript. But
         | it's not a valid criticism of Vue, React, Svelte because it's
         | solving a very simple problem. The reason for those frameworks
         | becomes clear when you have multiple people maintaining it and
         | adding features.
        
         | [deleted]
        
       | lelandfe wrote:
       | Oh, hey! This is from the founder of Frontend Masters - easily
       | the best FE resource I've ever found:
       | https://frontendmasters.com/. Their content creation process is
       | pretty nifty: they run live workshops regularly that subscribers
       | can join, and the footage from the workshops ultimately gets cut
       | and turned into the tutorials.
       | 
       | Had no idea who was behind it, but I love that they're still
       | contributing back like this.
        
         | grabanski wrote:
         | Ah, thanks for the plug!! I did this as a fun little weekend
         | project, glad people are finding it useful as a reference of
         | how simple vanilla JS can be these days. :-)
        
       | msoad wrote:
       | This code reminds me of Backbone. I think we all started here and
       | then abstracted event handling and reactivity into a tiny
       | framework like Backbone.
       | 
       | React and other declarative approaches are inherently different.
       | In React I hardly think of when my component renders. In Backbone
       | days, I remember having to debug why some part of code is not
       | running when I'm expecting it to run. React does this really
       | well.
        
         | steve_adams_86 wrote:
         | A cool thing about react is that it's easy to reason about as
         | well. The reconciliation algorithm is fundamentally pretty
         | simple and there isn't any magic happening.
         | 
         | It can get confusing to track down unexpected renders when you
         | think the result of the algorithm should be different, but
         | that's not really an issue with react so much a the nature of
         | managing complex state, memoization algorithms which
         | potentially use different diffing strategies, and logic which
         | might be mutating state in ways you don't quite expect, and so
         | on.
         | 
         | People criticize these front end libraries but I'm still
         | impressed by how well state management has been integrated into
         | such extensible and scalable view layers.
        
       | listless wrote:
       | The code here is clean, well written and honestly not that much
       | more verbose than many of the framework ones. I also found it
       | simple to understand.
       | 
       | Would you need a "framework" when an app gets beyond TODO? I
       | think you would need to start refactoring your code to be more
       | framwork-like. But this is something we don't do, and I would say
       | would even be considered "anti-pattern".
        
         | mch82 wrote:
         | My bet is that as soon as someone popularizes a way to manage
         | state across a set of web components the pendulum will swing
         | back to the "Vanilla JS" approach. It's so nice to work on web
         | apps without having to install NodeJS, builders, cli tools, and
         | so on. And it encourages software engineers to learn the web
         | platform APIs instead of learning frameworks.
         | 
         | HTML and CSS are actually quite nice to work with, given modern
         | browser developer tools. Much simpler to work with when they
         | are literal files.
         | 
         | It wouldn't surprise me if people continue to compile other
         | languages to JavaScript or WASM though. It seems reasonable a
         | Java developer might like to work in Java or a Ruby developer
         | in Ruby instead of writing JavaScript. But I don't understand
         | how people feel confident writing web applications if they
         | don't take the time to understand CSS, HTML, or the browser
         | APIs.
        
       | mmcnl wrote:
       | How many people who are critical of the current state of JS
       | actually use it on a daily basis? Modern frameworks like React
       | and Vue don't exist to fill in the gap left by native JS, they
       | exist so that you write your application in a declarative way
       | where the view is rendered as a function of state. This relieves
       | the developer of keeping track of DOM state, as you only declare
       | the render function once, and after that you only need to manage
       | state.
       | 
       | If anything, modern frameworks tend to build as much upon the
       | native functionality that is available. This reduces bundle sizes
       | and increases performance. It's an abstraction on top of the
       | browser capabilities, not a clone.
       | 
       | Now, onto the code itself. The author claims it is "pretty
       | simple" to build "fairly complex things". He backs up the claim
       | by stating it took only 60 minutes to write this app.
       | 
       | First, I would be careful to claim things are easy or difficult.
       | This is very subjective, and phrased in the wrong way it can also
       | come across as arrogant.
       | 
       | Second, the app is not simple. Looking at the code the author
       | created his own DOM abstraction. The current abstraction is only
       | proven to work for a simple to do app.
       | 
       | Third, a to do app is not a "complex thing". Not even remotely.
       | 
       | It's a nice exercise, but the conclusion drawn by the author
       | aren't valid.
        
         | klabb3 wrote:
         | > React and Vue [...] exist so that you write your application
         | in a declarative way where the view is rendered as a function
         | of state
         | 
         | Exactly. To elaborate, here's the big, big caveat in a
         | miniature form:
         | 
         | https://github.com/1Marc/todomvc-vanillajs-2022/blob/854dd40...
         | 
         | Note that this clears and recreates the DOM on every action (eg
         | mark complete), and DOM ops are the most expensive ones. This
         | is a sound strategy for vanilla JS, because the alternative is
         | mutating the DOM and keeping it in sync which is error prone to
         | put it mildly.
         | 
         | I use frameworks very sparingly, and am always cautious with
         | deps. But a reactive UI/diff engine is non-negotiable for me.
        
       | brrrrrm wrote:
       | I wrote a video editor in vanilla JS
       | https://github.com/bwasti/mebm
        
       | skybrian wrote:
       | It would be a different demo, but this could be made fairly
       | modern with some lightweight tooling and dependencies:
       | 
       | - Use esbuild to bundle the app. - Now you can change the file
       | extension and switch to Typescript. (Esbuild doesn't check the
       | types, but VS Code will.) - Then change the file extension to tsx
       | and use Preact.
       | 
       | I'm writing a little app this way and it seems quite nice. I
       | don't think I'm missing anything?
        
         | 1marc wrote:
         | Agreed, esbuild is nice. And adding TypeScript at some type of
         | scale probably makes sense. Not sure where that line is, but in
         | this simple example I'm trying to avoid all external tools.
        
       | randomfool wrote:
       | Please do not re-implement HTML sanitization. Just replace that
       | escapeForHTML and innerHTML assignment with a later textContent
       | assignment. Please. Pretty please.
        
         | grabanski wrote:
         | That seems like a good improvement. Pull requests welcome!
        
           | grabanski wrote:
           | How does this look? https://github.com/1Marc/todomvc-
           | vanillajs-2022/commit/d38e5...
        
       | simooooo wrote:
        
       ___________________________________________________________________
       (page generated 2022-05-07 23:01 UTC)