DEV Community

Cover image for Getting started with Alpine.js and TypeScript
wtho
wtho

Posted on

Getting started with Alpine.js and TypeScript

Have you heard about Alpine.js? It feels like Vue, but lightweight. Yes, even more lightweight.

It is not pre-compiled, it uses HTML with custom (technically invalid) attributes and brings the webpage to live on load. Sounds basic? It might be, but it is also super simple.

<div x-data="{ open: false }">
    <button @click="open = true">Expand</button>

    <span x-show="open">
      Content...
    </span>
</div>
Enter fullscreen mode Exit fullscreen mode

I like to use it for small projects where I would have used JQuery if I was in 2010. It offers several simple ways of managing state, directly in html (see example above) or in a central store. It offers several directives, such as x-for, but also has an API to add your own directives. Checkout the docs for more information.

A whole new project

I cannot (or better: I do not want to) work on projects without TypeScript anymore. Let's see how we can setup a new project powered by Alpine.ts. We use Vite to quickly setup a new project with Hot Module Replacement and bundling capabilities:

npm init vite@latest
? Project name: › alpine-ts
? Select a framework: › vanilla
? Select a variant: › vanilla-ts

cd alpine-ts
npm install -S alpinejs
npm install -D @types/alpinejs

npm run dev
Enter fullscreen mode Exit fullscreen mode

Let's use Alpine in our src/main.ts:

import './style.css'

import Alpine from 'alpinejs'

// suggested in the Alpine docs:
// make Alpine on window available for better DX
window.Alpine = Alpine

Alpine.start()
Enter fullscreen mode Exit fullscreen mode

Here we already encounter the first problem: Alpine is not defined on window. Let's fix that with a declaration file src/global.d.ts:

import { Alpine as AlpineType } from 'alpinejs'

declare global {
  var Alpine: AlpineType
}
Enter fullscreen mode Exit fullscreen mode

Now we can code our app in TypeScript while using Alpine.js.

Let's use add some data and use it in the HTML:

// main.ts
import './style.css'
import Alpine from 'alpinejs'

window.Alpine = Alpine

Alpine.store('shop', {
  name: 'Alpine-Shop',
  products: ['Swiss Alp Chocolate', 'Car Alpine A110'],
})

Alpine.start()
Enter fullscreen mode Exit fullscreen mode
  <body>
    <div x-data>
      <h1>
        Welcome to the
        <span x-text="$store.shop.name">shop-name</span>
      </h1>
      <div>
        Here you can buy:
        <ul>
          <template x-for="product in $store.shop.products">
            <li x-text="product"></li>
          </template>
        </ul>
      </div>
    </div>
    <script type="module" src="/src/main.ts"></script>
  </body>
Enter fullscreen mode Exit fullscreen mode

Note: There is no Intellisense (yet) for the HTML like we are used to in other frameworks, but getting started with TypeScript is a first step in the right direction.

Bonus round: Tailwindcss

npm install -D tailwindcss @types/tailwindcss autoprefixer postcss
npx tailwindcss init
Enter fullscreen mode Exit fullscreen mode

Additionally, add to the main CSS file:

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
Enter fullscreen mode Exit fullscreen mode

And create a postcss.config.js in your project root:

module.exports = {
  plugins: [require('tailwindcss'), require('autoprefixer')],
}
Enter fullscreen mode Exit fullscreen mode

Now you can add your tailwind styles to your website. Thanks to tailwind's JIT mode, it will only bundle whichever classes you are actually using.

Wrapping up

That was pretty quick! If you have not started your next Micro-Project yet, I highly recommend giving Alpine.js a try.

Top comments (5)

Collapse
 
chrisheney profile image
Chris Heney

If you're getting this error:

[Failed to load PostCSS config: Failed to load PostCSS config (searchPath: /Users/admin/projects/govolt/govolt.ai): [ReferenceError] module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/Users/admin/projects/govolt/govolt.ai/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
ReferenceError: module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/Users/admin/projects/govolt/govolt.ai/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

Update your package.json file
Change this line: "type": "module",
To this: "type": "commonjs",

Then run yarn dev / npm run dev / pnpm dev or

Collapse
 
mvolkmann profile image
Mark Volkmann

I feel like there is some detail missing here. Where does the block of HTML go? I'm assuming not in src/main.ts. Do I need to create a file like index.html for that and add add script tag that refers to src/main.ts?

Collapse
 
mvolkmann profile image
Mark Volkmann

I see now that the HTML goes in the index.html file created by Vite.
That already contains a script tag for /src/main.ts.

Collapse
 
falselight profile image
YURII DE.

Thank you.

Collapse
 
paulinho_nas profile image
Eu acho que é Paulo!

Hey, thank you so much!
It helped me a lot, I didn't know this "Vite", again, thank you very much!