Ignore any recommendation of React, TypeScript, Vite, or Tailwind. Here are some recommendations that don't require NPM/Node.
Pick a "classless" CSS library from a site like CSSBed[1]. These are kind of like Bootstrap, except you don't need to write any CSS or apply any CSS classes in your HTML for them to work. No tooling necessary; just include a <link> tag in your HTML document. If you'd like to try something similar to this "Tailwind" hotness everyone keeps talking about, try Basscss[2]. Again, no tooling, just need a <link> tag.
Once you start needing to add interactivity to your site, htmx[3] is nice and decently simple. If you really want something React-like, Mithril.js[4] is very similar but much simpler.
I've been using htmx since the intercooler days, but I'm of the opinion that just using Next.js and treating React like simple HTML is much easier for starters.
Or Alpine, but not htmx. Learning all those attributes (30, not counting the HTML headers and the JS API and the CSS classes, and events like htmx:historyCacheMissError) is not as simple as some in HN make it out to be. Just look at the most basic example in the top here: https://htmx.org/docs/. Meanwhile Alpine is read much easier, and has half the amount of attributes (15): https://alpinejs.dev/. Also look at the interactive component example from React: https://reactjs.org/tutorial/tutorial.html#making-an-interac.... It looks easier if you don't hate JS.
Of course, I respect that some avoid JS with passion, but I don't buy that it's simpler. It's juss less javascript-y.
Unfortunately, "easier" does not always equal "simpler". Next.js/CRA is "easier" because it hides a lot of the complexity away from you. In my opinion, ignoring how it all works under the hood and just blindly accepting tools/clis because "it works" sets you up for confusion down the road. I've met several JS developers who don't know that JSX gets transformed to JavaScript function calls after a build step -- they just assume it's part of how browsers work at this point. And that is mindblowing to me.
Most of what OP needs can probably be achieved with a few HTML files and <script> tags. It will probably be a few more keystrokes than `npx create-next-app`, but the disconnect between the code he/she is writing and the final running application will be much smaller, and I think he/she will have a better understanding of what the heck is going on.
Fair point on htmx and Alpine; I have not given Alpine a shot yet, but it looks nice from the docs.
> I've met several JS developers who don't know that JSX gets transformed to JavaScript function calls after a build step -- they just assume it's part of how browsers work at this point. And that is mindblowing to me.
I believe you, and I've also met some like you described who came to our interviews indeed, but it's more like the failure of their mentors. I've also met back-end engineers, with a lot of experience, who couldn't write a simple HTTP service with C#, without using ASP.NET, nor open a simple DB connection without using EntityFramework APIs.
Understanding what's going on will be even harder if it's not your main field (back-end developer just trying to get front-end out of the way) and some magic there won't cause a lot of problems IMHO.
failure of their mentors? To an early point, but beyond that everyone who considers themselves a professional needs to sit down with a book or three and understand stuff. 'mentors' is a small excuse IMO.
This is a valid criticism of SSR and the complex mental model it requires to implement effectively, even with Next.js. You need a firm understanding of the HTTP request lifecycle and the serialization boundary. For a novice programmer starting with frontend dev, I would not recommend starting with Next for this reason (create-react-app would be better).
But for an experienced backend developer, the mental model of Next is no problem, and the flexibility of SSR will feel liberating. After a few weeks you might even put down the Flask!
If you want to use SSR on your pages, I'd recommend sampling some Next projects (just pick one of the examples and get it running locally). You might like what you find. And for closer integration with Python, I'm sure there are options for server-side rendering of JSX that you could use, although they'll all ultimately need to either wrap a JS runtime or emulate JSX compilation in Python. So you may as well just skip the middleman and go to straight to react, whether via a framework or otherwise.
If you don't want a heavy framework, or you just want basic CSR for some richer pages, you can accomplish a lot with just `react` and `esbuild`. Even SSR is just a matter of calling `ReactDOMServer.renderToPipeableStream()` and doesn't need a framework like Next. They're just nice because they take care of all the problems you'd end up solving in a robust deployment anyway.
As a non-js developer I found Alpine lacking. In the examples they use something like await axios get to get new content. I have no idea what any of those mean or why they have to there in that order with that syntax.
What does "hx-get" do? Does it replace the HTML from that url? Why is it on a div, does it happen on load or does it wait for an event? It's a study on its own:
Oh, apparently I can put hx-trigger="mouseup mousemove delay:500ms" there to make it explicit. I mean this thing has its own DSL, and IMHO, you are escaping from JS and jumping to another language, which you still have to learn and less people know of.
In alpine, it's explicit. You can say fetch, then replace something in your data, and use that thing in your x-html. You still need to learn some, but in my experience, much less to keep in mind than htmx.
OTOH, Next.js is even easier than Alpine to learn. You just create pages as js files and run the server. Yes, you need to run a BFF (back-end for front-end) but it's just that. The thing even updates in real-time. Only thing that can match this is Phoenix LiveView but I can't speak for it as I've just played with it and nothing more.
Yeah... I'm about as far to the other side of this as you can get.
It really looks like the x-html attribute you're complaining about is just using plain old javascript. It takes a statement that resolves to a string, and renders that.
The statement they provided happens to be pretty terrible for docs (I would have just used the built in fetch api, instead of the axios networking library - https://github.com/axios/axios), but it's plain old js regardless.
Your example is some custom fucking DSL that I have NO idea what it's doing. When does it run? how does it handle errors? What is the base url? What happens to the original text? How does it auth? What if I needed to post, or put, or delete? It's an entire fucking language I have to learn on top of the actual css/html/js knowledge required to understand this. In almost all cases, you're better off just learning "plain old javascript" since that skillset travels with you everywhere.
basically: DO NOT MAKE ME LEARN YOUR FUCKING DSL. It's wasted time and effort for me, and learning it provides absolutely zero benefits outside of your library. Further - it will fucking leak, and then you're right back at writing plain old js again, but now you have to understand the intimate details of the library implementing the dsl to tweak the right spots.
Even alpine turns me off a bit here (it's still a dsl, even if most of it reverts to plain old js) - but at least they're incredibly up front about the total time investment to learn the dsl (15 attrs, 6 props, 2 methods). HTMX is like 5 times the size (https://htmx.org/reference/), so I assume roughly 20 times the effort to learn the DSL.
I wrote an internal tools framework on top of htmx with a desire to make things easier for backend contributors, but ran into exactly this problem - even htmx isn't quite simple. What I would have likely done next is try to create jinja abstractions around htmx
Do you really suggest https://htmx.org/?
That thing has bold questions, like
> Why should only <a> and <form> be able to make HTTP requests?
And than you turn off your js in the browser and try to open a demo from the htmx. White screen of death. It doesnt even work without js. Why even bother to use it?
HTML is not perfect, but it is well tested, can work without js, also works with screenreader and you can create accessible web apps.
With htmx you can create something usable to some degree, but completely inaccessible, which may lead your company to be sued.
The reason is to avoid npm/node. And that's absolutely right -- I'm a backend engineer, and I've done Vue projects with npm, and npm is fantastic -- the quality and care that has gone into it is obvious; even the screen output is beautiful (compared e.g. to the mess that JVM developers make, who think of a shell as some weird thing that someone might need to use if their IDE is broken).
However. For the OP's question, a toolset for quick and easy frontend development for a backend engineer who doesn't spend much time doing front end, avoiding npm is definitely the way forwards. It introduces a HUGE amount of complexity to a project who's aim was simply: produce some HTML and CSS with the necessary javascript to make the UI work. If your typescript compiler or Vue/React transpiler or bundler isn't working quite right, it is completely non-obvious to a backend engineer who isn't familiar with npm what to change in package.json to fix it, or even how to go about debugging it.
Point taken; I admit I wrote that as a sort of frustration and reaction to the abundance of comments telling a newb at front-end developer to just take the deep dive and start installing a bunch of NPM packages / CLI tools. In my opinion, those tools hide amazing layers of complexity that become a problem as soon as you need to eject. I think any beginner at front-end development should realistically start by getting used to the bread 'n butter of HTML/CSS/Vanilla JS, things the browser already understands. Only once you start feeling the limitation of those tools should you start including libraries, and then maybe a package manager and view layer.
I think it just depends what you want to build. Once your UI reaches a certain level of complexity, the benefits of various tools begin to outweigh the cost.
If you know you're going to end up at that point because your designs include a high level of interactivity, you might as well use tools that will support your needs from the beginning--either that or revise the designs to be less ambitious.
Often newbies have a vision of what they want to build that matches the complexity/polish of established products--they're building Uber for X or Instagram for Y and so they want that same silky smooth UX. To achieve that, they are going to need a lot of packages and tools. The solution in that case isn't necessarily to convince them to build the whole thing in vanilla html/css/js instead, but to level with them about their expectations being unrealistic for where they're at.
> Once your UI reaches a certain level of complexity, the benefits of various tools begin to outweigh the cost.
What's that certain level of complexity? I have some heuristics I might use, but what I've noticed is that even discussion about where these product behavior thresholds are seems to be rare.
And "polish" and "silky smooth" don't seem like features that come automatically with any of the top frameworks either, nor things that are inherently difficult without them.
But the earlier comment was saying to avoid NPM/Next/React because of the challenges that arise when you want to eject and add complexity. However, not using NPM/Next/React also comes with challenges when you want to add complexity.
In my mind, the best advice for beginners is to just follow the mainstream. You'll get the best tutorials, best community support, easiest tooling, and least fragmentation. First time using a computer? Mac or Windows. First time programming? Javascript. Just want to do simple web dev? NPM and React. After you've got the basics down you can start exploring the niche stuff like Linux or Rust or Htmx.
Not only privacy, but also reliability in my experience. If you add in a CDN you now have a point of failure you have no control over that (Murphy's Law) fails at the most inopportune time. In all web frameworks it's pretty trivial to serve up static files with a future expiry date.
> a simple front end to which I can attach some new experiments for home brew coding
This thread is about engineers looking for a simple way to just create a UI. Pandering to niche neuroses about privacy by avoiding entirely mainstream technologies such as CDNs is out of scope!
You can think of it being a neuroses for yourself, but you don't have to label it as such for others.
It can be a perfectly reasonable concern in the life of others, while not in yours.
> This thread is about engineers looking for a simple way to just create a UI
The recommendation doesn't go against this. To create a UI, you'll have to host at least one HTML file. Potentially several, also images, stylesheets, javascripts, etc. One more to ditch the CDN doesn't add work to the process. Deploying one or two files isn't much of a difference.
While Mithril is interesting unless you are resume-building I'd avoid anything React-like until you are a small team and just go Vanilla JS with events, it can go a long way if you are a solo dev, especially if you have a backend experience and can write clear and simple code.
Can I ask a concrete question: say someone wants to render a table with data coming via an Ajax call to a JSON API. How should they do that with the tools you're suggesting? Use the native JS DOM API to synthesize table rows? (Just in case tone of voice doesn't come across, if that's the solution great, I'm not implicitly criticizing it in advance).
Yes, use Fetch API to retrieve the resources, and pass the resulting data to a function that uses the DOM APIs to create the table element + children. If you're not attaching event handlers to the elements, and if the data is properly sanitized, you can also use a combination of `innerHTML` + HTML written in template strings to dynamically create the markup.
Often people will see this and say "that doesn't scale!" Well, yeah, unless you start writing optimizations, at which point, you maybe created your own framework or view library and maybe you should start looking at something like Preact or Mithril.
Thanks, that's really helpful to me. In particular, I wanted to know whether creating a table dynamically from Ajax data was sufficient reason to start using Preact/Mithril, and you made it clear that in your opinion it's not.
Because if you wanted to make changes to the table, and your rendering mechanism is rewriting to innerHTML, it's going to nuke all the elements and create new ones (even those that don't need to be recreated).
On the other hand, DOM APIs can get expensive quickly especially if you're calling `document.createElement` repeatedly to create maybe 1000s of table rows.
So then you have to find ways to minimize the amount of DOM operations that must happen. Or like the rest of us, just pick up a JS library that already solved this problem.
Don't know if this is directly related but the last time I fetched 9,000 elements to a select list, my browser went HRNGHHHH (on an M1 Macbook Pro). (No, 9,000 elements in a select list was not intentional.)
I haven't given CSSBed or basscss a good try yet, but I do like tailwind enough to find it worth a build system. It doesn't require NPM/Node if you don't already use that; it has a standalone cli now[1].
> Ignore any recommendation of React, TypeScript, Vite, or Tailwind.
I mostly agree with the first three (with caveats about how interactive/app like you want to the result to be), but I totally disagree about Tailwind, the only exception being if all you want to do is throw up some <p>s and <hx> tags and have it look better than the default.
If you're going to do much layout at all, you're gonna need CSS. If you already need CSS, Tailwind isn't much more. It's basically just css properties expressed as classes in your html. If you know the CSS already, the Tailwind equivalent is in most cases guessable. If you don't know the CSS you need yet, you'll mostly have to learn it anyway unless you can copy/paste somebody's existing layout and have it be good enough for you. And again, once you know the CSS you need, the equivalent tailwind is easy. The benefit of Tailwind is that it puts markers/boundaries over the raw CSS that are easier to reason about, and having it right in the html (IMHO) makes it a lot simpler to work with.
You've mentioned in other comment:
> I wrote that in reaction to the comments telling a front-end newb to start installing a bunch of NPM packages and CLI tools. I don't think OP should be "afraid" of Tailwind, but for someone new to front-end development, I would not recommend you install a CLI tool or some funky CDN script just to style your HTML. Basscss is a good alternative since it's small and ships as a single plain CSS file.
I agree with what you've said, but again excepting Tailwind. A "compiled" version of TW can be used (very easily) from CDN[1] so there's no need to mess with npm or cli tools.
The Play CDN is the funky script I was referring to. It's not plain compiled CSS, it's a rather large (~100kb) JavaScript file that dynamically adds Tailwind classes to your document as you use them. It's also only intended for development purposes. I would recommend the CLI to OP over that, but my point was that it's largely unneeded for his use-case and more likely to cause confusion and more toolchain bloat for what are one-man homelab hobby projects.
I looked through all the available styles from cssbed and quite a few did not have any styling for links that have already been clicked on. This seems weird to me. Why would you get rid of this styling? Sure, purple sticks out, but it's useful information when navigating a webpage (particularly when I'm trying to click every link in the list of styles to see what they all look like!).
Great thread all around! Have been hearing raves about "htmx" and finally clicked the above link. Chagrined to find the tight DOM element coupling is done via data-set string attributes. Mapping to data store keys. Kind of the inevitable no-framework pattern I just assumed everyone was implementing ;)
I recently stood up my own website[1] and decided to write my own CSS, HTML, and JS in VS Code with the Live Server extension. It was exactly what I needed! It’s as if we’ve already been given all the tools we need for a nice, simple website.
Ignore advice that doesn't give a rationale. <-- Like that
Don't be afraid of Tailwind. It does not require NPM/Node. Utility CSS can be very helpful. If it works for you, tailwindcss is a great tool. By all means, give Basscss, etc a look as well.
Point taken. As mentioned in another comment, I wrote that in reaction to the comments telling a front-end newb to start installing a bunch of NPM packages and CLI tools.
I don't think OP should be "afraid" of Tailwind, but for someone new to front-end development, I would not recommend you install a CLI tool or some funky CDN script just to style your HTML. Basscss is a good alternative since it's small and ships as a single plain CSS file.
Pick a "classless" CSS library from a site like CSSBed[1]. These are kind of like Bootstrap, except you don't need to write any CSS or apply any CSS classes in your HTML for them to work. No tooling necessary; just include a <link> tag in your HTML document. If you'd like to try something similar to this "Tailwind" hotness everyone keeps talking about, try Basscss[2]. Again, no tooling, just need a <link> tag.
Once you start needing to add interactivity to your site, htmx[3] is nice and decently simple. If you really want something React-like, Mithril.js[4] is very similar but much simpler.
[1] https://www.cssbed.com/
[2] https://basscss.com/
[3] https://htmx.org/
[4] https://mithril.js.org/