Say No To Complexity With AlpineJS

Rate this content

Modern JavaScript is powerful, but big frameworks like Vue or React add an overwhelming amount of complexity to a developers' workflow. That’s why I wrote AlpineJS. It’s less than 10kb, requires no build process, takes almost no time to learn, yet gives you the declarative templating and reactivity you can’t live without. I can’t wait to show it to you.

33 min
18 Jun, 2021

AI Generated Video Summary

Alpine.js is a lightweight framework for creating JavaScript behavior directly in markup. It has 13 directives and 6 magic properties, making it like Tailwind for JavaScript. The upcoming version of Alpine will focus on performance and optimization. It sits between jQuery and Vue, offering reactivity without compilation. Alpine.js is robust and resilient for DOM manipulation, and works well with Laravel for localization and internationalization.

1. Introduction to Caleb Porzio and Alpine.js

Short description:

I am Caleb Porzio, a full-time open source maintainer and developer. I maintain LiveWire, a full stack framework for Laravel. I also host the No Plans to Merge podcast. Alpine.js is my ode to simplicity, perfect for projects that don't require Vue.js or React. Let's start from a blank slate and install Alpine.js via a simple CDN. Our first component will be a counter. Let's see what Alpine looks like with a basic component.

Hey, there. I am Caleb Porzio. I'm a full-time open source maintainer, developer. I maintain a few packages. One of them is LiveWire. It's a full stack framework for the Laravel framework for PHP. I also host a podcast called No Plans to Merge with my buddy Daniel. Every Friday we hang out and we talk about code and just hang out every Friday, so give that a listen if you care. And then also the other project I maintain is Alpine.js, which I'm here to talk to you about today.

Alpine.js is my ode to simplicity. It's basically for a lot of projects that I work on, like full stack framework type, like Rails, Laravel projects, and even static sites and small things. I don't always want something as big as Vue.js or React, but Vanilla.js just isn't enough. It doesn't give me the reactivity and the things that I've come to love with these bigger frameworks. So I basically wrote Alpine, and that's what I'm going to show you. We're just going to live code it, and I'll show you exactly how it works.

So the first thing, those slides that I just showed you, that's just an Alpine component. This is the entirety, a simple HTML page. So I'm actually going to get rid of that, and we're going to start from a totally blank slate. This is a simple HTML page loaded in a browser with a few base styles, so there's no magic happening here at all. So the first step is going to be installing Alpine.js. To go with that simplicity mantra, there's no NPM anything. You can NPM installed if you want, but personally, I love the good old days of a simple CDN, dropping it into a page and then getting up and running. So you can go to the Alpine repository on GitHub and just yank this CDN out, and then we'll paste it in, and now we are ready to go. Alpine is totally installed. It's 7.5 kilobytes of JavaScript minified, so it's extremely small.

Okay, let's get to it. So our first component, I'm just going to write a counter component. This is like the hello world of JavaScript frameworks. A counter, meaning we just hit a button, plus and minus, and see a number update, and then we'll kind of backfill some of the knowledge, but I just want you to see what Alpine looks like, a basic Alpine component. So we're going to create a div, and we'll create a button that's a plus, a button that's a minus, and a span tag for the actual number.

2. Creating an Alpine Component

Short description:

To turn the button into an Alpine component, we add xdata property and a JavaScript object literal of our state. The x text directive is used to bind the text value to the count. The x on directive listens for a click event and runs JavaScript code. We can increment the state using count++ inside the button.

So here's our button, plus and minus. And to turn this into an Alpine component, everything is in the markup. So we'll add this xdata property. xdata tells the markup, like here's going to be the Alpine component. Then inside of it, you put a JavaScript object literal of your state for the component. So for us, it's going to be count is zero.

Think of this like the data object inside of a view component. And the first directive we're going to see outside of xdata is x text. So x text, if you're familiar with Vue.js, a lot of these should be very familiar. This is V text in Vue. X text is saying, hey, whatever you put in here, we're going to put count in here. Whatever you put inside of this expression bind to the text value, the inner text value of this element. So if we refresh the page, we should now see a zero. Okay? And there we go. We refresh, we have a zero.

So now we need to wire up the plus and the minus buttons so that when we click them, we mutate that state. So here's the next directive. X on. So it's similar to Vue. V on. X on. You can specify any browser event. In our case, we want to listen for a click and then it'll run this JavaScript when you click. And just to be super clear, what's going inside of these quotations, this is just a JavaScript expression. So you can put any valid JavaScript, even stuff that needs the window or document object. So we can say, alert, hey, when we unclick that button. And, oh, let me refresh the page. We hit plus and then we get hey. Okay? So we also have access to the state inside this button. So we can say count plus plus to increment the state.

