I say save yourself the trouble and just avoid all "modern" web development tooling. Avoid "frontend builds" at all costs (everything except for esbuild is insanely slow anyway). Most websites do not need npm for frontend (or backend). Most web applications are barely "applications" at all but rather mostly-static content with a few forms, tables, and/or menus.
I use vanilla html/css/js for frontend + golang for the backend. Modern JS (esp. modules) are very powerful. ESLint provides pretty good static checks for the frontend, and of course golang is statically typed so you get strong guarantees about your backend. Go builds extremely fast as a small self contained binary that can run on any OS and in a from scratch docker container. Go performance and tooling blows JS out of the water. And go has a powerful built-in templating engine for SSR which allows to to make your JS even leaner. Testing a change requires no more than refreshing the page. Debugging is super easy, barely an inconvenience since there are no build layers between anything encumbering developer velocity. Just add breakpoints directly to chrome devtools in the JS (or in VSCode for the golang) and step through.
Always start vanilla. Most of the time you won't need to be dependent on npm, you'll never break when some random maintainer becomes an activist, people will wonder why your site page loads are so snappy, and you'll live happily ever after.
Don’t get me wrong, I’m very unhappy with the state of today’s JS ecosystem but if you’re building a project of any complexity ditching absolutely everything that can help you along the way is not going to work out. Nor is it going to work out for the person taking over the code from you.
Every now and then I’ll be putting together a tiny landing page type thing and write it all in vanilla JS and it’s bliss. But as soon as I start dealing with non-trivial state you’d better believe I’m reaching for a framework.
Most people overuse frontend state. It seems like every new React programmer goes through a phase where they think that everything needs to be in state, especially things that never change.
Been there, done that.
I don't agree.
Go's native html/template and even pongo2 or quicktemplate etc have a big problem when it comes to conditional fragments of some text.
It's messy and you end up writing helper functions for pretty much everything.
Need a href aware navbar?
Custom function and macro time.
Bleh.
Performance is great, maintainability isn't.
I dislike graphql because it's too mich overhead.
RESTful is not good enough, only good for admin UI CRUD.
I moved to json rpc calls.
So I can have the best of both worlds.
However what I'd really like to have is a proper SSR component framework that is interactive or rather reactive.
If you're using JS modules and ESLint, you are using a frontend build. You can certainly go back to the days of jquery and vanilla CSS with none of the advantages of modern dependency management, transpilation and module loading, but if you try to do that at even a small company you are not going to last long. These tools exist for a reason, and most people who don't see the point of them were not around for the bad times before the existed.
I mean, you could do that, but as someone who has been doing this for a very long time, I would not recommend it. If your application is very simple and has very few dependencies it might work, though I think you'll have a lot of trouble managing your dependencies across multiple environments. You wouldn't distribute a C application without a Makefile, and you shouldn't distribute or deploy a frontend application without the equivalent dependency management and build orchestration. These tools exist not just to help one developer create and app that works, but to help teams manage code contribution and dependency management across environments.
> You wouldn't distribute a C application without a Makefile
And yet, SQLite does just that. They distribute as a single .c file. I wrote a moderately successful lcov replacement in python that I distribute as a single .py file so people can directly run it without needing pip (if desired). There's a time and a place for needing build systems, but as a minimalist I default to vanilla + no build system and that serves me very well the vast majority of the time.
> and you shouldn't distribute or deploy a frontend application without the equivalent dependency management and build orchestration
Why not? That's the other thing. What are all these dependencies you are talking about that need "managing"? Most web apps I've written have needed 1 dependency (bootstrap CSS). Maybe PIXI or ThreeJS if making something graphical. Include it in the html, boom done, no npm needed.
Take a look at this guy's blog and tell me that he needs to abandon vanilla and start using a frontend build system: https://ciechanow.ski/gps/
I use vanilla html/css/js for frontend + golang for the backend. Modern JS (esp. modules) are very powerful. ESLint provides pretty good static checks for the frontend, and of course golang is statically typed so you get strong guarantees about your backend. Go builds extremely fast as a small self contained binary that can run on any OS and in a from scratch docker container. Go performance and tooling blows JS out of the water. And go has a powerful built-in templating engine for SSR which allows to to make your JS even leaner. Testing a change requires no more than refreshing the page. Debugging is super easy, barely an inconvenience since there are no build layers between anything encumbering developer velocity. Just add breakpoints directly to chrome devtools in the JS (or in VSCode for the golang) and step through.
Always start vanilla. Most of the time you won't need to be dependent on npm, you'll never break when some random maintainer becomes an activist, people will wonder why your site page loads are so snappy, and you'll live happily ever after.