The Most Important Lesson From HTMX

Theo - t3․gg
16 Jan 202410:00

Summary

TLDRThe script discusses the common practice of building complex client-side applications that require excessive API calls and client-side logic, resulting in poor performance and security issues. It advocates moving back to server-side rendering using frameworks like Intercooler.js or HTMX, allowing developers to build expressive and secure apps without API churn. The core argument is that trusted server-side code avoids the security pitfalls of putting too much logic in the hands of the untrusted client.

Takeaways

  • 😟 API churn from constantly changing UIs is a major pain point
  • 😀 Increasing client-side expressiveness can reduce API churn
  • 😨 But more expressive client-side APIs increase security risks
  • 😟 Building robust security for expressive APIs is extremely hard
  • 😊 Server-side rendering avoids client-side security issues
  • 👍 Server-side code is trusted so you can give devs more power
  • 🤯 HTMX lets you render HTML on the server to avoid client issues
  • 🔒 Server-side rendering reduces the need for complex security
  • 😃 HTMX and Next.js enable simpler full-stack applications
  • ✅ Server-side solutions simplify development and improve security

Q & A

  • What is API churn and why is it a problem?

    -API churn refers to the constant tweaking and modifying of API endpoints to support changing UI needs. This leads to a chaotic situation with lots of ad hoc APIs that need to be updated frequently.

  • How can increasing client-side expressiveness help with API churn?

    -By increasing the expressive power of API endpoints through solutions like GraphQL, frontend developers have more control over how data is returned. This means the API can remain stable as UI needs change.

  • What is the main security concern with client-side expressive APIs?

    -Putting powerful and expressive APIs in the browser makes them accessible to potentially hostile users, not just front-end developers. So exhaustive access control needs to be implemented.

  • Why can giving front-end developers server-side rendering capabilities help?

    -On the server-side, code is trusted so developers can be given flexible data access without security concerns. Solutions like Intercooler allow server-side HTML rendering.

  • What is the core trade-off discussed in the article?

    -The article discusses the trade-off between API churn and security complexity. Increasing client-side expressiveness solves API churn but causes security issues.

  • What does HATEOAS stand for?

    -HATEOAS stands for 'Hypermedia as the Engine of Application State'. It's an architectural approach where HTML responses define the client-side application state.

  • How can server-side solutions like Intercooler help?

    -Solutions like Intercooler allow server-side rendering logic while avoiding client-side complexity. This provides flexibility without security issues.

  • What are the benefits of using HTMX?

    -HTMX allows server-side HTML rendering while keeping modern, interactive UIs. It avoids the need for complex client-side code and security models.

  • How do server components compare to GraphQL?

    -Server components render HTML on the server like GraphQL returns data. But server components avoid GraphQL's client-side security issues by running logic on the trusted server.

  • Why does the author recommend moving more logic to the server?

    -Server-side logic avoids client-side complexity, security issues, and chaos. It makes applications easier to build while empowering front-end capabilities.

Outlines

00:00

😮 The challenges of designing APIs for complex UIs

The first paragraph discusses the issues that arise when designing APIs to support complex and constantly changing user interfaces. As UIs evolve, APIs need to change frequently to meet their needs, resulting in API churn. This leads to chaotic and difficult to maintain APIs.

05:01

😱 The security risks of highly expressive APIs

The second paragraph highlights the security risks associated with highly expressive APIs like GraphQL that are exposed to clients. These put a lot of power into the hands of potentially malicious users and require complex security models to lock down access.

Mindmap

Keywords

💡API churn

API churn refers to the frequent changes and tweaks required in API endpoints to support changing UI/frontend needs. As the article states, letting UIs drive API design leads to chaotic, hard-to-maintain APIs. This is a key problem the video highlights.

💡client-side logic

Client-side logic refers to code that runs in the browser/on the client side. The video argues that heavy client-side logic requires complex security models to prevent access by hostile users.

💡graphQL

GraphQL is a query language that allows clients to request exactly the data they need. The video suggests graphQL and other generic APIs lead to complexity and security issues.

💡HTML rendering

HTML rendering means generating HTML markup on the server before sending it to the client/browser. The video advocates doing more HTML rendering server-side to avoid client-side complexity.

💡intercooler.js

Intercooler.js (now called HTMX) is a library for dynamically updating UIs using HTML. The video suggests it allows moving logic back to the server to avoid client-side problems.

💡security model

The security model refers to the system design and measures in place to control access and prevent abuse. More complex client-side logic necessitates more elaborate security models.

💡server-side code

Server-side code runs on the backend server. The video argues this is more secure since servers are trusted environments, unlike client-side browser code.

💡server components

Server components render UI markup on the server, before sending to client. The video suggests they avoid client-side complexity like security issues.

💡trusted environment