3. Introduction to Alpine.js Components

Short description:

We'll also add an X on click, count minus minus, to decrement that state. If you're familiar with Vue.js and V on, you can use the shorthand syntax. That's the hello world of Alpine components. You express data for the component's state, listen for events, and run JavaScript inside it. Alpine is a lightweight framework that uses mutation observer and simple DOM manipulations.

And we'll also add an X on click, count minus minus, to decrement that state. And if you're familiar with Vue.js and V on, you can also use the shorthand syntax that Vue makes available to you. Just at click, count plus plus and count minus minus. Okay? We refresh and now we hit plus and we hit minus. And that's it. That's the hello world of Alpine components. It's extremely simple. You express some data that the component is going to use as its state and then you can listen for events and run JavaScript inside of it. And you can also bind pieces of the template to that data and it will all react automatically. I should note that Alpine is a really lightweight framework. I meant it to be extremely robust. So it doesn't actually use a virtual DOM or anything. It uses mutation observer and simple DOM manipulations to make this stuff happen.

4. Introduction to Alpine Directives

Short description:

We just introduced three directives: X data, X on, and X text. Alpine is a collection of attributes that allow you to compose behavior directly in your markup. It has 13 directives and 6 magic properties. Alpine is like Tailwind for JavaScript, where you put your behavior directly in your markup. Let's move on to the next directive, xmodel, which is similar to vmodel in Vue. We'll create a simple Twitter clone with a Tweet box and a character counter. By using xmodel, we can bind the value of Tweet to the input element.

Okay. So we just introduced you to three different directives. The X data directive, I also introduced you to X on for listening for events. And I also introduced you to X text. So Alpine is just this. Alpine is a collection of attributes that you can add to your HTML to basically compose behavior directly in your markup.

So there's actually 13 directives. That's the entirety of Alpine. If you go to the docs, the entirety of Alpine is 13 directives and 6 magic properties that we'll get to in a little bit. We're not going to cover the entirety of Alpine today, but we'll cover the basics.

And the idea with Alpine is that it's behavior mixed into your markup, similar to how like a library, a CSS library like Tailwind or I'm trying to think of the other utility libraries where you basically compose your styling directly in your markup, where before you were extracting classes to separate files. So Alpine is a similar concept. It's like Tailwind for JavaScript where you're putting your behavior directly inside your markup.

Okay, so let's keep going. Let's look at our next directive is going to be xmodel. So xmodel, if you're familiar with Vue, is very similar to vmodel. And we're going to create a different example. We'll make a text area. And this is going to be kind of a like world's simplest Twitter clone ever. The idea is that we're going to have like a little Tweet box. And then as we type in, sorry, here we go. What is happening to my computer. Okay, so here's our Tweet box. And then as we type into it, we want a character counter, just like on Twitter.

Okay, so here's our div. Let's make this a Alpine component with x data. And we're going to have our property. Our data property is going to be tweet. And we'll start off with the value of, say, something. Okay? Now, if we say x model Tweet, what we're telling Alpine is to bind the value of Tweet to the value of this input element and vice versa.

5. Introduction to Alpine.js Expressions and XBind

Short description:

When the text area changes, the data will change. This is two-way data binding. The expressions in Alpine.js are plain JavaScript. You can put any JavaScript you want inside these expressions. You can use the data from the component in the expressions. To limit the Tweet to 20 characters, we use XBind to conditionally add and remove the red class based on the Tweet length.

When the text area changes, the data will change. So this is two way data binding that you're familiar with from old Angular and also Vue.js. So if we refresh, there we go. The text area now says, say something. And we can use our x text from before to bind the value of Tweet to this div. So let's say x text Tweet. Okay? Refresh. And now we have say something and say something. And if we change it, it's going to update in real time because it's completely reactive.

And also, to reiterate that inside of these expressions, this is plain JavaScript. So we can say Tweet.toUpperCase, refresh, and now everything is going to be toUpperCased. I think that's something that takes a little bit of time to sink in. That even in Vue.js or another framework like that, you're used to extracting things to separate methods or computed properties and just referencing those inside these expressions. With Alpine, you're totally free to put in any JavaScript you want inside of these expressions, and you're encouraged to. All right. So instead of Tweet.toUpperCase, we're going to say Tweet.length to get the length of this Tweet. So we start off with say something, as we change this, the length updates. So there it is. Super simple.

