[HN Gopher] Why Htmx Does Not Have a Build Step
       ___________________________________________________________________
        
       Why Htmx Does Not Have a Build Step
        
       Author : crbelaus
       Score  : 130 points
       Date   : 2023-08-25 18:08 UTC (4 hours ago)
        
 (HTM) web link (htmx.org)
 (TXT) w3m dump (htmx.org)
        
       | can3p wrote:
       | I think build systems are a very big reason for the mess
       | javascript is in nowadays.
       | 
       | - Typescript is very light from the code transformation point of
       | view. If anyone remembers the output of babel especially for
       | async/await + the way module imports are implemented generates a
       | really hard to read code and the "best practices" about hiding
       | the state make things a lot harder. Just think about the fact
       | that back in the days (tm) it was common to inspect the state of
       | the app and change it full lisp style and now the js console can
       | mostly be used for quick code tests and looking around when
       | execution is stopped at breakpoint and you can't see that much
       | anyway because of how the code is generated. - The whole babel
       | thing still feels like a madness to me. Yeah, you're getting some
       | new language features but for the price of non obvious code
       | transformation that makes you need source maps (and you need to
       | make them work and maintain that) and all the rest - Build step +
       | npm results in on controlled bloat of the js bundle. `npm install
       | <random-component>` may inflate you bundle by 500kb easily - And
       | with all that there is still a quite big trouble with requiring
       | necessary modules for the use on frontend. Just think that there
       | is still no simple way to require all css provided by a library
       | from npm
       | 
       | Another big problem on my opinion is the propagation of "write
       | once/use everywhere" approach. It works sometimes yeah, but you
       | need to sell your soul for that: you'll have to use something
       | like next.js and that implies that you're bound to use node.js
       | and then you either do all your development in node or have
       | another service doing stuff in the language of your choice and
       | then have a node service as a templating layer and then you need
       | containers and orchestration and so on which makes it a
       | technically challenging project for something that almost for
       | sure can be done in some trivial set of technologies if this
       | requirement had been dropped.
       | 
       | One could argue that we need a different approach with libraries
       | that acknowledges that frontend is distinct world and aims to
       | provide ready made components specifically for the web with an
       | easy setup and no/minimal dependencies. Maybe even with a vendor
       | folder like approach, since the won't be too much code anyway.
       | That should be enough for 99.999% of projects and the rest can
       | use the full scale approach and embrace complexity if they really
       | need it.
        
       | mamcx wrote:
       | Dependency hell IS hell.
       | 
       | I broke my dev machine because a bad application of reps + brew,
       | and triying to reinstall all was a messy mess.
       | 
       | Now I doing things with nix, and is almost good, yet I can't
       | escape dependency hell completely...
        
       | PaulHoule wrote:
       | I've seen Typescript programs break between versions of
       | Typescript more than I've seen happen in any other programming
       | language.
        
         | dgb23 wrote:
         | Upgrading JS dependencies is a nightmare. That includes
         | build/dev dependencies.
         | 
         | Part of my job is to maintain more than 50 web projects. That
         | includes streamlining, refactoring, upgrading, optimization
         | etc. Some of them are a decade old.
         | 
         | The most painful and time consuming part is dealing with JS
         | issues.
         | 
         | To anyone reading this: cut the fat and do it early. A little
         | bit of perceived "DX" is not worth writing "npm install".
         | 
         | Just write the code that needs to be written in a straight
         | forward manner. Lean on standards and don't get distracted by
         | fads. Prioritize stability.
         | 
         | Use libraries that do so as well.
        
         | klysm wrote:
         | Break meaning no longer type check or behaviorally not work?
        
         | teaearlgraycold wrote:
         | I personally haven't seen this. What kind of issues have you
         | seen?
        
           | Tade0 wrote:
           | The GP could be referring to situations where libraries have
           | strict bounds which versions of TypeScript they work with.
           | 
           | It's most visible in the Angular ecosystem, where both the
           | core library and additional stuff have such bounds.
           | 
           | For this reason Angular updates are often a terrible
           | experience for everyone involved.
        
             | teaearlgraycold wrote:
             | The only time I used Angular was when I had to because I
             | was working at Google. I'd never use it outside of Google
             | after that experience.
        
             | PaulHoule wrote:
             | I've had trouble where the build fails with various TS####
             | error messages, most of the time there was some change in
             | Typescript syntax. I guess if you use those bounds you have
             | less of those problems.
        
             | nraf wrote:
             | I've found Angular updates to be mostly painless since
             | they've automated most of the migrations using `ng update`.
             | 
             | That said, I do wait 2-3 months to give time for
             | dependencies to update.
        
           | beanjuiceII wrote:
           | I have not either, and i work with over 5 million lines of
           | typescript codebases.
        
         | [deleted]
        
         | ComputerGuru wrote:
         | Me too, but it's _usually_ because of the weird way TypeScript
         | was built as a thin veneer over JavaScript. Unlike a proper
         | strongly-type, statically-compiled language with a consistent
         | underlying framework where unsound behavior is adversarially
         | sought out and eliminated in the very design of the language
         | from the start, TypeScript started off as just bolting types on
         | to JavaScript and progressed to actually sanity checking the
         | code that a JavaScript runtime happily accepts.
         | 
         | I just ran into a case yesterday where some code ported from
         | JavaScript to TypeScript five or more years ago once more
         | wouldn't compile after upgrading from TypeScript 5.1.x to 5.2.x
         | and in this case it was a DOM event handler that for some
         | reason (probably copy-and-paste from another location in the
         | codebase) had a `return foo;` in a couple of the conditional
         | statements in the event handler callback. Now obviously event
         | handlers _don 't_ return anything, and anything they _do_
         | return is ignored (perfectly normal for JavaScript). TypeScript
         | didn 't error out on that, but it _did_ error out because not
         | all the code paths returned a value, so it was no longer able
         | to infer the return type.
         | 
         | A function (that returns a value) that can execute along some
         | logic path without returning a value is a soundness issue.
         | Granted it didn't actually cause any problems (as the return
         | value was always ignored in all cases, the solution was to just
         | remove the `return` statements that never should have been
         | there) but tsc incidentally caught something funky that never
         | should have been in the code in the first place.
         | 
         | So if you view incremental tsc releases as "tightening down all
         | the bolts" then I think its behavior makes sense. I wish tsc
         | caught everything from the start, but I'm only ever happy to
         | see that my code no longer compiles because it means that
         | something tsc * _wrongly_ * accepted before is now being caught
         | - which usually means that potentially errant runtime behavior
         | has been identified and this is a chance for me to correct it.
         | Which is, after all, the whole point of turning JavaScript into
         | a compiled language - so I can catch errors (or at least as
         | many as the TypeScript language is empowered to and the
         | TypeScript compiler is smart enough to) at compile-time rather
         | than at run-time.
         | 
         | (But I'm not primarily a web developer, I hate loosely-typed
         | languages, I absolutely abhor runtime errors, and I think any
         | soundness holes in a language should be treated alarm bells
         | left and right, so perhaps my opinion is not actually
         | reflective of the average webdev.)
        
       | simonw wrote:
       | I liked Julia Evans' take on this:
       | https://jvns.ca/blog/2023/02/16/writing-javascript-without-a...
       | 
       | """ My goal is that if I have a site that I made 3 or 5 years
       | ago, I'd like to be able to, in 20 minutes:
       | 
       | - get the source from github on a new computer
       | 
       | - make some changes
       | 
       | - put it on the internet """
       | 
       | Front-end build scripts make sense for projects that are
       | constantly developed by a team that is actively ready to
       | incrementally fix any problems that come up.
       | 
       | For sites that only get maintained every year or so (and I have
       | plenty of those myself) my experience is that they often cause
       | more problems than they solve.
       | 
       | I also found that I started really enjoying JavaScript
       | development again once I gave myself permission to ignore the
       | npm/webpack/etc script world entirely and just write regular code
       | that runs in browsers!
        
         | em-bee wrote:
         | exactly this. i am just in the process of upgrading the
         | framework of a site that has been built this way. the thing is
         | that the default tools all push towards using buildtools,
         | bundlers and transpilers. so i had to dig a little bit until
         | figured out how to do it without.
         | 
         | in the process i asked myself why go through the trouble and
         | not just use the build tools like everyone else. and i came
         | pretty much to the same answer. when i need to make some
         | changes to the site in a few years, i do not want to be stuck
         | with having to figure out how to get 5 year old build tools
         | working before i can even start working on the site.
         | 
         | the current site, btw was build in 2016, and it still works,
         | and i was able to dive in with adding new features without
         | delay. the upgrade of the framework is optional, because i want
         | to take advantage of new features not because the site would
         | have stopped working otherwise.
        
         | alexpetros wrote:
         | I can't believe I forgot about this! I love Julia's writing, I
         | cited a different blog post of hers in this piece.
        
         | Raed667 wrote:
         | I don't understand this issue.
         | 
         | With a proper `package-lock` and `nvm` i picked up 3 or 4 year-
         | old projects, installed everything with one `npm install`, made
         | my changes and never faced a problem.
         | 
         | Edit: I remember facing one issue with `node-gyp` but that was
         | just a poor choice of packages that were trying to be too
         | native.
        
           | madacol wrote:
           | > `nvm`
           | 
           | That's mostly why!, you need to have installed something. If
           | you don't use a build step you don't even need nodejs, your
           | browser is your only dependency.
        
           | cxr wrote:
           | Experiences vary wildly.
           | 
           | > With a proper `package.lock`
           | 
           | I've never heard of package.lock. Are you as familiar with
           | the subject as the general tone of your comment implies?
        
             | spankalee wrote:
             | How have you never heard of a package lock, yet are
             | criticizing other people's knowledge and tone?
        
               | pc86 wrote:
               | They were being pedantic, in that `package-lock` is a
               | thing, and `package.lock` (which is the comment
               | originally said) doesn't. Because apparently a typo
               | invalidates whatever experience you have.
        
               | cxr wrote:
               | You seem to have missed that my comment was a _response_
               | to pedantry. It was not, in itself, an attempt at
               | pedantry, let alone pedantry unprovoked.
               | 
               | If someone writes a comment intended to come across as
               | knowledgeable about something (NB: in service of trying
               | to downplay the experience of others, including the
               | person they are responding to), but their self-report
               | gets something as wrong as referring to package-lock.json
               | as "package.lock", which is in the ballpark, but far
               | enough off to be weird, then it raises questions about
               | just how much experience they actually have with that
               | thing (including and especially relative to the person
               | they were trying to contradict).
        
             | Raed667 wrote:
             | My bad I meant `package-lock`, updated for clarity.
             | 
             | > Especially when the old project in question is not yours
             | 
             | Then it falls out of the stated scope of "updating my small
             | website once every 5 years or so"
        
           | megaman821 wrote:
           | To counterbalance that anecdote, I have never picked up a
           | JavaScript project more than a year old and not have to mess
           | with the build system or package versions in order to deploy
           | some small update.
        
           | dpe82 wrote:
           | > Edit: I remember facing one issue with `node-gyp` but that
           | was just a poor choice of packages that were trying to be too
           | native.
           | 
           | Bingo.
        
           | arcbyte wrote:
           | I just picked up a project after 2 years. When i left it,
           | eveything worked fine. Npm run and it spun right up.
           | 
           | Today, nothing works, module resolution problems everywhere.
           | It's going to take me days of fixing the build system now
           | just to get the initial compile working again.
           | 
           | Node is a disaster.
        
           | o_m wrote:
           | Your host might eventually drop the Node version you are
           | running on, and then the house of cards come crashing down.
           | You might have a dependency that doesn't support the new Node
           | version you need to run.
        
         | flashgordon wrote:
         | This. I very grudgingly learnt nextjs to do "modern" JS
         | development. Don't get me wrong it isn't a bad framework but I
         | think I spent most of my time figuring out how 3p components
         | worked, or how to setup build system parts or write new plugins
         | or upgrading other dependencies - this even if I came back
         | after say a 3 month hiatus. My layouts rarely changes. Server
         | side rendering is a whole other pain. If you are like me and
         | want to server side NOT in node you are sol! I was lamenting
         | the other day that I just want to do Fe in typescript (on the
         | browser only for fe logic) but have layouts etc just server
         | side rendered.
         | 
         | I was very delighted to find htmx solves that problem for me!
        
       | ComputerGuru wrote:
       | I agree with the main points in the post and certainly understand
       | how they could push one in the direction that htmx has taken, but
       | for me (and I posted a long comment along these lines as a reply
       | in this thread elsewhere) the benefit of TypeScript isn't just
       | the type safety but also that it forces you to explicitly provide
       | more strongly-structured, parseable context info (regarding your
       | intent in the codebase) that can be used to further empower
       | static analysis tools (whether it's the TypeScript compiler or
       | various linters a la eslint and co) to pick up on discrepancies
       | between what the code is supposed to do and what the code does.
       | 
       | I view JS as a particularly unreliable language to build solid
       | (as in dependable, consistent, coherent, and sound) projects in,
       | and the various build tools are just ways to at least partially
       | overcome those inherent shortcomings of the language. Transpiling
       | from ESNext to ES5, merging disparate source components, etc are
       | all just icing on the cake and not the real reason to use
       | TypeScript (though I am surprised that the article talked about
       | its ECMAScript version restrictions caused by IE11 support but
       | _didn 't_ talk about how w/ TypeScript you can use language-level
       | (not library-level) features such as the spread operator, for ...
       | of, async/await, etc. and have them automatically
       | converted/transpiled to functional equivalents that work on ES5
       | browsers).
       | 
       | Just look at how the various @typescript-eslint/* packages can
       | supplant basic eslint rules, replacing them with more precise
       | variants1 by using the extra information provided by the
       | TypeScript AST instead of just the info surfaced by the
       | JavaScript AST.
       | 
       | 1 Let alone the existence of the hundreds of additional lints
       | that are only possible for TypeScript codebases.
        
         | jononomo wrote:
         | I think the goal is to never have to use or think about
         | Javascript again.
        
       | NelsonMinar wrote:
       | I love this, particularly its clear-eyed summary of some of the
       | tradeoffs. Gonna be honest: build systems have completely robbed
       | the joy from writing simple frontend hacks for me. I no longer
       | use them, which means I just can't use a whole lot of Javascript
       | frameworks and libaries. Oh well.
        
       | spankalee wrote:
       | Compilers should be optional, in a two senses of the word:
       | 
       | 1. Even if you use a language like TypeScript in your library,
       | your users shouldn't have to. Provide types to them, even provide
       | features like decorators, but have first-class and ergonomic ways
       | for plain JS users to accomplish the same task.
       | 
       | 2. Frameworks don't need compilers. All the reasons those that do
       | claim to have them: especially performance, ergonomics, are
       | disproven as requirement by libraries that meet or exceed them on
       | those axes. You especially don't need to fork JS and HTML, and
       | doing so fragments the web dev ecosystem, and causes tool
       | friction, for very little gain. You can offer a compiler, but it
       | should be an optional optimizer.
       | 
       | However, even as compilers should be optional, I also think they
       | should be possible. If users want TypeScript to check their work,
       | and especially if they're in large teams and organizations where
       | extra checks help collaboration, your approach shouldn't prevent
       | it.
       | 
       | And if you're doing things in a language without traditionally
       | good static analysis tools, like HTML, you should try to provide
       | them, otherwise your approach really doesn't scale due to ever-
       | increasing fragility as your code base and team size grows.
        
       | meowtimemania wrote:
       | I just threw away an admin site written with trpc+react and
       | rewrote it with htmx. Deleting so much code felt glorious.
       | Everything feels more simple and as a result adding features is
       | so much easier.
        
       | max_ wrote:
       | I was recommending htmx to some of my friends and they asked me
       | "What does it add?"
       | 
       | I told them that it's value proposition was not that it "added"
       | anything but that it "eliminated" things, like build systems,
       | configs, and the need to use js frameworks in incidences where
       | it's an overkill (which in my experience is majority of the
       | cases)
       | 
       | HTMX is a good example/manifestation of Nassim Taleb's "Via
       | Negative" heuristic i.e some systems can improved simply by the
       | removal of components that are dangerous, ineffective or cause
       | friction. As opposed to trying to improve systems by trying to
       | add components that we think will make a system better. [0]
       | 
       | A lot of technology is focused on improvement by adding, but I
       | think we should start thinking more in this paradigm of
       | improvement by subtracting -- subtraction complexity that makes
       | systems more difficult to maintain & build upon.
       | 
       | [0]: https://coffeeandjunk.com/via-negativa/
        
         | jmull wrote:
         | Well... there still has to be a reason to use htmx, or else why
         | not cut it too?
        
           | xctr94 wrote:
           | Needlessly snarky... it adds a lot of value if you want to
           | enhance HTML with dynamic behaviors that would be cumbersome
           | to write in plain JavaScript.
        
           | dventimi wrote:
           | Go ahead. Cut out htmx as well if you don't need incremental
           | updates without having to write JavaScript.
        
         | dunk010 wrote:
         | Reminds me of this:
         | https://programmingisterrible.com/post/139222674273/write-co...
         | 
         | "Write code that is easy to delete, not easy to extend."
        
         | yawaramin wrote:
         | "Perfection is achieved, not when there is nothing more to add,
         | but when there is nothing left to take away."
         | 
         | -- Antoine de Saint-Exupery
        
           | cdcarter wrote:
           | "do more and more with less and less until eventually you can
           | do everything with nothing" - R Buckminster Fuller
        
       | pictur wrote:
       | The answer is simple: it offers simple things as a simple
       | library. I really liked the effort to explain this so long. You
       | shouldn't even be satisfied with that, my friend. I'm looking
       | forward to the htmx nutshell book. you can write it.
        
       | bingemaker wrote:
       | > It's certainly not true for Python, or Java, or C
       | 
       | As far as the C code that I've seen from the past (early 2000s),
       | they do compile pretty fine even today. I doubt if "C" belongs
       | there.
        
         | torstenvl wrote:
         | This was a bizarre comment in the OP article, with an even more
         | bizarre reasoning: they "all have versioning mechanisms where
         | opting for new language features will force you off of
         | deprecated APIs"
         | 
         | C code from 1999 will, unless written by a literal psychic, not
         | have "opt[ed] for new language features" that arose in the
         | interim.
        
         | tedunangst wrote:
         | I think gets() was the only function removed from C11? That
         | complaint seemed really odd.
        
         | dvdkon wrote:
         | I've had lots of old C code refuse to compile on new compilers
         | out-of-the-box, not to mention that you'll likely need to track
         | down old versions of dependencies as well. Sure, you can always
         | get it all to compile with no changes to the code, but the
         | process can be arduous and the result can basically have its
         | own OS's worth in libraries attached to it (not that modern
         | languages are any better here...).
        
       | semiquaver wrote:
       | Crossing my fingers that the proposal for allowing (browser-
       | ignored) type annotations in javascript progresses:
       | https://tc39.es/proposal-type-annotations/
       | 
       | Between that, HTTP2/3 and ES modules many of the downsides for
       | building apps with no compile step are almost completely
       | mitigated.
        
         | benatkin wrote:
         | Wouldn't that conflict with possible future optional static
         | typing? It's only Stage 1. I'm hoping it doesn't make it in its
         | current form. Some good discussion in the issues, though:
         | https://github.com/tc39/proposal-type-annotations/issues
        
           | Someone1234 wrote:
           | Can you explain why the two proposals would "conflict?" Seems
           | like they're proposing the same thing to me.
        
             | benatkin wrote:
             | It would be hard to separate ignored ones from ones that
             | would use a possible future optional static typing system.
             | They would possibly have to use a different, uglier syntax.
        
               | Someone1234 wrote:
               | I'm not sure I follow. Both proposals are suggesting that
               | browser's engines ignore the syntax completely to allow
               | some other, external, process to check them.
               | 
               | They use slightly different wording but are describing
               | the same basic idea: This syntax will be ignored entirely
               | and then optional/other process can use this area for
               | whatever.
        
         | nwienert wrote:
         | Does http2 solve waterfall imports? Also wouldn't tree shaking
         | still be unsolved? What about minification?
         | 
         | IMO build step woes are really overstated, my build step has
         | linting, type checking, optimization, bundle analysis size diff
         | checks, enables JSX, and is basically necessary for development
         | anyway as you get hot reloading, compiler-added features for
         | better debugging, etc.
        
           | ryncewynd wrote:
           | Care to share your build set up? I'd very much appreciate it
           | 
           | I haven't done js since jquery days, but keen to get into
           | modern js development
        
             | nwienert wrote:
             | I maintain Tamagui, so the tamagui starter kit basically is
             | it, try `npm create tamagui`
        
           | mixedCase wrote:
           | >Does http2 solve waterfall imports?
           | 
           | It used to, but browsers ruined it because they didn't want
           | to help improve caching support
        
       | ikekkdcjkfke wrote:
       | I remember going from just having to hit F5 to waiting for a
       | "hot" reload, angular js -> angular 2. Sad times
        
         | peferron wrote:
         | I like hot module reloads more than F5 since it preserves the
         | state of the page. I don't use Angular though, but with Vite +
         | React it's extremely quick.
        
       | yellow_lead wrote:
       | I tried to use htmx but the client side templates extension
       | (allowing you to transform json into html client side using a
       | template) doesn't support json arrays.
       | 
       | Maybe I don't understand the right way of doing things with htmx,
       | but returning large amounts of html seemed like it's a waste of
       | bandwidth to me. That said, I appreciate htmx not having a build
       | step. Even tailwind gets annoying to me.
        
         | nisegami wrote:
         | It's not surprising that HTMX didn't allow you to do that
         | because that's pretty explicitly not what it wants to be. HTMX
         | is all about sending HTML over the wire, not JSON. If your
         | HTML/JSON is gzipped, it shouldn't be significantly different
         | in terms of bandwidth. Plus, you're not bundling nearly as much
         | javascript with your site compared to a heavy client side
         | framework, not to mention savings from avoiding processing more
         | than just the DOM update on the client.
        
         | loloquwowndueo wrote:
         | Returning partial HTML from endpoints _is_ the whole point of
         | htmx. If your endpoint returns json and you're trying to
         | convert that to HTML to use with htmx, don't bother - just use
         | another "traditional" Js framework.
         | 
         | I highly recommend the "building hypermedia systems" book (free
         | at https://hypermedia.systems/) so you can understand the HTML/
         | hypermedia architecture of which htmx is a key component and
         | how it's meant to be used.
        
           | yellow_lead wrote:
           | Thanks, will take a look at the book. Your points make sense,
           | but having an extension dedicated to this made me think
           | returning JSON may be ok.
        
             | loloquwowndueo wrote:
             | If you have an endpoint that returns json and you can't
             | change for legacy, historical, compliance reasons, it might
             | make some sense to integrate with an application that uses
             | htmx the way it was intended and only needs that one weird
             | legacy endpoint returning json to be converted to HTML
             | client side. That sounds like the use case for that
             | extension - the other explanation is someone wanting to
             | jump on the htmx bandwagon without understanding the
             | philosophy, and so trying to keep returning json,
             | converting to HTML on the client and then trying to
             | shoehorn this into a hypermedia architecture :)
        
         | dpe82 wrote:
         | You may be surprised how well HTML compresses.
        
         | rakoo wrote:
         | > large amounts of html
         | 
         | It only sends large amounts of html if there is a lot of data,
         | and if there is a lot of data it will send large amounts of
         | JSON. html in itself doesn't add much, it's the data that makes
         | the bulk of the content
        
         | googlryas wrote:
         | Almost all http clients send Accept-Encoding headers that will
         | significantly shrink the response. Try just gzipping an example
         | html response to get an idea of how good it will be.
        
           | yellow_lead wrote:
           | Makes sense, thanks.
        
       ___________________________________________________________________
       (page generated 2023-08-25 23:02 UTC)