A trusted environment refers to places like servers where code can be trusted and given more access/power. Unlike browsers which can run hostile code.

💡UI/frontend developers

UI/frontend developers write code that runs in the browser and handles user interfaces. The video discusses challenges in providing them more power via client-side logic.

Highlights

Heavy clientside logic requires a tradeoff between API churn or an increasingly complex security model

Letting something that is constantly in flux like the UI determine the shape of your API causes API churn as you try to keep up

Increasingly expressive endpoints put power not just in frontend devs' hands but also potentially hostile users

Context sensitive field level security is needed on every field returned by an API to properly secure expressive endpoints

There's a tension between empowering frontend devs with expressive APIs and the security headaches this causes

On the server side, code is trusted so developers can have complete flexible data access without security issues

Generating frontends on the server avoids client side security complexity and API churn issues

HTMX and server components replace the need for complex security models required by graphQL and expressive endpoints

HTMX and server components are the future of full stack development by avoiding client side security issues

Replacing APIs with endpoints that serve HTML solves the API churn and security tradeoff issue

HTMX is the rediscovery of hypermedia as the engine of application state where HTML defines app state

Moving more application logic to the server makes everything easier and makes frontend developers more capable

The security models required by graphQL and expressive endpoints already feel antiquated compared to HTMX and server components

There are more things to know with HTMX and server components but those things are simpler and result in better software

Should more application work move to the server than is being done today?

Transcripts

play00:00

I talk a lot about how much I love HTML

play00:03

not specifically like an HTML file or

play00:05

the HTML syntax but the power of sending

play00:08

static markup from the server to the

play00:11

client there A lot of times where you

play00:12

might want to send updated UI to the

play00:14

user without having to make them refresh

play00:16

the whole page there's also a lot of

play00:18

things you probably want to do when a

play00:19

user clicks a button that can't be done

play00:21

on their computer so you're going to

play00:22

need the server to be involved in those

play00:23

things anyways what I've seen as a

play00:25

result is a lot of applications that

play00:27

send giant Json payloads to the user

play00:30

once they've done something on the

play00:31

client and then the JavaScript parses

play00:33

that data transforms that into some new

play00:35

markup and then renders it on the page

play00:37

often very slowly the JavaScript

play00:39

necessary to do all of this stuff gets

play00:41

massive to the size of tens of megabytes

play00:43

for some websites and the resulting

play00:45

performances what you would expect not

play00:47

great thankfully we're starting to see a

play00:49

revolution where we're moving away from

play00:51

these giant Json payloads and towards

play00:53

sending markup to the user when it makes

play00:55

sense but this isn't a new Revolution

play00:57

this is actually something that the HTM

play00:59

X team has been pushing hard for a while

play01:00

all the way back when they used to be

play01:02

called intercooler JS they tried to warn

play01:05

us but now we're finally hearing it what

play01:07

we're talking about here is a response

play01:09

to a great tweet from Z the CTO of

play01:12

Sentry which was joking about how we got

play01:14

tricked into using graphql while I do

play01:15

think graph Q has a lot of benefits

play01:17

there are negatives too and that's the

play01:19

joke here is a lot of people were using

play01:21

it when they shouldn't be but these

play01:22

continued abstractions where you were

play01:24

building more and more complex API

play01:26

Solutions so the client could get the

play01:28

info it needed this became a very fast

play01:30

slippery slope and graphql emphasized

play01:33

how slippery that slope had gotten the

play01:34

HTM X team replied with a link to a blog

play01:37

post from

play01:38

2016 about this where they tried to warn

play01:41

us and for those who don't know

play01:42

intercooler was the old name for HTM X

play01:44

so let's take a look at this blog post

play01:46

because I love it and I think it's more

play01:47

relevant now than it's ever been before

play01:50

the API churn to security tradeoff tldr

play01:53

heavy clientside logic requires a

play01:54

trade-off between API churn or an

play01:56

increasingly complex security model the

play01:58

problem a recent article by Jean jaac de

play02:01

BR titled why I no longer use MVC

play02:03

Frameworks sparked a long and

play02:04

interesting discussion on Hacker News

play02:06

which crystallized a fundamental problem

play02:07

I see with the current Trend towards

play02:09

heavy client side logic and web apps

play02:11

here is the start from that article

play02:12

where Jean jaac lays out the problem the

play02:14

worst part of my job these days

play02:16

designing apis for front end developers

play02:17

the conversation inevitably goes as Dev

play02:20

so this screen has data elements XYZ

play02:23

could you please create an API with the

play02:24

response format

play02:26

XYZ me okay I don't even argue anymore

play02:30

projects end up with a gazillion apis

play02:32

tied to screens that change often which

play02:34

by Design requires changes in the API

play02:36

and before you know it you end up with

play02:37

lots of apis and for each API many form

play02:40

factors and platform variants to

