Skip to content

Commit c069f20

Browse files
committed
clean up the formatting for the gumroad essay
1 parent 42e51a1 commit c069f20

File tree

3 files changed

+107
-31
lines changed

3 files changed

+107
-31
lines changed

www/content/essays/_index.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ page_template = "essay.html"
2525
* [The API Churn/Security Trade-off](https://intercoolerjs.org/2016/02/17/api-churn-vs-security.html)
2626
* [Does Hypermedia Scale?](@/essays/does-hypermedia-scale.md)
2727
* [SPA Alternative](@/essays/spa-alternative.md)
28-
* [htmx sucks](@/essays/htmx-sucks.md)
2928

3029
### Building Hypermedia Applications
3130
* [A Real World React to htmx Port](@/essays/a-real-world-react-to-htmx-port.md)
@@ -50,6 +49,10 @@ page_template = "essay.html"
5049
* [Is htmx Just Another JavaScript Framework?](@/essays/is-htmx-another-javascript-framework.md)
5150
* [htmx Implementation Deep Dive (Video)](https://www.youtube.com/watch?v=javGxN-h9VQ)
5251

52+
### On The Other Hand...
53+
* [htmx sucks](@/essays/htmx-sucks.md)
54+
* [Why Gumroad Didn't Choose htmx](@/essays/why-gumroad-didnt-choose-htmx.md)
55+
5356
### Hypermedia History
5457

5558
* [A File Structure For The Complex, The Changing and the Indeterminate (Ted Nelson, 1965)](https://dl.acm.org/doi/pdf/10.1145/800197.806036)

www/content/essays/why-gumroad-didnt-choose-htmx.md

Lines changed: 95 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,121 @@ author = ["Sahil Lavingia"]
77
tag = ["posts"]
88
+++
99

10-
At Gumroad, we recently embarked on a new project called [Helper](https://helper.ai). As the CEO, I was initially quite optimistic about using [htmx](https://htmx.org) for this project, even though some team members were less enthusiastic. My optimism stemmed from previous experiences with React, which often felt like overkill for our needs. I thought htmx could be a good solution to keep our front-end super light.
10+
At Gumroad, we recently embarked on a new project called [Helper](https://helper.ai). As the CEO, I was initially quite
11+
optimistic about using [htmx](https://htmx.org) for this project, even though some team members were less enthusiastic.
1112

12-
![Gumroad Red](/img/gumroad-red.jpeg)
13+
My optimism stemmed from previous experiences with React, which often felt like overkill for our needs. I thought htmx
14+
could be a good solution to keep our front-end super light.
15+
16+
<figure>
17+
<a href="/img/gumroad-red.jpeg" target="_blank">
18+
<img alt="Gumroad Red" src="/img/gumroad-red.jpeg" style="width: 100%">
19+
</a>
20+
<figcaption>Source with htmx - Click Image To View</figcaption>
21+
</figure>
1322

1423
In fact, I shared this sentiment with our team in Slack:
1524

1625
> "https://htmx.org/ may be a way of adding simple interactions to start"
1726
1827
And initially, it seemed promising! As one of our engineers at Gumroad eloquently put it:
1928

20-
> "HTMX is (officially) a meme to make fun of how overly complicated the JS landscape has gotten - much like tailwind is just a different syntax for inline CSS, HTMX is a different syntax for inline JS."
29+
> "HTMX is (officially) a meme to make fun of how overly complicated the JS landscape has gotten - much like tailwind is
30+
> just a different syntax for inline CSS, HTMX is a different syntax for inline JS."
2131
22-
However, unlike Tailwind, which has found its place in our toolkit, htmx didn't scale for our purposes and didn't lead to the best user experience for our customers–at least for our use case.
32+
However, unlike Tailwind, which has found its place in our toolkit, htmx didn't scale for our purposes and didn't lead
33+
to the best user experience for our customers–at least for our use case.
2334

2435
Here's why:
2536

26-
1. **Intuition and Developer Experience**: While it would have been possible to do the right thing in htmx, we found it much more intuitive and fun to get everything working with Next.js. The development process felt natural with Next.js, whereas with htmx, it often felt unnatural and forced. For example, when building complex forms with dynamic validation and conditional fields, we found ourselves writing convoluted server-side logic to handle what would be straightforward client-side operations in React.
27-
28-
2. **UX Limitations**: htmx ended up pushing our app towards a Rails/CRUD approach, which led to a really poor (or at least, boring and generic) user experience by default. We found ourselves constantly fighting against this tendency, which was counterproductive. For instance, implementing a drag-and-drop interface for our workflow builder proved to be a significant challenge with htmx, requiring workarounds that felt clunky compared to the smooth experience we could achieve with React libraries.
29-
30-
3. **AI and Tooling Support**: It's worth noting that AI tools are intimately familiar with Next.js and not so much with htmx, due to the lack of open-source training data. This is similar to the issue Rails faces. While not a dealbreaker, it did impact our development speed and the ease of finding solutions to problems. When we encountered issues, the wealth of resources available for React/Next.js made troubleshooting much faster.
31-
32-
4. **Scalability Concerns**: As our project grew in complexity, we found htmx struggling to keep up with our needs. The simplicity that initially attracted us began to feel limiting as we tried to implement more sophisticated interactions and state management. For example, as we added features like real-time collaboration and complex data visualization, managing state across multiple components became increasingly difficult with htmx's server-centric approach.
33-
34-
5. **Community and Ecosystem**: The React/Next.js ecosystem is vast and mature, offering solutions to almost any problem we encountered. With htmx, we often found ourselves reinventing the wheel or compromising on functionality. This became particularly evident when we needed to integrate third-party services and libraries, which often had React bindings but no htmx equivalents.
35-
36-
![Gumroad Green](/img/gumroad-green.jpeg)
37-
38-
Ultimately, we ended up moving to React/Next.js, which has been a really great fit for building the complex UX we've been looking for. We're happy with this decision–for now. It's allowed us to move faster, create more engaging user experiences, and leverage a wealth of existing tools and libraries.
39-
40-
![Gumroad Helper Before After](/img/gumroad-helper-before-after.png)
41-
42-
This experience has reinforced a valuable lesson: while it's important to consider lightweight alternatives, it's equally crucial to choose technologies that can grow with your project and support your long-term vision. For Helper, React and Next.js have proven to be that choice.
37+
1. **Intuition and Developer Experience**: While it would have been possible to do the right thing in htmx, we found it
38+
much more intuitive and fun to get everything working with Next.js. The development process felt natural with
39+
Next.js, whereas with htmx, it often felt unnatural and forced. For example, when building complex forms with dynamic
40+
validation and conditional fields, we found ourselves writing convoluted server-side logic to handle what would be
41+
straightforward client-side operations in React.
42+
43+
2. **UX Limitations**: htmx ended up pushing our app towards a Rails/CRUD approach, which led to a really poor (or at
44+
least, boring and generic) user experience by default. We found ourselves constantly fighting against this tendency,
45+
which was counterproductive. For instance, implementing a drag-and-drop interface for our workflow builder proved to
46+
be a significant challenge with htmx, requiring workarounds that felt clunky compared to the smooth experience we
47+
could achieve with React libraries.
48+
49+
3. **AI and Tooling Support**: It's worth noting that AI tools are intimately familiar with Next.js and not so much with
50+
htmx, due to the lack of open-source training data. This is similar to the issue Rails faces. While not a
51+
dealbreaker, it did impact our development speed and the ease of finding solutions to problems. When we encountered
52+
issues, the wealth of resources available for React/Next.js made troubleshooting much faster.
53+
54+
4. **Scalability Concerns**: As our project grew in complexity, we found htmx struggling to keep up with our needs. The
55+
simplicity that initially attracted us began to feel limiting as we tried to implement more sophisticated
56+
interactions and state management. For example, as we added features like real-time collaboration and complex data
57+
visualization, managing state across multiple components became increasingly difficult with htmx's server-centric
58+
approach.
59+
60+
5. **Community and Ecosystem**: The React/Next.js ecosystem is vast and mature, offering solutions to almost any problem
61+
we encountered. With htmx, we often found ourselves reinventing the wheel or compromising on functionality. This
62+
became particularly evident when we needed to integrate third-party services and libraries, which often had React
63+
bindings but no htmx equivalents.
64+
65+
<figure>
66+
<a href="/img/gumroad-green.jpeg" target="_blank">
67+
<img alt="Gumroad Green" src="/img/gumroad-green.jpeg" style="width: 100%">
68+
</a>
69+
<figcaption>Source with NextJS - Click Image To View</figcaption>
70+
</figure>
71+
72+
Ultimately, we ended up moving to React/Next.js, which has been a really great fit for building the complex UX we've
73+
been looking for. We're happy with this decision–for now. It's allowed us to move faster, create more engaging user
74+
experiences, and leverage a wealth of existing tools and libraries.
75+
76+
<figure>
77+
<a href="/img/gumroad-helper-before-after.png" target="_blank">
78+
<img alt="Gumroad Helper Before After" src="/img/gumroad-helper-before-after.png" style="width: 100%">
79+
</a>
80+
<figcaption>Gumroad Helper Before & After - Click Image To View</figcaption>
81+
</figure>
82+
83+
84+
This experience has reinforced a valuable lesson: while it's important to consider lightweight alternatives, it's
85+
equally crucial to choose technologies that can grow with your project and support your long-term vision. For Helper,
86+
React and Next.js have proven to be that choice.
4387

4488
Since we've moved there, we've been able to seriously upgrade our app's user experience for our core customers.
4589

46-
1. **Drag-and-Drop Functionality**: One of the key features of our workflow builder is the ability to reorder steps through drag-and-drop. While it's possible to implement drag-and-drop with htmx, we found that the available solutions felt clunky and required significant custom JavaScript. In contrast, React ecosystem offers libraries like react-beautiful-dnd that provide smooth, accessible drag-and-drop with minimal setup.
90+
1. **Drag-and-Drop Functionality**: One of the key features of our workflow builder is the ability to reorder steps
91+
through drag-and-drop. While it's possible to implement drag-and-drop with htmx, we found that the available
92+
solutions felt clunky and required significant custom JavaScript. In contrast, React ecosystem offers libraries like
93+
react-beautiful-dnd that provide smooth, accessible drag-and-drop with minimal setup.
4794

48-
2. **Complex State Management**: Each workflow step has its own set of configurations and conditional logic. As users edit these, we need to update the UI in real-time to reflect changes and their implications on other steps. With htmx, this would require numerous server roundtrips or complex client-side state management that goes against htmx's server-centric philosophy. React's state management solutions (like useState or more advanced options like Redux) made this much more straightforward.
95+
2. **Complex State Management**: Each workflow step has its own set of configurations and conditional logic. As users
96+
edit these, we need to update the UI in real-time to reflect changes and their implications on other steps. With
97+
htmx, this would require numerous server roundtrips or complex client-side state management that goes against htmx's
98+
server-centric philosophy. React's state management solutions (like useState or more advanced options like Redux)
99+
made this much more straightforward.
49100

50-
3. **Dynamic Form Generation**: The configuration for each step type is different and can change based on user input. Generating these dynamic forms and handling their state was more intuitive with React's component model. With htmx, we found ourselves writing more complex server-side logic to generate and validate these forms.
101+
3. **Dynamic Form Generation**: The configuration for each step type is different and can change based on user input.
102+
Generating these dynamic forms and handling their state was more intuitive with React's component model. With htmx,
103+
we found ourselves writing more complex server-side logic to generate and validate these forms.
51104

52-
4. **Real-time Collaboration**: While not visible in this screenshot, we implemented features allowing multiple users to edit a workflow simultaneously. Implementing this with WebSockets and React was relatively straightforward, whereas with htmx, it would have required more complex server-side logic and custom JavaScript to handle real-time updates.
105+
4. **Real-time Collaboration**: While not visible in this screenshot, we implemented features allowing multiple users to
106+
edit a workflow simultaneously. Implementing this with WebSockets and React was relatively straightforward, whereas
107+
with htmx, it would have required more complex server-side logic and custom JavaScript to handle real-time updates.
53108

54-
5. **Performance Optimization**: As workflows grew larger and more complex, we needed fine-grained control over rendering optimizations. React's virtual DOM and hooks like useMemo and useCallback allowed us to optimize performance in ways that weren't as readily available or intuitive with htmx.
109+
5. **Performance Optimization**: As workflows grew larger and more complex, we needed fine-grained control over
110+
rendering optimizations. React's virtual DOM and hooks like useMemo and useCallback allowed us to optimize
111+
performance in ways that weren't as readily available or intuitive with htmx.
55112

56-
It's important to note that while these challenges aren't insurmountable with htmx, we found that addressing them often led us away from htmx's strengths and towards solutions that felt more natural in a JavaScript-heavy environment. This realization was a key factor in our decision to switch to React and Next.js.
113+
It's important to note that while these challenges aren't insurmountable with htmx, we found that addressing them often
114+
led us away from htmx's strengths and towards solutions that felt more natural in a JavaScript-heavy environment. This
115+
realization was a key factor in our decision to switch to React and Next.js.
57116

58-
We acknowledge that htmx may be a great fit for many projects, especially those with simpler interaction models or those built on top of existing server-rendered applications. Our experience doesn't invalidate the benefits others have found in htmx. The key is understanding your project's specific needs and choosing the tool that best aligns with those requirements.
117+
We acknowledge that htmx may be a great fit for many projects, especially those with simpler interaction models or those
118+
built on top of existing server-rendered applications. Our experience doesn't invalidate the benefits others have found
119+
in htmx. The key is understanding your project's specific needs and choosing the tool that best aligns with those
120+
requirements.
59121

60-
In our case, the complex, stateful nature of Helper's interface made React and Next.js a better fit. However, we continue to appreciate htmx's approach and may consider it for future projects where its strengths align better with our needs.
122+
In our case, the complex, stateful nature of Helper's interface made React and Next.js a better fit. However, we
123+
continue to appreciate htmx's approach and may consider it for future projects where its strengths align better with our
124+
needs.
61125

62-
That said, we're always open to reevaluating our tech stack as our needs evolve and new technologies emerge. Who knows what the future might bring?
126+
That said, we're always open to reevaluating our tech stack as our needs evolve and new technologies emerge. Who knows
127+
what the future might bring?

www/themes/htmx-theme/static/css/site.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,14 @@ display: block;
508508
background: none;
509509
}
510510

511+
figure {
512+
margin: 12px;
513+
}
514+
515+
figcaption {
516+
text-align: center;
517+
font-style: italic;
518+
}
511519

512520
.search-box {
513521
transition: all .2s ease-in-out;

0 commit comments

Comments
 (0)