By Kevin Åberg Kultalahti

An Introduction to Actions in Svelte (Part 1)

Ever wondered what all the fuss is about? Actions are a great way to expand the functionality of elements in your markup without having to clutter it up with lots of code. In a series of posts I will show you what you can do with them; enhance inputs, use external libraries, improve user experience in general and, lastly, how they work under the hood.

What’s it all about?

Oftentimes you find yourself wanting to add functionality to regular old HTML elements. If it’s not styling you often have to get a reference to the tag, do some magic javascript and clutter up your components. At least this is what usually happens in for example React. I’ve done it too many times. In Svelte there’s a better way. Actions.

Interacting with the DOM in Svelte

Before we jump in to the subject of actions we need to make sure that we have a good understanding of some basic concepts.

All elements in our markup are DOM nodes. A couple of examples are h1, p and input. These nodes contain properties and functions. If you’ve ever done some bare-metal DOM manipulation you’re probably familiar with some of them: Node.childNodes, Node.firstChild or Node.appendChild(). Elements are a special kind of node that have a number of additional properties. You have probably used, or at least heard of for example style or innerText .

Let’s take a look at a small example that will show us how we interact with a DOM node in Svelte without actions.

That does’t look too bad. We start by getting a reference the node we want to interact with, in this case an h1. But why do we need to use onMount? That’s because when the component is initialised the h1 element doesn’t exist yet, which means that our “node” is undefined. Not the end of the world. However, imagine a scenario where you need to implement something more complex. Even worse, what would happen if someone asked you to implement the functionality in several different components? You would start by moving the tellMeAboutTheNode function out of the App.sveltefile. And then what? You still need to import onMount and declare let node. It’s not very declarative. This is where actions shine.

So what are actions?

As the Svelte documentation describes it, “Actions are functions that are called when an element is created.”. OK. Functions. Called when an element is created. Got it. 🤔

Let’s break that down. When an element is created (added to the DOM by Svelte’s runtime) a function is called with the first argument being the element’s node. For example:

function tellMeAboutTheNode(node) {
  console.log('Information: ', node.tagName )

This function would, if applied as an action, log the nodes tagName. In Svelte we use the following syntax (using the above examples function name) for actions: use:tellMeAboutTheNode. And here’s how it looks when applied to an actual element:

What a time to be alive! Seven lines of code instead of 14. And it looks so much nicer. And we haven’t even moved our function out of the Svelte file yet! Here we apply the tellMeAboutTheNode function to the h1 element. When Svelte creates this element the function will run and in the console we should see the following:

Information:  H1

If you want to check for yourself you can click the Console tab in the bottom right of the REPL.

Ok, that’s great, but no one cares about logging out a node. What can we actually use them for? In the beginning of the article I mentioned a couple of use-cases. Let’s look at one of them: improving user experience.

Imagine that your manager comes to you and tells you that the design team has decided that the heading tags on your website are boring. She wants you to add a typewriter effect to them. After working on the solution for a while you realise that you will need to clutter up your tidy component with all sorts of shenanigans. But wait! Actions to the rescue 🚑! Below I have gone ahead and implemented the typewriter effect using an action.

There is so much good stuff going on here. The complex typewriting effect is abstracted away in a neat function, out of site and out of mind. All that is left is use:typeWriter. You instantly understand what it does and so will probably any future colleagues. And there’s more - this action is re-usable. Anytime you want a typewriter effect added to an element, you just import the function and apply it. So elegant. Why don’t you go ahead and try adding it to another element. Cool, right?

Options and Re-running Actions; The update Function

Actions can recieve a second argument, an option parameter, that lets you adjust how your action behaves. In the above example you might find yourself wanting to adjust the typewriters speed. Here’s the syntax:

<script>function typeWriter(node, speed) {
    // Here goes all your logic

<h1 use:typeWriter={speed}>Try editing this text</h1>

The observant among you have probably noticed that these actions are called only once. And you are, of course, correct. Svelte solves this by allowing you to return an object containing an update function from your action. Everytime the option parameter changes the update function will run. This sounds a bit confusing. Let’s look at the syntax:

<script>function action(node, option) {
    // Here goes all your logic

    return {
      update((option) => {
        // Re-runs everytime the option parameter changes

<h1 use:action={option}>Try editing this text</h1>

Ok, that helps. A bit. I think we might need to make something that is a bit more interactive. In the following example I’ve taken the typewriter example from above but added a button that changes the speed that is passed down to our action. Let’s take a look:

It is starting to get a bit complicated here but bear with me. Looking at the typewriter code we can see that we’re now returning an object containing an update function that recieves a speed paramter. This function runs everytime the speed parameter changes. This means that when we click the button in our App component the speed changes from 100 to 400 and the update function is executed.

Destroying the element; clearing things up

This is all well and good. But what happens when the element is destroyed? Aren’t we stuck with a bunch of timers? Yes, but once again Svelte comes to our rescue. In addition to returning an update function we can also return a destroy function. This function is executed whenever the element is removed from the DOM. This is where we for example clear timers and remove event listeners. Keeping in spirit with our earlier timer demo, let’s make sure that we’re actually clearing those timeouts we set up:

Here I’ve added a simple button that removes the h1 tag from the DOM. When it comes to the function we can see that I have added the destroy. In addition to this i’ve made sure to collect all the timeouts we’ve set up during course of the functions lifetime. Once the h1 tag is removed we run through and clear all our timeouts and finally log “Timeouts cleared!“. Try it out by clicking the Toggle Headline button.

Liking this content?
Sign up to the newsletter!


So that’s all there is to it. We started off by talking about what actions are and when we might want to use them: enhancing inputs, adding functionality to elements, using external scripts and improving user experience. Next up was update and how to pass in parameters to our actions. Last but not least was the cleanup-part. We investigated how to clear up things like timers and event listeners using the destroy function.

Actions are deceptively simple yet incredibly powerful. Some call them the lifecycle methods of elements which I think is an apt description. That’s it, for now. In the next part we’ll be talking about some more advanced examples and use-cases. I might even give you a peek at how I built an action that applies other actions. I call it Actionception. Because why not? 🤷‍♂️

If you liked this content, please consider subscribing to the newsletter. Especially if you want to get notified when the next part is released! Just enter your e-mail in the form above.

Thanks for reading.

profile image

I'm Kevin. A (mostly) front-end web developer focusing only on Svelte. I write articles, create videos and make courses. I run the Svelte Radio podcast. Oh, and I like to build stuff; websites, packages, anything really. If you want to get in contact with me, hit me up on Twitter or send me an email.

Svelte School is a company that develops courses and trains developers on how to use the framework Svelte.