play02:42

summarize if you are designing Network

play02:44

API endpoints for a front end you will

play02:46

end up tweaking and modifying the API to

play02:48

support your UI needs in an ad hoc and

play02:50

often chaotic manner by letting

play02:51

something that by its nature is

play02:53

constantly in flux and fiddly that is

play02:55

the UI determine the shape of your API

play02:58

you end up thrashing it around trying to

play03:00

keep up for the remainder of this

play03:01

article I will refer to this problem as

play03:03

API churn that's an important piece to

play03:05

remember API churn is the enemy that

play03:07

we're fighting with all of this so

play03:09

what's the solution the solution is if

play03:11

you're committed to that client side

play03:12

increase the expressiveness of the API

play03:14

available on the client side okay so

play03:16

what does that mean means you must begin

play03:17

surfacing more and more generalized data

play03:19

access and mutation functionality on the

play03:21

client side you see this General query

play03:23

languages like graphql replacing

play03:25

multiple rsh in ad hoc API endpoints

play03:27

with fewer more expressive endpoints is

play03:29

going to be thought of as a move towards

play03:31

something like SQL on the client side I

play03:34

don't like comparing it to SQL but I get

play03:35

what they're trying to say by increasing

play03:36

the expressive power of endpoints you

play03:39

the API designer no longer need to worry

play03:41

about getting an API just right rather

play03:43

the frontend developer has control over

play03:45

how and what is returned or what is

play03:47

modified and your API stays stable as

play03:50

the UI needs change sounds great but

play03:53

wait a second there's a problem with

play03:54

this solution problem these increasingly

play03:56

expressive endpoints is that you're also

play03:57

putting them not just in the hands of

play03:59

your front end de but also the hands of

play04:00

potentially hostile users the browser is

play04:02

about the least secure Computing

play04:04

environment I can imagine and anything

play04:06

that the front end devs can do can also

play04:07

be done by a hostile user like this

play04:09

graphql query if you don't make this

play04:12

really secure you're going to have users

play04:14

able to hit it and get info they

play04:15

probably shouldn't like salary this is

play04:17

terrifying and a lot of graphql stuff

play04:19

wasn't set up properly I have a video

play04:21

about how putting your logic in your

play04:22

database is terrifying and the reason a

play04:24

lot of people were stuck doing things

play04:25

like that is because they have these

play04:27

generic API layers that don't know

play04:29

enough about the intent of how it's

play04:31

being used to first off expose data

play04:33

correctly but more importantly to

play04:35

authenticate the user properly to make

play04:36

sure they should or shouldn't have

play04:38

access to that data it's utter chaos and

play04:39

I've seen so many code bases drowning in

play04:42

this particular style of mess and oops

play04:45

you had better darn well not show that

play04:46

information so now you have to build

play04:48

context sensitive field level security

play04:50

so on every query on every field in

play04:53

every query you have to work really hard

play04:55

to make sure your fields are properly

play04:58

secured so now every single key being

play05:00

returned by your API ever has to have

play05:02

its own security model around it you can

play05:04

see how chaotic and hard to maintain

play05:06

that gets really

play05:07

fast as I just said this is incredibly

play05:10

complicated and when this security issue

play05:13

was brought up on Hacker News the

play05:15

response was it doesn't belong in the

play05:16

spec it belongs in the implementation

play05:18

but yes the reference implementation

play05:19

graph qjs should probably be updated to

play05:21

demonstrate Access Control at the time

play05:23

the go2 example for graphql and web apps

play05:25

was graph qjs and they didn't have data

play05:27

Access Control implemented in it so

play05:28

people just copy the default

play05:30

implementation didn't have any security

play05:32

which is terrifying I literally laughed

play05:34

out loud when I read this this is a

play05:36

major major issue and anyone who

play05:37

considers increasing client side

play05:39

expressiveness as the answer to API

play05:41

churn needs to have a very good answer

play05:42

for it I totally agree this isn't just a

play05:45

security problem there's also so many

play05:47

technical challenges in implementing

play05:48

things in this way where it's just hard

play05:49

to build and maintain a generic way to

play05:52

get data to the client security is one

play05:54

part design of the schema is one part

play05:56

implementation details libraries you're

play05:57

choosing all of this stuff gets really

play05:59

complex really fast but what if there

play06:01

was a better way this again is about

play06:03

trust the core problem again is that in

play06:05

putting more expressive tools in the

play06:06

hands of your client side devs you are

play06:08

also inadvertently letting them slip

play06:10

into the hands of adversarial users

play06:12

there is a fundamental tension therefore

play06:14

between how much you can give your

play06:15

developers and how much of a security

play06:17

headache this power will turn out to be

play06:18

in an Ideal World you will give your UI

play06:20

developers everything they could

play06:21

possibly need in an open and expressive

