Remix.run Logo
brokegrammer 3 days ago

I built my latest SaaS (https://clarohq.com) using HTMX, backed by Django. I really enjoy the process because HTMX allows reactivity using swaps and plain Javascript events instead of server side state management, useeffect, and API endpoints.

However, it's difficult to get things right. I spent way too much time on some basic features that I could have shipped quicker if I used React.

The issue with React though, is that you end up with a ton of dependencies, which makes your app harder to maintain in the long-term. For example, I have to use a third-party library called react-hook-form to build forms, when I can do the same thing using plain HTML and a few AlpineJS directives if I need dynamic fields.

I'm not sure if I'll ever build an app using HTMX again but we need more people to write about it so that we can nail down patterns for quickly building server rendered reactive UIs.

threatofrain 3 days ago | parent | next [-]

You only use the popular React form libraries when you want utmost control over your forms. Like as you type into a registration form you check off boxes for password requirements, and you only show errors after they’ve touched it once.

Otherwise vanilla forms are great in React. If you did this by hand in Vue or vanilla it would also be hell.

Also in terms of maintenance burden the top libraries in this space are massively popular. Most here would likely be making a great maintenance burden decision in offloading to well reputed teams and processes rather than in housing your own form and validation library.

brokegrammer 3 days ago | parent | next [-]

Sure, I could build forms with React only but I found controlled forms to have less performance when there are many fields. react-hook-forms uses uncontrolled forms with refs which has near native performance, so if I had to build that by hand it would be more tedious. AI makes this process easier, but it's still extra code that needs to be maintained and tested, when you can do the same for free if you stick with standard web tools.

jollyllama 2 days ago | parent | prev | next [-]

> If you did this by hand in Vue or vanilla it would also be hell.

It's really not. If you walk away from your project for 7 years, your vanilla JS will just load into the web browser and still behave the same. If you walk away from your React (or other NPM-based project) for the same amount of time, you won't be able to build all your dependencies from source without spending time updating everything. Going with something like HTMX or plain JS vastly reduces your maintenance overhead.

threatofrain 2 days ago | parent [-]

When people talk about maintenance burden they aren't talking about your scenario. A codebase where you walk away for 7 years and then come back? That's something people can do now for any project in any language. When people talk about maintenance burden they're talking about what tomorrow to the next few years is going to feel like for people who actively maintain projects.

So when you're actively maintaining something and you bring in a dependency, you're in some sense outsourcing some of that work, whether it's a colleague or an outside party maintaining that library. The specifics of who begins to matter. Is it the React team maintaining that part of the codebase? Is it lonely author in Kyiv? Or is it you?

So what is it like to be the colleague of someone who wrote their own Tanstack Forms and successfully or unsuccessfully integrated with Zod and the like? Or did they choose to write their own runtime type validator too? That's maintenance burden.

jollyllama 2 days ago | parent [-]

Active is a relative term. The modern frontend monoculture is built for a high churn codebase. Sure, seven years is extreme, but even for two years, there will be more issues if the cold project that I'm trying to load was made with the modern, npm-based frontend monoculture versus if it was all custom code.

a_subsystem 2 days ago | parent | prev [-]

>>> check off boxes for password requirements, and you only show errors after they’ve touched it once

I don’t get it. This is super easy w htmx.

zarzavat 3 days ago | parent | prev | next [-]

> For example, I have to use a third-party library called react-hook-form to build forms

Why? I've written a lot of React and I've never used this library. In fact, I rarely use any React-focused dependencies except a router, as you say every dependency has a cost especially on the client.

React works just fine without dependencies.

yladiz 2 days ago | parent [-]

Although you don’t necessarily need the hook, writing a large form with reasonable performance in React can be tricky, so I can understand why you would go with a hook for that case.

bookofcooks 3 days ago | parent | prev | next [-]

Exactly my idea.

This Github demo was pulled straight out of some work I was doing for the Admin of Prayershub (https://prayershub.com).

Working on this specific feature (the soundtrack uploader) though, I reguarly asked myself "what if I just used Svelte or SolidJS"?

Note, Prayershub uses a regular mix of HTMX and SolidJS, so I can pop-in SolidJS whenever I find convenient.

brokegrammer 3 days ago | parent [-]

I've been thinking about loading React or something similar for specific components but still not sure which method I'm going to use for that. How are you embedding SolidJS on specific pages? Or do you actually have a full build pipeline?

bookofcooks 2 days ago | parent | next [-]

It actually depends on the page. Some pages, I don't use the SolidJS JSX, just its plain-js state primitives.

For other page, I'll use full-blown SolidJS (with JSX and everything) for like a popup. Example: https://pasteboard.co/hY35xM7VbATG.png

Now, how I specifically embed SolidJS, its pretty simple, I have my entrypoint files for specific pages: assets/admin-edit-book.tsx assets/admin-edit-song.tsx assets/single-worship.tsx assets/worship-edit.tsx

Then I have a 30-line build script that invokes esbuild along with esbuild-plugin-solid (to compile JSX to plain-old html, no fancy virtual dom) to compile the scripts into javascript.

I can share the build script if you'd like. It helps that SolidJS is so self-contained that it makes such a setup trivial.

brokegrammer 2 days ago | parent [-]

Sure, the build script would be insightful. Removing the virtual dom sounds cool. I've been sleeping on SolidJS because I've always stuck with React after being disappointed by other frameworks. If it allows me to keep my server rendered pages, SolidJS might be what I've been looking for.

bookofcooks 2 days ago | parent [-]

Alright, let me know if you need any extra help.

https://gist.github.com/BookOfCooks/42181c4214442144c3e4d7e5...

pbowyer 2 days ago | parent | prev [-]

I do this with Vue in Symfony PHP apps. Depending on the scope I eitehr have a full build pipeline for the JS (preferred) or will include the files direct from a CDN and have in-HTML templates that are parsed on load.

For passing data into it I've used Inertia.js [0] and also my own data-in-page setup that's parsed and loaded into the Vue app. The app then writes the changes back out, usually into a hidden form input. The form on the page is then submitted as usual to the server, along with any other data that I need.

It's a great way for adding more complicated behaviour to an existing app.

0. https://inertiajs.com/

bloomca 2 days ago | parent | prev | next [-]

What kind of forms do you need? I honestly feel people think they have to use all sort of dependencies. There are some you definitely need, like the router or any state management (you can build both, but there is a decent amount of boilerplate and efficient hooks can be tricky).

But for forms I honestly would recommend to start with plain React and only abstract things you need in your project.

andrewstuart 2 days ago | parent | prev | next [-]

Don’t use a form library, use the machine - program the browser DOM forms API.

worble 3 days ago | parent | prev [-]

> I have to use a third-party library called react-hook-form to build forms

Regular form elements work just fine in React, all you need to do is interrupt the onInput and onSubmit handler and deal with the form data yourself. I've tried a handful of these form libraries and frankly they make everything way more complicated and painful than it needs to be.

bestest 2 days ago | parent [-]

That is fine as long as your forms are simple text inputs and buttons. Now plug in drag-and-drop and multiple file uploads and selects and checkboxes and radios and more of these various inputs you're in the world of pain.

I've recently, once again, gave native inputs a chance in a new project. It lasted as long as I've described in the first sentence. And I've been in the frontend world for 20 years. Trust me, you don't want complicated native forms.

And react-hook-form is just what you need (albeit it also is boilerplate-ish, so I always end up wrapping it up in a simpler and smarter hook and component).

edit: Same, in a sense, for HTMX. It's ok for simple things. But eventually you may end up trying to build a house with a fork. The fork in itself is not a bad tool, sure. But you also don't need a concrete mixer with your morning toast.