Now let's take it a little bit further and say that we want the Tweet to be limited to 20 characters. But if you type over 20, the Tweet count turns red, okay? So let's make a class to make that Tweet count red. Just going to add a style tag up at the top, and inside the style tag a class called red that turns the color to red, okay? And now if we apply this class to this div, so class equals red, and refresh the page, we then have our red character count. But what we want to do is conditionally add and remove this red class depending on the Tweet length. So to change attributes, here's our next property or our next attribute in Alpine, XBind. You can XBind any attribute in HTML. Could be class, could be style, could be disabled, whatever you want. So you can XBind class, and then here is just another JavaScript expression, so we could concatenate re plus d and refresh, and it's going to be red because it's a JavaScript expression that gets evaluated. And of course, you can use the data from the component inside of these expressions. So let's say Tweet.length. If Tweet.length is greater than 20, then we want to make this the red class.

6. Introduction to Alpine.js Directives and XInit

Short description:

If not, we want to make it an empty class. In Alpine, it's x bind. Same thing here. If you want to use the shorthand syntax, you can just use colon, class. The next directive is called Xinit. It's the only lifecycle hook in Alpine. Anything inside Xinit gets run on initialization of Alpine. It's a nice little hook to run JavaScript when Alpine is initialized. Alpine is like a Swiss army knife for JavaScript. One common use case is using it to control and initialize other third-party libraries. Let's turn an input element into a date picker.

If not, we want to make it an empty class, okay? So we have 14 characters, and as we type, we get to 20, and bam. Now it's red and it's totally reactive. And just like in Vue.js, like in Vue, there is V bind. In Alpine, it's x bind. And in Vue, you can leave off the V bind and just use the colon. Same thing here. If you want to use the shorthand syntax, you can just use colon, class.

So there we go. Let's move on to another example. The next directive that I want to show you is called Xinit. This is basically the only lifecycle hook in Alpine. So any Alpine component, let's say we add X data. And then an empty object. And then we'll say Xinit. Now anything inside Xinit is just going to get run on initialization of Alpine. So we can say alert. Hey. Okay. And now we refresh the page and you guessed it. Hey is just going to show up. So it's very simple. It's just a nice little hook to run JavaScript when Alpine is initialized.

So one of the common areas that I do things like this, like Xinit, notice I don't even have a stateful data object. Alpine is like, it's like a Swiss army knife for JavaScript. For me, I use it for all sorts of things. And one of the really common use cases for me is using it to control and initialize other third-party libraries. So let's say that I wanted to take an input element and turn it into a date picker. So right now let's get rid of that. Hey, so we don't have to see that every time we refresh. So we have this input element and let's say that we want this to be a date picker, but we want to pull in a library to make that happen.

7. Introduction to Picaday and xref Attribute

Short description:

Picaday is a fantastic JavaScript date picker that is super lightweight and has no dependencies. To install it, simply add the Picaday JavaScript and CSS to your project. To initialize it, use the alpine-xinit property and the xref attribute to access elements without using query selectors.

So we don't have to build it ourselves. So here's Picaday. It's a fantastic, a refreshing JavaScript date picker. Super lightweight, no dependencies. I love it.

So to install it, I already have a snippet so that I don't have to copy and paste it. So Picaday just has some JavaScript and CSS. And then to initialize it, normally, this is what you would do. You would add a script tag, or maybe this would be in your JavaScript bundle. And you would say new Picaday, pass in an object with a value called field, and then document.querySelector, you know, that element that you want to turn into a date picker out of the DOM like this.

Okay. And now if we refresh our page, we click in the input, and now we have a date picker. So that's really nice. But because we want this to run on initialization, we can just stick this inside of our alpine-xinit property. One of the benefits of this is that you don't have to, normally you would have to do something like document.addEventListener, DOMContentLoaded, or onReady or something like that. And because it's running when alpine is initialized, it's just going to run in the right order anyway. Okay. So we new pick a day and that totally works, but we have this document.querySelector right here.