play06:23

query layer and that would let them tune

play06:25

the structure and return the data of a

play06:26

query just so for those hot complicated

play06:29

quer I that always end up dominating

play06:30

system performance what if I told you

play06:32

there was a place that exists where you

play06:33

can do this such a place does exist it's

play06:35

called the server side see where we're

play06:37

going guys don't know if you expected

play06:39

this but I just tricked yell into

play06:40

watching yet another server components

play06:42

video because this article could be

play06:44

summarized as the arguments for Server

play06:46

components and or how server components

play06:49

replace graphql they solve this problem

play06:51

really really well you see on the server

play06:54

side code is trusted you can give your

play06:56

developers a completely open and

play06:57

flexible data access and and update API

play07:00

because you to a first order

play07:01

approximation trust them give them the

play07:03

power of say a structured query language

play07:06

and that's totally fine it's not even

play07:08

controversial when you do that because

play07:10

that power isn't going to the user it's

play07:12

just in the layer between the HTML the

play07:14

user sees and the server that has that

play07:16

data when you give your frontend devs

play07:17

the ability to generate their front ends

play07:19

on the server a lot of these problems go

play07:22

away really fast and it's funny that I'm

play07:24

bringing this up because a lot of the

play07:26

reason people are so hesitant with the

play07:27

new server component model and the new

play07:29

nextjs model is they think it's less

play07:31

secure and they don't trust frontend

play07:32

devs to do it right the harsh reality is

play07:34

these backend devs have gotten so good

play07:35

at these security models because they're

play07:37

a necessary evil in order to use

play07:39

something like graphql while yes front

play07:41

and devs need to think a little bit

play07:42

about security Now the benefit that

play07:44

comes with it is they don't have to

play07:45

think about security anywhere near as

play07:46

much and we're not building these crazy

play07:48

chaotic systems so that you can add one

play07:50

additional key to your query on the

play07:52

client side the solution to the problem

play07:54

with the solution so if you want to

play07:55

avoid this API churn and security

play07:57

complexity trade-off is's a great way to

play07:58

do it move things back to the server

play08:00

side one way to do it without

play08:01

sacrificing modern web usability is to

play08:03

use something like intercooler into do

play08:04

your HTML rendering and domain Logic on

play08:06

the server in a trusted environment

play08:08

you'll also get a lot of other benefits

play08:09

from this approach hate without tears a

play08:11

programming model that you likely

play08:13

already have close to a decade of

play08:14

experience with and so on this is an old

play08:16

article and my audience probably doesn't

play08:18

have a decade of experience with things

play08:19

that were already old at the time seven

play08:21

years ago but that point aside let me

play08:23

know if you want me to do a hate OS

play08:24

video because it's a pretty cool pattern

play08:27

where do they actually say what it

play08:28

stands for always forget the acronym

play08:30

stands for hyper media as the engine of

play08:32

application state so your HTML is

play08:34

actually the thing that defines the

play08:36

state of the page it's a really cool

play08:37

pattern it's really nice seeing this

play08:39

being rediscovered with a new error of

play08:41

HTM X if you want a long video about

play08:43

that let me know in the comments this

play08:45

video isn't about that this video is

play08:46

about the value of replacing your apis

play08:49

with end points that serve HTML the core

play08:51

point of this article is that in order

play08:53

to make Dynamic front ends without

play08:56

having the server run the HTML you now

play08:58

have to deal with with a massive

play09:00

security issue architecture issue and

play09:02

utter chaos in order to increase the

play09:04

expressiveness so client side developers

play09:06

can do the things they need to do to

play09:07

make good applications this is what's so

play09:09

cool about this model and this is why I

play09:11

think both HTM X and server components

play09:14

are the future of how we build full

play09:15

stack applications these security models

play09:18

already feel so Antiquated and the

play09:20

moment you start playing with either

play09:21

HDMX or server components you're going

play09:23

to realize just how much more complex

play09:25

things were than they needed to be yes

play09:26

there are more things you need to know

play09:28

about well those things are simpler and

play09:30

the result is better software so what do

play09:32

you think are we being too aggressive

play09:34

with the killing of apis or should we be

play09:36

doing more work on the server than we

play09:37

are today I'm obviously in favor of

play09:39

moving more of the stuff to the server

play09:41

it makes everything easier and it makes

play09:43

frontend developers more capable of

play09:44

delivering great software but how do you

play09:46

feel about it let me know in the

play09:47

comments and tell me if I should do that

play09:48

ha to OAS video because something I want

play09:50

to talk a bit more about if you want to

play09:51

learn the truth about HTM X I'll pin a

play09:53

video in the corner with that and if

play09:54

You' already seen that or you're not

play09:55

interested the video below should be

play09:56

pretty good too thank you guys as always

play09:58

appreciate you all a ton peace nerds