Javascript for Haters

Posted on Jul 30, 2022

Here’s a fresh new take for you, I don’t really like writing Javascript.

However, as a web developer sometimes it is necessary or useful as much as I like to avoid it. I have been recently been working on a little side project that needed some fairly interactive UI, so I was casting about for new tools.

I wanted to avoid the build pipeline complexity of modern tools like React and I like to try and stick to common web standards as much as possible. I want to write plain html, css and Javascript - I don’t want to learn too much framework specific code.

If you are similarly inclined then here are the tools I discovered.

htmx

https://htmx.org

The idea behind htmx is that modern hypertext should be more useful for modern usecases. Here is their blurb1:

htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext

htmx is small (~10k min.gz’d), dependency-free, extendable & IE11 compatible

Here is an example from the site I am building.

An example note

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<div class="note">
  <div class="controls">
    <input 
      name="done" 
      type="checkbox"
      hx-post="/note/176/toggle" 
      hx-target="closest .note" 
      hx-swap="outerHTML"
    >
    <div 
      class="emoji-button" 
      hx-get="/note/176/edit" 
      hx-target="closest .note" 
      hx-swap="outerHTML"
    >
      🖍
    </div>
    <div 
      class="emoji-button" 
      hx-get="/note/176/delete" 
      hx-target="closest .note" 
      hx-swap="delete"
    >
    🗑
    </div>
  </div>
  <div class="content">
    <p>Write a blog on html</p>
  </div>
  <div class="metadata">
  ...
  </div>
  <hr>
</div>

If we take a look at just the edit button we can break it down.

1
2
3
4
5
6
7
8
    <div 
      class="emoji-button" 
      hx-get="/note/176/edit" 
      hx-target="closest .note" 
      hx-swap="outerHTML"
    >
      🖍
    </div>

You can see we have a classic class attribute, but then the three hx-* attributes. These tell htmx, when the div is clicked, to send a GET request to /note/176/edit, then with the response swap out the closest .note element. The server responds to this with an html fragment that is swapped in place.

I am not sure how effective the model would be on large scale applications, but for me tinkering around on the weekends it means I can have a lot of productivity and a fair amount of UI complexity, without ever having to write Javascript. Nice.

Alpine.js

https://alpinejs.dev

The idea behind Alpine.js is it acts as a super tiny, lightweight Javascript framework.

Alpine is a rugged, minimal tool for composing behavior directly in your markup. Think of it like jQuery for the modern web. Plop in a script tag and get going.

Alpine is a collection of 15 attributes, 6 properties, and 2 methods.

Alpine follows a similar idea of markup directly in the html, but exposes much more javascript for you to use.

1
2
3
4
5
<div x-data="{ count: 0 }">
    <button x-on:click="count++">Increment</button>
 
    <span x-text="count"></span>
</div>

I haven’t used it myself, but I include it as it is something I am eying up for future projects with different requirements.

Svelte

https://svelte.dev/

Now, Svelte is definitely on the “writing javascript” side of “not writing javascript” but bear1 with me. Here is their schtick:

Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app.

Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<script>
	let count = 0;

	function incrementCount() {
		count += 1;
	}
</script>

<button on:click={incrementCount}>
	Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

Now, I was working with svelte for a bit, before I switched to htmx. I really enjoyed the development experience and it felt much more like writing plain HTML with Javascript smarts rather than Javascript everywhere, like writing React. I moved away from it because I didn’t want a SPA but if I end up going down that track, or need a more complex UI it is something I would definitely turn back to.


  1. bare with me? ↩︎