So let me introduce you to the next attribute, xref. So we're using document.querySelector, which is fine, but input, you know, obviously in any other app, there's multiple inputs. This isn't going to be deterministic. So maybe you would end up doing something like date picker, like use an ID, but then maybe you want to have multiple on the same page and you run into ID collisions, whatever. I loved the concept of refs from views. So I brought it over to Alpine. In view, you could do something like this ref input. And then from any JavaScript expression, you could say refs.input and access that element without doing the whole query selector thing. So in Alpine, it's xref input and then refs.input. And now let's refresh and make sure that worked. Okay, there we go. So I use this all the time.

8. Cleaning Up an Alpine Component

Short description:

To clean up the component, remove the value and use xdata instead of data property. Remove the unnecessary div and inline the expression. Get rid of xref and use the magic property $L. Alpine is great for small JavaScript tasks and third-party libraries.

Like sometimes I'll make an Alpine component just to use refs so that I can pull things out of the DOM more predictably, programmatically, whatever you want to call it. All right, so let's clean this component up a little bit. If you're not actually using the data property, you can get rid of the value and just use xdata to shorten it up a bit. And I'll say that we don't even need this div. We can take this entire expression and we can pop it inline right here, okay? And that cleans it up. Now, it's just a one liner. And finally, we can also get rid of this xref completely because there's another magic property in Alpine called $L. And $L is going to give you the current element of the Alpine component. So here we go. Let's make sure this works. Refresh, hit, and there we have our nice little date picker in one line of code. It's directly inline. The behavior is entirely co-located with the markup that it's concerned with. And we added literally this much JavaScript to initialize a date picker. So I use Alpine for all sorts of little JavaScript tasks like third-party libraries like this date picker. Awesome.

9. Introduction to xshow Directive

Short description:

The final directive I want to show you is xshow, which is perfect for dropdowns. I created Alpine.js because dropdowns and modals are surprisingly hard with vanilla JavaScript. Alpine started as a simple framework for creating dropdowns and modals, but it evolved into much more.

So the final directive that I wanna show you is called xshow. So naturally a good example for xshow is a dropdown. And honestly, I wrote Alpine because dropdowns and modals are actually surprisingly hard with vanilla JavaScript. I got so used to using vue.js, I had forgotten what it's like, and then you go to create something simple and you realize that it's just harder than you want it to be. And then you go back to something like vue. So Alpine initially started that, I want a framework that I can easily make dropdowns and modals and toggles and things like that. And then it turned into this, of course.

10. Creating an Alpine Dropdown

Short description:

Let's create a dropdown with Alpine.js. Initialize the component with the dropdown contents hidden by default. Listen for a click on the show dropdown button to open the dropdown. To hide the dropdown, add a modifier called away and set open to false when clicking away from the element.

So let's create our little dropdown. This is going to be our show dropdown button, and then this is going to be our dropdown contents. Let's take a look at those on the page. Show dropdown and dropdown contents.

So what we want to happen is we want dropdown contents hidden by default. So let's first initialize this component. So xdata, and this is going to be open, is false. And now, dropdown contents, we can bind to that Boolean with xshow. We'll say xshow, open. And remember, this is just another JavaScript expression. You could put, you could literally hard code true in here. You could do whatever you want. Call a method, doesn't matter. So xshow, open. So now, if we refresh, this should actually go away, and it does.

So now we want to listen for a click on show dropdown, set open to true, and it should just react. So let's do that. So we'll listen for a click and then we'll say open equals true. Okay, refresh. And now, if I hit show dropdown, it opens. Perfect. Next question is how do we hide the dropdown? So we could make this a toggle, so that when we click this again, it hides it. But in a lot of cases like this, with dropdowns and modals, you want to be able to click away from the thing that's shown as a way of hiding it. And so to do that is actually kind of annoying. So I added a little helper inside of Alpine. If we listen for a click on the dropdown content itself, we can add a modifier called away. So we can say add click dot away. And now we're saying when we click away from this element, run this JavaScript and we'll set open equal to false. So check it out. Refresh, we show dropdown.

11. Handling Dropdown Events and Transitions

Short description:

Now we click away and dropdown is now hidden. Let's say we can listen for a key down event. I love listening for key down events in Alpine and Vue because they make it so easy. We can listen for the escape key to hide the dropdown at the whole document level. Another handy modifier is transition, which provides a nice transition in and out for the dropdown.

Now we click away and dropdown is now hidden. Perfect. So you get this complex event delegation behavior. If you've ever tried to implement this yourself, it's a little bit complex and you just get it out of the box.

