# Alpine.js


[](https://alpinejs.codewithhugo.com/chat/)
Alpine.js offers you the reactive and declarative nature of big frameworks like Vue or React at a much lower cost.
You get to keep your DOM, and sprinkle in behavior as you see fit.
Think of it like [Tailwind](https://tailwindcss.com/) for JavaScript.
> Note: This tool's syntax is almost entirely borrowed from [Vue](https://vuejs.org/) (and by extension [Angular](https://angularjs.org/)). I am forever grateful for the gift they are to the web.
## Translated documentation
| Language | Link for documentation |
| --- | --- |
| Arabic | [**التوثيق باللغة العربية**](./README.ar.md) |
| Chinese Simplified | [**简体中文文档**](./README.zh-CN.md) |
| Chinese Traditional | [**繁體中文說明文件**](./README.zh-TW.md) |
| German | [**Dokumentation in Deutsch**](./README.de.md) |
| Indonesian | [**Dokumentasi Bahasa Indonesia**](./README.id.md) |
| Japanese | [**日本語ドキュメント**](./README.ja.md) |
| Portuguese | [**Documentação em Português**](./README.pt.md) |
| Russian | [**Документация на русском**](./README.ru.md) |
| Spanish | [**Documentación en Español**](./README.es.md) |
| Turkish | [**Türkçe Dokümantasyon**](./README.tr.md) |
| Français | [**Documentation en Français**](./README.fr.md) |
| Korean | [**한국어 문서**](./README.ko.md) |
## Install
**From CDN:** Add the following script to the end of your `
` section.
```html
```
That's it. It will initialize itself.
For production environments, it's recommended to pin a specific version number in the link to avoid unexpected breakage from newer versions.
For example, to use version `2.8.2` (latest):
```html
```
**From npm:** Install the package from npm.
```js
npm i alpinejs
```
Include it in your script.
```js
import 'alpinejs'
```
**For IE11 support** Use the following scripts instead.
```html
```
The pattern above is the [module/nomodule pattern](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) that will result in the modern bundle automatically loaded on modern browsers, and the IE11 bundle loaded automatically on IE11 and other legacy browsers.
## Use
*Dropdown/Modal*
```html
Dropdown Body
```
*Tabs*
```html
Tab Foo
Tab Bar
```
You can even use it for non-trivial things:
*Pre-fetching a dropdown's HTML content on hover.*
```html
Loading Spinner...
```
## Learn
There are 14 directives available to you:
| Directive | Description |
| --- | --- |
| [`x-data`](#x-data) | Declares a new component scope. |
| [`x-init`](#x-init) | Runs an expression when a component is initialized. |
| [`x-show`](#x-show) | Toggles `display: none;` on the element depending on expression (true or false). |
| [`x-bind`](#x-bind) | Sets the value of an attribute to the result of a JS expression. |
| [`x-on`](#x-on) | Attaches an event listener to the element. Executes JS expression when emitted. |
| [`x-model`](#x-model) | Adds "two-way data binding" to an element. Keeps input element in sync with component data. |
| [`x-text`](#x-text) | Works similarly to `x-bind`, but will update the `innerText` of an element. |
| [`x-html`](#x-html) | Works similarly to `x-bind`, but will update the `innerHTML` of an element. |
| [`x-ref`](#x-ref) | Convenient way to retrieve raw DOM elements out of your component. |
| [`x-if`](#x-if) | Remove an element completely from the DOM. Needs to be used on a `` tag. |
| [`x-for`](#x-for) | Create new DOM nodes for each item in an array. Needs to be used on a `` tag. |
| [`x-transition`](#x-transition) | Directives for applying classes to various stages of an element's transition. |
| [`x-spread`](#x-spread) | Allows you to bind an object of Alpine directives to an element for better reusability. |
| [`x-cloak`](#x-cloak) | This attribute is removed when Alpine initializes. Useful for hiding pre-initialized DOM. |
And 6 magic properties:
| Magic Properties | Description |
| --- | --- |
| [`$el`](#el) | Retrieve the root component DOM node. |
| [`$refs`](#refs) | Retrieve DOM elements marked with `x-ref` inside the component. |
| [`$event`](#event) | Retrieve the native browser "Event" object within an event listener. |
| [`$dispatch`](#dispatch) | Create a `CustomEvent` and dispatch it using `.dispatchEvent()` internally. |
| [`$nextTick`](#nexttick) | Execute a given expression AFTER Alpine has made its reactive DOM updates. |
| [`$watch`](#watch) | Will fire a provided callback when a component property you "watched" gets changed. |
## Sponsors
**Want your logo here? [DM on Twitter](https://twitter.com/calebporzio)**
## Community Projects
* [Alpine Devtools](https://github.com/HugoDF/alpinejs-devtools)
* [Alpine Magic Helpers](https://github.com/KevinBatdorf/alpine-magic-helpers)
* [Alpine Weekly Newsletter](https://alpinejs.codewithhugo.com/newsletter/)
* [Spruce (State Management)](https://github.com/ryangjchandler/spruce)
* [Awesome Alpine](https://github.com/ryangjchandler/awesome-alpine)
* [Turbolinks Adapter](https://github.com/SimoTod/alpine-turbolinks-adapter)
### Directives
---
### `x-data`
**Example:** `
...
`
**Structure:** `
...
`
`x-data` declares a new component scope. It tells the framework to initialize a new component with the following data object.
Think of it like the `data` property of a Vue component.
**Extract Component Logic**
You can extract data (and behavior) into reusable functions:
```html
// Dropdown
```
> **For bundler users**, note that Alpine.js accesses functions that are in the global scope (`window`), you'll need to explicitly assign your functions to `window` in order to use them with `x-data` for example `window.dropdown = function () {}` (this is because with Webpack, Rollup, Parcel etc. `function`'s you define will default to the module's scope not `window`).
You can also mix-in multiple data objects using object destructuring:
```html
```
---
### `x-init`
**Example:** ``
**Structure:** ``
`x-init` runs an expression when a component is initialized.
If you wish to run code AFTER Alpine has made its initial updates to the DOM (something like a `mounted()` hook in VueJS), you can return a callback from `x-init`, and it will be run after:
`x-init="() => { // we have access to the post-dom-initialization state here // }"`
---
### `x-show`
**Example:** ``
**Structure:** ``
`x-show` toggles the `display: none;` style on the element depending if the expression resolves to `true` or `false`.
**x-show.transition**
`x-show.transition` is a convenience API for making your `x-show`s more pleasant using CSS transitions.
```html
These contents will be transitioned in and out.
```
| Directive | Description |
| --- | --- |
| `x-show.transition` | A simultaneous fade and scale. (opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms)
| `x-show.transition.in` | Only transition in. |
| `x-show.transition.out` | Only transition out. |
| `x-show.transition.opacity` | Only use the fade. |
| `x-show.transition.scale` | Only use the scale. |
| `x-show.transition.scale.75` | Customize the CSS scale transform `transform: scale(.75)`. |
| `x-show.transition.duration.200ms` | Sets the "in" transition to 200ms. The out will be set to half that (100ms). |
| `x-show.transition.origin.top.right` | Customize the CSS transform origin `transform-origin: top right`. |
| `x-show.transition.in.duration.200ms.out.duration.50ms` | Different durations for "in" and "out". |
> Note: All of these transition modifiers can be used in conjunction with each other. This is possible (although ridiculous lol): `x-show.transition.in.duration.100ms.origin.top.right.opacity.scale.85.out.duration.200ms.origin.bottom.left.opacity.scale.95`
> Note: `x-show` will wait for any children to finish transitioning out. If you want to bypass this behavior, add the `.immediate` modifier:
```html
```
---
### `x-bind`
> Note: You are free to use the shorter ":" syntax: `:type="..."`.
**Example:** ``
**Structure:** ``
`x-bind` sets the value of an attribute to the result of a JavaScript expression. The expression has access to all the keys of the component's data object, and will update every-time its data is updated.
> Note: attribute bindings ONLY update when their dependencies update. The framework is smart enough to observe data changes and detect which bindings care about them.
**`x-bind` for class attributes**
`x-bind` behaves a little differently when binding to the `class` attribute.
For classes, you pass in an object whose keys are class names, and values are boolean expressions to determine if those class names are applied or not.
For example:
``
In this example, the "hidden" class will only be applied when the value of the `foo` data attribute is `true`.
**`x-bind` for boolean attributes**
`x-bind` supports boolean attributes in the same way as value attributes, using a variable as the condition or any JavaScript expression that resolves to `true` or `false`.
For example:
```html
```
This will add or remove the `disabled` attribute when `myVar` is true or false respectively.
Boolean attributes are supported as per the [HTML specification](https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute), for example `disabled`, `readonly`, `required`, `checked`, `hidden`, `selected`, `open`, etc.
> Note: If you need a false state to show for your attribute, such as `aria-*`, chain `.toString()` to the value while binding to the attribute. For example: `:aria-expanded="isOpen.toString()"` would persist whether `isOpen` was `true` or `false`.
**`.camel` modifier**
**Example:** `