Why HTML Actions Are Suddenly a JavaScript Trend

Actions are not new. But they are seeing a resurgence — having a moment, if you will — in the JavaScript frontend world.

At the React Conference live-streamed from Las Vegas earlier this month, the React compiler and React 19 took center stage. But buried amid the presentations was talk of React Action. And last week, Astro announced its own support for actions, which Astro frontend developer Ben Holmes said via Twitter was similar to React Actions.

”It’s our way of defining an RPC endpoint in Astro,” Holmes said. It takes the basics of a server action and adds features for error handling and input validation.”

Actions have been around for some time, pointed out Andrew Clark, a Vercel software engineer and React core contributor, at the React Conference.

“Actions are a first-class pattern for asynchronously updating data in your application in response to user input,” Clark said. ”Actions as a general pattern are not a React invention. They’ve been part of the web platform for decades. In fact, in HTML form actions were first introduced to the web back in the 1900s.”

Ouch. Yes, he said the 1900s — like cowboys introduced them in the Wild West. For you historians out there, that’s before JavaScript was even created.

HTML form actions were a way to add interactivity to a web page. In a classic HTML form, developers specified a server endpoint by passing it the URL to the action property, Clark explained. When a user submitted the form, the data was sent to the server, and the server responded with a fresh HTML page.

“Submit form, load page, submit form, load page, it’s pretty simple, right? And what’s great about this model is that you can use it to build almost anything,” he said.

Yet actions haven’t been used much since JavaScript came online.

“Nowadays, a web developer could go their entire career without ever using this API,” he said. “What happened is, upon the introduction of JavaScript — we all love JavaScript — it eventually became possible to build client-heavy web apps that provided a much richer, more interactive experience than apps whose behavior was confined solely to the server.”

User expectations changed, too. They wanted instant feedback interacting with the app, so they don’t want to wait for an entirely new HTML document every time, he said. Users want apps to remember their current state so they don’t lose the scroll position or the text input whenever an action is performed.

“In other words, users expect more than what’s possible to achieve without at least some client-side interactivity,” he said. “There are some nice things about client-side event handlers. They can be used to implement instant rich feedback to user input and they can compose client and server behavior together.”

But there are also downsides with the JavaScript-only approach, such as: it’s hard to manage local state. Achieving asynchronicity is also difficult and frequently leads to bugs, he said. Also, because event handlers rely on JavaScript, the UI is not interactive until the code loads and runs, which is slow compared to raw HTML and leads to dropped interactions, he added. This makes it tempting to revert back to plain HTML actions because the app is interactive as soon as the HTML renders.

“We shouldn’t forget about the reasons we moved away from actions in the first place,” he said. “They provide little to no immediate feedback in response to user input. You’re basically just stuck with whatever the browser stock controls give you. And it’s really difficult to sprinkle on additional client interactivity because it’s an entirely different programming model.”

React exists to solve exactly this kind of riddle, Clark said.

So… Wait. Why Is React Adding Actions?

This month, React Actions came out of the canary channel — where they’d been since last summer — and into React.

“You may have heard about them in the context of something called server actions features, available in server components frameworks like Next.js, but actions are not exclusive to server components frameworks,” Clark said.

React actions are an evolution of two existing APIs, he said. The first is react transitions, which is used for updating state without blocking user input. Actions built on transitions by adding support for asynchronous functions. The second is the HTML form API.

“Using a React action is a lot like using an HTML form action, except instead of passing a URL to the action prop, you can now pass a function,” he said. “In the most basic example, that’s all you have to do pass a function to the action prop, and when the user submits the form, the action is caused. By using an action function instead of a URL, you can define the behavior of the action directly inside your component.”

Clark said that there’s been “a resurgence of actions-inspired APIs within the JavaScript community, thanks in large part to the Remix and React frameworks.” Actions were re-introduced as a pattern for server-client communications, he added.

“Nowadays, it seems that nearly every JavaScript web framework has their own take on the actions pattern,” he said. ”And for good reason. We think that actions are a fantastic way to build applications, and they fit perfectly into the React programming model.”

Which, he noted, begged the question: If action-based APIs already exist in React frameworks, why build them into React?

The React team thinks they can do even more with actions by integrating them into React without compromising Read’s composability, by using in features such as:

“There’s nothing special about an action function. They are regular functions: You can compose them, you can write abstractions for them the same way you would any other function, you can define the action on the client, or if you use a server component framework, you can define the action on the server via the use server directive and access your data layer directly,” he said. “You can have any number of actions per page per component, per whatever, you can swap out actions at runtime.”

That level of “maximum composability” is achieved because the React team has integrated “actions into every layer of React from the client runtime to the streaming SSR renderer to the server components data format, all working together to provide a seamless experience,” he added.

“Our goal is to provide a core primitive that meta frameworks like Remix, Next and Redwood can build on top of the same way they currently build on features like streaming and suspense,” he said.

Where React Actions Shine

Actions in React look a lot like HTML actions, but they also look similar to event handlers like onsubmit, or onclick, Clark said.

“Despite the surface-level similarities, though, actions have some important abilities that set them apart from regular event handlers,” he continued. “One such ability is support for progressive enhancement. Form actions in React are interactive before hydration occurs. Believe it or not, this works with all actions, not just actions defined on the server.”

If the user interacts with a client action before it is finished hydrating, React will cue the action and replay as soon as it streams it, he said. If the user interacts with a server action, action can immediately trigger a regular browser navigation, without hydration or JavaScript.

Actions also can handle asynchronous logic, he said.

“React actions have built-in support for UX patterns like optimistic UI and error handling,” he said. “Actions make these complex UX patterns super simple by deeply integrating with React features like suspense and transitions. They’re effortlessly composable. They have a unified client and server API. They’re interactive before hydration, and you can implement advanced UX in just a few lines of code.”

Group Created with Sketch.

 

 

 

 

Top