So there we go. Let's do another one. Let's say we can listen for a key down event. I love listening for key down events in Alpine and Vue because they make it so easy. You can say at key down dot escape. And now we're listening for the escape key to hide that modal. Or sorry, the dropdown. It could be modal, whatever. Let me show it.

Now I want to hit escape and hide it. So if I hit escape, notice that while nothing happens and then show dropdown gets kind of this focus outline. So that's because we're listening for the escape key on this element. And what we really want to do is listen for the escape key at the whole document level so that when we hit escape anywhere on the page, it's going to hide it. So we can do that with another really handy modifier called a window. You can add dot window to any event listener and it will then listen at the window level. So let's refresh. We show dropdown, we hit escape and now we hit it.

So let's keep going with these convenience modifiers. For X show, I also added another one called transition. So we can say X show dot transition and now when we show dropdown, we get a nice transition in and transition out. And we're on zoom so it's possible you didn't even see that. You can configure it with more modifiers. So let's say we'll make this 2,000 milliseconds long. So it's gonna be a full two second transition show dropdown. And now it transitions in with opacity and scale for two seconds and then it'll transition out. And I really sweated the details over this transition system.

12. Alpine.js Customization and Final Thoughts

Short description:

Alpine.js is a robust framework that allows for customization of transitions and provides the full power of V transition and tailwind utility classes. You can extract logic into separate JavaScript files or script tags by exposing functions and creating methods. Alpine.js is a JavaScript Swiss army knife, weighing only seven and a half kilobytes and as simple as a CDN link. For more information, visit the Alpine.js repository for helpful examples.

It's pretty robust and I used all the defaults of Material Designs motion specifications. So it's really well thought out. You can also customize. You can say only transition in, only transition the opacity, all sorts of stuff like that. And if you're from view and you're used to V transition and using like tailwind utility classes, there's also X transition which works the exact same way and gives you the full power.

Okay. So that's XShowDropDownContents. The final step here is, let's say you're repeating things around your expressions and maybe you want to extract some of this logic into a separate JavaScript file. Maybe the markup mixed with behavior is a little bit too much for you. Although, I'd love a good expression right in line. Let's say that that's the case. You can always extract this JavaScript into a separate file or a script tag by exposing a function. So let's expose a function called dropdown that returns a piece of data. And that piece of data is open, false. Okay. And so here we can actually run this function, dropdown, and that is going to give that component the data. And additionally, you can create methods. So we could say show, and then equals true. And now open equals true could then just reference the show method. And if we refresh, we hit ShowDropDown, and there we go.

So that is Alpine. We've only gone through eight of the directives. But there's also XIF, there's X4. There's lots of other power for you. It is my ode to simplicity and minimalism. It's my JavaScript Swiss army knife. It's seven and a half kilobytes of JavaScript and as simple as a CDN link. So if you're interested, go over to the Alpine.js repository and dig around all the documentations right in there. There's a bunch of helpful examples. And that's it.

13. Conclusion and Course Announcement

Short description:

I work on Liveware and Alpine full-time. If you use Alpine and you're really into it, head over to my sponsor page and give me a sponsorship. It means the world to me. I'm going to be launching a course on VS code. I started an email list at where I share VS code workflow tips. This has been Alpine JS. Thank you for watching. Happy coding!

Hopefully you really like it. And I should say that I work on this stuff full-time. I work on Liveware and Alpine full-time. And I basically rely entirely on GitHub sponsors for my income. So if you use Alpine and you're really into it, head over to my sponsor page and give me a sponsorship. It means the world to me. It's what allows me to do these things.

And also as another form of generating revenue so I can build this stuff all day is I'm going to be launching a course on VS code. So I do a lot of screencasting and a lot of people say, you know, I love your setup, your key bindings, all this stuff. How do you set it up? What extensions do you use? And it turns out I'm pretty opinionated about my VS code setup. So I started an email list. And if you care, go to and you can sign up for this email list. I basically start off like, here's VS code out of the box. It's kind of an eyesore, very distracting. And here's how we get to something more minimal and clean. And I go deep on a lot of VS code workflow tips. So if you give me your email, I'll send you stuff right away. You'll get a bunch of tips right away. And then eventually I'll put it into a course. So if you're interested in that, check that out.

Again, this has been Alpine JS. Thank you for watching. I hope you use it. And happy coding. Thank you. Excellent stuff, Caleb. Amazing. You can't see me, but the viewers can. I've got a microfiber thing on my head. Yeah, because my brain literally exploded.

14. Caleb Portheo's Perspective on Alpine Performance

