Introduction to Qwik and the Power of Loaders and Actions
Tags: qwik, javascript, web, webdev
Published: 2023-08-23 14:53:34

---
title: Introduction to Qwik and the Power of Loaders and Actions
published: true
date: 2023-08-07 09:00:00 UTC
tags: ["qwik", "javascript", "web", "webdev", "webdevelopment"]
canonical_url: https://tech.sparkfabrik.com/en/blog/qwik-and-the-power-of-loaders-and-actions/
---

![Qwik logo](https://tech.sparkfabrik.com/images/content/qwik/qwik-logo.svg)

## Introduction

[Qwik](https://qwik.builder.io/) is a JavaScript framework for building web applications with a focus on speed. It's designed to be "the fastest possible first load experience" by prioritizing what's important and loading only what's needed. It achieves this by using a component-level code splitting and optimized server-side rendering. Qwik was created by [Miško Hevery](https://github.com/mhevery), the same mind that created the **Angular** framework at Google, as well as the original **AngularJS**.

The defining characteristic of Qwik is its instant-on interactivity. Unlike other frameworks, **Qwik is resumable**, meaning Qwik applications require zero hydration. This allows Qwik apps to be interactive instantly, regardless of the size of the application.

I recently used Qwik for a talk that I'm giving at [Come to Code](https://www.cometocode.it/) in Italy. I was impressed by how easy it was to get started with Qwik, how fast it was to build a simple application, and particularly in my brief experience I learned to use two of Qwik's server-side features, `routeLoader$` and `routeAction$`, and I wanted to share my findings with you.

## Understanding Loaders and Actions

One of the key features of Qwik is resumability, and this is achieved by serializing the state of the application into the HTML and sending it to the client. This means that data loading and state changes must happen on the server, and this is where our two functions come in.

Both are APIs included in Qwik City, a library that provides **server focused features**.

- `routeLoader$` is used to bind a route to a function that loads data. This is typically used for loading data when the application is bootstrapped or when the state of the application changes.
- `routeAction$` is used to handle form submissions, to change the state of the application, and to perform any side effect.

The power of these APIs is their ability to simplify the management of application state and data loading, and the encapsulation of the logic inside specific functions with a separation of concerns that makes the code easier to maintain and reason about. They also allow Qwik to optimize the loading of components and data, and make the application feel faster for the user.

## Examples

Let's take a look at an example. Suppose we're building a web application that fetches and displays RSS feeds. We have a function `fetchFeeds` that fetches the feeds from a list of URLs, and a function `sortAndLimitFeeds` that sorts these feeds by date and limits the result to the latest 10 feeds.

```jsx
async function fetchFeeds(feedUrls) {
  // Fetch and parse the feeds...
}

function sortAndLimitFeeds(feeds) {
  // Sort and limit the feeds...
}
```

We can use `routeLoader$` to bind these functions to a URL. This means that when the application is bootstrapped or the state of the application changes, Qwik will automatically call these functions to load the data.

```jsx
import { routeLoader$ } from '@builder.io/qwik-city';

export const useRssContentLoader = routeLoader$(async () => {
    const feedUrls = ['https://tech.sparkfabrik.com/en/index.xml', ...];
    const feeds = await fetchFeeds(feedUrls);
    return sortAndLimitFeeds(feeds);
});
```

We can then use this function in our component to load the data. `routeLoader$` returns a `Signal`, so we can get the value simply by accessing the `value` property.

```jsx
import { useRssContentLoader } from './rss-content-loader';

export default function RssContent() {
  const rssContent = useRssContentLoader();
  return (
    <div>
      {rssContent.value.map((feed) => (
        <div>{feed.title}</div>
      ))}
    </div>
  );
}
```

The `$` at the end of the function is a boundary marker, and it tells the [Qwik Optimizer](https://qwik.builder.io/docs/advanced/optimizer/) where to break the code to create chunks, for lazy loading.

The logic inside the function is executed on the server, and the result is serialized and sent to the client. This means that the data is available immediately, and that's why the application is interactive instantly.

Now let's take a look at `routeAction$`. Suppose we want to add a button to our application that allows the user to add a link from a feed to his favorites. We can use `routeAction$` to create a function that executes on the server when the user clicks the button.

```jsx
import { user } from './user';
import { routeAction$ } from '@builder.io/qwik-city';

export const useAddToFavoriteAction = routeAction$((item) => {
  const link = item.url;
  user.favoriteLinks.push(link);
  return {
    success: true,
  }
});
```

Now we can add the special component `Form` to wrap our items list and add a button that calls the `useAddToFavoriteAction` function when clicked.

```jsx
import { useAddToFavoriteAction } from './add-to-favorite-action';
import { Form } from '@builder.io/qwik-city';

export default component$(() => {
    const addToFavoriteAction = useAddToFavoriteAction();
    return (
        <Form action={addToFavoriteAction}>
            <div>
                {rssContent.value.map((feed) => (
                  <div>
                      <div>{feed.title}</div>
                      <button name="url" value={feed.link}>Add to favorite</button>
                  </div>
                ))}
            </div>
        </Form>
    );
});
```

So `routeAction$` is exposing a URL that we can use to trigger an action on the server, via a form submission, and the logic executed on the server is the body of the function.

The `item` parameter that we pass to the function is an object representing the form data. In this case, it contains the property `url` with the `value` attribute of the button that was clicked, for example:
    
```js
{
    url: 'https://tech.sparkfabrik.com/en/blog/qwik-and-the-power-of-route/',
}
```

And since under the hood the `Form` component uses the native HTML `<form>` element, all of these will work without JavaScript enabled in the browser!

## Conclusion

There are many other features in Qwik that I haven't covered in this article, but I hope this gives you a good idea of what Qwik is and how it works. When I started working with Qwik to set up a demo, I was expecting a React-like framework optimized for SSR/SSG, and I knew about its [resumability](https://qwik.builder.io/docs/concepts/resumable/) concept, but seeing it in action, after developing my simple application and playing with it, looking at its performance, network requests, and the simplicity of the code, I was really impressed. Not to mention the developer experience, which is also great with the `qwik new` and `qwik add` CLI tools and the debugging in the browser in development mode, the many [integrations](https://qwik.builder.io/docs/integrations/) that already exist and others that are coming, the wonderful [documentation](https://qwik.builder.io/docs/), and the [community](https://qwik.builder.io/community/values/) that is growing around it.

Qwik is ready for production, and I think it's a great choice for building web applications. Maybe I will cover some of its other features in future articles, so stay tuned!