Short description:

Caleb Portheo mentioned smaller file sizes as Alpine's main selling point, but he believes that the most important thing is developer experience and productivity. He is currently working on the next major version of Alpine, with performance as the main goal. The current version is already fast, as it utilizes native browser APIs instead of virtual dom compiling and patching.

All the goodness there. Thank you. Luckily, I had so much brain that even though it exploded, I can still continue.

Caleb, please join me on the stage of interrogation where I shall mercilessly interrogate your questions until you weep or beg for mercy. Perfect.

So, viewers, folks, that was Caleb Portheo because I have rechristened him. That's right. So every time you call him by his new name Portheo, I'm on 10%. I'm going to be a millionaire.

Caleb, lots of questions from the community for you. I'm trying to make sure I don't ask all the performance related ones so you don't end up repeating yourself too much. But you mentioned smaller file sizes as Alpine's main selling point. How does it compare with React and Vue performance-wise? I don't think it's its main selling point. I will say that. I think in general, the whole file size thing is a bit of a distraction and I fall prey to it totally, because I idolize that too. But in reality, the most important thing to me is developer experience and productivity. What is it like to use the tool? Does it make you more productive? Does it feel good? Does it feel simple? Is it aesthetically pleasing? Those are the things that I care about. Top priority. That's its selling point. File size is a fun little side effect that I get to say, one single character file size, minified and g-zipped. So I will say that. That's the disclaimer. How does it compare performance wise? I started digging into this. I'm working on the next major version of Alpine and performance is going to be the main goal in the next major version. The goal of this version was to get the API where I wanted it. And I will say that it is pretty darn fast because what's under the hood of Alpine, there's no virtual dom compiling and patching or anything like that. It's all native browser APIs. I don't know how to create a virtual dom framework, so I started the most minimal that I could. I was like, well, so an xtext directive, that would take the element and set its dot intertext to that value. So I started there and then built up.

15. Caleb Portheo on Alpine Performance

Short description:

The prototype version for v3 is faster than view 2. Alpine isn't a full front end. It's not an SPA tool. You're sprinkling in behavior. Performance is one of those things that I love to geek out on. You can use PHP or whatever to produce your HTML and then sprinkle in as much or as little jQuery as you want to do the grunt work of toggling things and mucking about with individual DOM elements.

I will say that the prototype version for v3 is faster than view 2, which I imagine who knows what view 3. And I don't mean to compare, at this level of performance comparison, I made an x4, which is the same as v4, of like, I don't know, however many thousands of rows, like 30 or 40,000. And then you start to really notice the difference. And yeah, because I have the advantage of not dealing with a template compiler. So that's nice. It allows me to kind of only update the pieces of the dom that need to update when a piece of data changes. So the next version of Alpine, I'm super excited to get really nerdy and see how far I can push the performance gains. And I think it's pretty far. Yeah, so that would be my answer. Pretty vague, but yeah.

No, no, that's good. So file size aside, you're not going to, I'm not going to give my users a performance hit if I choose to use Alpine for its better developer experience. Yeah, no. And the majority of things people are doing is toggling stuff. Like you're making a drop down and a modal and a little slider. And this is great for that. That's sort of the Alpine ethos is Alpine isn't a full front end. It's not an SPA tool. You're not going to build your entire front end system with Alpine. You're going to do it with, you know, whatever a static site generator or a Rails app or Laravel app or Django or Express or something that produces HTML from the backend. And in that case, you're sprinkling in behavior. It's JavaScript sprinkle. So performance is one of those things that I love to geek out on. But in reality, I could get away with murder. And people wouldn't even really know unless they were doing things that maybe Alpine is not even good for, like subbing out your entire front end template for Alpine. So I don't know if you heard in my intro, I was extolling the virtues of jQuery, but would it be fair to say this is kind of like that? I can use PHP or whatever to produce my HTML and then sprinkle in as much or as little jQuery as I want to do the grunt work of toggling things and mucking about with individual DOM elements. Exactly. Yes. And that's where it was born out of is me being a Laravel developer, kind of going back to those ways. So if you're in a back end context MVC type framework, like Rails or Laravel or something like that, Alpine is just that.

16. Alpine.js Rendering and Mutation

Short description:

Alpine.js sits between jQuery and Vue, offering reactivity without the need for compilation or webpack. It allows for behavior sprinkling and works well with Laravel. When mutating DOM elements, Alpine updates the DOM based on the mutated data. The upcoming version of Alpine will perform actions during the initial render, optimizing the execution of JavaScript. Mutation observer is used to handle additions and removals of DOM elements.

And it's a lot of... So it kind of sits in between jQuery and something like Vue, where it gives you some of the fancy reactivity of Vue, but it gives you the simplicity of jQuery CDN. There's no need to compile. There's no webpack. There's nothing like that. You don't have to do that stuff. And it's not even recommended that you do it because you're sprinkling in behavior here and there.

So yeah. Interesting you talked about Laravel because here in my home city of Birmingham in the UK there's a really nice web shop called Jump24. I'm not trying to push them. It's just I drink a beer with their chief execs at times. And when I tweeted about this Smashing Mag article, he said, oh, we love that framework. It works so well with Laravel. I think not realizing that you were connected to the Laravel project. But enough about my personal beehing on it. Let's move on to another question.

You mentioned there's no vDom, Virtual Dom. So Vlad Stavisky asks, how does it work for rendering if you mutate a few Dom elements at the same time? Does Alpine re-render them all at the same time or successively? Yeah, so there's a couple of different answers to this. I guess, what do you mean by mutate two different elements at the same time? Because I think in general, the Alpine paradigm is you're mutating the data and then the Dom updates with the data. Does that make sense? So like in our counter example, you would change count and then the Dom would update. So right now, I crawl the Dom. For that initial render, I'm crawling the Dom. And I'm setting things as I crawl through it. The next version of Alpine, I'm pretty pumped about, because that first initial render, as I crawl, I perform actions. So when I get to, let's say, a div with xtextcount, whatever, when I get to that, I wrap that expression where I actually execute .innertext where I set it in a observable function. So now anytime data that was used to drive out that .innertext changes, only that will execute. So only those pieces of JavaScript will execute. There's no virtual Dom rendering or anything like that. Then I use mutation observer to reinitialize things that are added after the fact or remove things that are removed. It's robust.

17. Robustness and Localization in Alpine.js

Short description:

I built Alpine.js to be robust and resilient, allowing for manipulation of the DOM without issues. When discussing it, it's better to say you sprint over the DOM rather than crawl. As for internationalization and localization, Alpine.js primarily focuses on composing behavior within the HTML, while the backend, such as Laravel, handles the actual localization. Unfortunately, we're out of time for more questions. Thank you for your participation!

I built it to be really robust. It uses mutation observer. A lot of things are computed at runtime, so you can use it with something else. You can manipulate things, and it's not all going to blow up in your face. That's kind of a goal for me. I want it to be something that's a little more resilient than an entire virtual Dom-driven thing that owns the Dom. I want it to be something that manipulates the Dom as it needs.

Gotcha. Interesting you say when you crawl, you do actions, because my lady friends tell me that when I'm drunk, I'm much the same, actually. Is that right? Yeah. A little bit of a PR tip. Don't say you crawl over the Dom. Say you sprint over the Dom. Give the idea that you're not slow, like straight from the outside. Yeah, right. Good call. Good marketing tip. Yeah. No worries. Again, 10% for that. Of course.

Another interesting question, not about deep tech or performance. Naomi Meyer says, great talk, Caleb, with an emoji that looks like a carrot, but I suspect it might be some kind of party thing. I've got terrible eyesight. And then she says, does Alpine support internationalization and localization functionality or components? Yeah, I guess I'll say no. I'll say that, like, I'm using Alpine with Laravel most of the time, and Laravel has really good localization support, so that's kind of taken care of with Laravel. Is that the question? Does that answer the question? Yeah. Yes, I think it does. So what you're saying is no, it doesn't, because that's not its goal, it's the thing that produces the HTML is the actual goal. Is that a reasonable pattern? Yeah, so like the backend is the thing producing the HTM... Alpine is the thing composing behavior within that HTML, so let's say if I'm in Laravel and I want to localize a string, I would do that on the backend and then I could toggle that string with Alpine on the frontend, but the actual localization would have happened further upstream. And we have many more questions, but the voice of God in my head is telling me we're out of time, Caleb. Thank you so much for answering the questions, and please, if you could go to the Zoom Room paid ticket holders, you get a chance to interrogate Caleb. I hope I didn't make you cry with my ruthless questions there, Caleb. I'm holding it back. Thank you so much. Good man, good man.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
JSNation 2022JSNation 2022
28 min
Full Stack Documentation
Interactive web-based tutorials have become a staple of front end frameworks, and it's easy to see why — developers love being able to try out new tools without the hassle of installing packages or cloning repos.But in the age of full stack meta-frameworks like Next, Remix and SvelteKit, these tutorials only go so far. In this talk, we'll look at how we on the Svelte team are using cutting edge web technology to rethink how we teach each other the tools of our trade.
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
JSNation 2023JSNation 2023
28 min
SolidJS: Why All the Suspense?
Solid caught the eye of the frontend community by re-popularizing reactive programming with its compelling use of Signals to render without re-renders. We've seen them adopted in the past year in everything from Preact to Angular. Signals offer a powerful set of primitives that ensure that your UI is in sync with your state independent of components. A universal language for the frontend user interface.
But what about Async? How do we manage to orchestrate data loading and mutation, server rendering, and streaming? Ryan Carniato, creator of SolidJS, takes a look at a different primitive. One that is often misunderstood but is as powerful in its use. Join him as he shows what all the Suspense is about.
React Summit Remote Edition 2021React Summit Remote Edition 2021
43 min
RedwoodJS: The Full-Stack React App Framework of Your Dreams
Tired of rebuilding your React-based web framework from scratch for every new project? You're in luck! RedwoodJS is a full-stack web application framework (think Rails but for JS/TS devs) based on React, Apollo GraphQL, and Prisma 2. We do the heavy integration work so you don't have to. We also beautifully integrate Jest and Storybook, and offer built-in solutions for declarative data fetching, authentication, pre-rendering, logging, a11y, and tons more. Deploy to Netlify, Vercel, or go oldschool on AWS or bare metal. In this talk you'll learn about the RedwoodJS architecture, see core features in action, and walk away with a sense of wonder and awe in your heart.

Workshops on related topic

JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
Featured WorkshopFree
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)
Node Congress 2021Node Congress 2021
128 min
Learn Fastify One Plugin at a Time
Fastify is an HTTP framework for Node.js that focuses on providing a good developer experience without compromising on performance metrics. What makes Fastify special are not its technical details, but its community which is wide open for contributions of any kind. Part of the secret sauce is Fastify plugin architecture that enabled developers to write more than a hundred plugins.This hands-on workshop is structured around a series of exercises that covers from basics "hello world", to how to structure a project, perform database access and authentication.
JSNation 2023JSNation 2023
66 min
Build a Universal Reactive Data Library with Starbeam
This session will focus on Starbeam's universal building blocks. We'll use Starbeam to build a data library that works in multiple frameworks.We'll write a library that caches and updates data, and supports relationships, sorting and filtering.Rather than fetching data directly, it will work with asynchronously fetched data, including data fetched after initial render. Data fetched and updated through web sockets will also work well.All of these features will be reactive, of course.Imagine you filter your data by its title, and then you update the title of a record to match the filter: any output relying on the filtered data will update to reflect the updated filter.In 90 minutes, you'll build an awesome reactive data library and learn a powerful new tool for building reactive systems. The best part: the library works in any framework, even though you don't think about (or depend on) any framework when you built it.
Table of contents- Storing a Fetched Record in a Cell- Storing multiple records in a reactive Map- Reactive iteration is normal iteration- Reactive filtering is normal filtering- Fetching more records and updating the Map- Reactive sorting is normal sorting (is this getting a bit repetitive?)- Modelling cache invalidation as data- Bonus: reactive relationships
React Advanced Conference 2022React Advanced Conference 2022
81 min
Build a Product Page with Shopify’s Hydrogen Framework
Get hands on with Hydrogen, a React-based framework for building headless storefronts. Hydrogen is built for Shopify commerce with all the features you need for a production-ready storefront. It provides a quick start, build-fast environment so you can focus on the fun stuff - building unique commerce experiences. In this workshop we’ll scaffold a new storefront and rapidly build a product page. We’ll cover how to get started, file-based routing, fetching data from the Storefront API, Hydrogen’s built-in components and how to apply styling with Tailwind.You will know:- Get started with the hello-world template on StackBlitz- File-based routing to create a /products/example route- Dynamic routing /products/:handle- Hit the Storefront API with GraphQL- Move the query into the Hydrogen app- Update the query to fetch a product by handle- Display title, price, image & description.- Tailwind styling- Variant picker and buy now button- Bonus if there’s time: Collections page
Prerequisites: - A Chromium-based browser (StackBlitz)- Ideally experience with React. A general web development background would be fine.