DEV Community

Cover image for DaisyUI + Alpine.js + - the simple web app trio
Jbee -
Jbee -

Posted on

DaisyUI + Alpine.js + - the simple web app trio

Hello and welcome to this hands-on tutorial where we'll create a simple and interactive web app using DaisyUi, Alpine.js and

This guide is tailored for front-end developers looking to explore the smooth integration of DaisyUI's stylish components, Alpine.js's minimalist reactive framework, and the straightforward back-end capabilities of

Whether you're an experienced developer or just starting out, this tutorial will walk you through the essential steps of web app development and deployment.

The finished result of this Web App is shown in the screen shot below.

Buzzword generator screenshot
Check out a live example here

What you will learn from this tutorial


DaisyUI is a component library for Tailwind CSS, offering a range of pre-styled components for rapid UI development. It's perfect for developers who want to create elegant interfaces quickly without sacrificing the customizability that Tailwind provides.


Alpine.js is a minimalist JavaScript framework for adding interactive elements to your HTML. It's ideal for developers who need a lightweight, straightforward tool to enhance their website's UI with dynamic features and reactive data binding. is a serverless platform that simplifies backend development. It allows you to easily deploy serverless functions and APIs, focusing on your code while it handles the infrastructure, scaling, and maintenance.

OK, let's learn how to build the Web App.

Project Setup

We need to create a project directory for the source code files and initialize npm.

mkdir myproject && cd myproject
mkdir webapp
npm init -y
npm install codehooks-js
Enter fullscreen mode Exit fullscreen mode

Later we'll edit the package.json and add the deployment command for

Now, create the Web App source files. In the root directory create the two files index.jsand buzzwords.js for the server side code.

In the 'webapp' directory, create the two files for the client side code index.html and script.js. The touch command is a handy helper.

touch index.js buzzwords.js webapp/index.html webapp/main.js
Enter fullscreen mode Exit fullscreen mode Account Setup

Next you'll need to connect the local project directory to your project space.

Sign up for an account at, and create a new project, e.g. mywebapp.

Install the CLI.

npm install -g codehooks
Enter fullscreen mode Exit fullscreen mode

Login to your account.

coho login
Enter fullscreen mode Exit fullscreen mode

Connect your local web app project with your account/project.

coho init --empty
Enter fullscreen mode Exit fullscreen mode

Use the up/down keys to pick your project and database environment (default dev) from the list. The example project list from my personal account is shown below, where i pick mywebapp-okuc as the active project to host my Web App.

coho init
? Select project 
❯ mywebapp-okuc 
Enter fullscreen mode Exit fullscreen mode

Select your particular project and press enter, this will create a config.json file in your project directory with the unique project name.

Finally, your project directory should look like this after running the above commands successfully.

├── buzzwords.js
├── config-dev.json
├── index.js
├── package-lock.json
├── package.json
└── webapp
    ├── index.html
    └── main.js
Enter fullscreen mode Exit fullscreen mode

This concludes the (boring) tasks we must do to setup our project, let's move on with the fun stuff of developing the frontend and the backend.

Developing the Frontend (index.html)

The web app frontend is a really simple HTML page that uses DaisyUI for the looks and Alpine.js for the reactive dynamics.

In the <head> we include CDN links for Tailwind CSS, DaisyUI, and Alpine.js.

<!DOCTYPE html>
<html lang="en">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- Tailwind CSS and DaisyUI CDN -->
  <link href="^2.2.19/dist/tailwind.min.css" rel="stylesheet">
  <link href="^1.3.6/dist/full.css" rel="stylesheet">
  <!-- Alpine.js CDN -->
  <script src="//" defer></script>
  <!-- use /dev/index.html environment for development and test, for production remove and serve at root domain e.g. -->
  <base href="/dev/" />

  <div class="container mx-auto p-8">
    <h1 class="text-4xl font-bold text-center">Buzzword generator!</h1>
    <!-- bind x-data to messageStore -->
    <div x-data="messageStore" class="flex justify-center">
      <div class="card w-96 bg-base-100 shadow-xl">
        <div class="card-body">
          <h2 class="card-title">Buzz count <div class="badge badge-lg" x-text="bsCount"></div>
          <div class="toast toast-top toast-center">
            <div class="alert alert-info">
              <span x-text="message"></span>
          <div class="card-actions justify-end">
            <!-- call method to fetch new data and update page -->
            <button @click="getMessage()" class="btn btn-primary">Get Buzzwords</button>
  <script src="main.js"></script>

Enter fullscreen mode Exit fullscreen mode

Backend API Integration (main.js)

We'll use the Alpine.js powerful x-data directive to handle dynamic content and reactive binding. The client calls the server REST API /api/message, and the REST API returns a dynamic JSON object as a response to the client request.

The client side code webapp/main.js is shown below.

document.addEventListener('alpine:init', () => {'messageStore', () => ({
    message: 'Click the button to fetch a message ...',
    bsCount: 0,
    // init is called when document is ready
    init() {      
    // fetch json from the server public api
    async getMessage() {
      try {
        const response = await fetch('api/message', {
          headers: {
            'Content-Type': 'application/json'
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        // destruct json from server
        const { message, bsCount } = await response.json();
        // update local model
        this.message = message;
        this.bsCount = bsCount;
      } catch (error) {
        console.error('Error:', error);

Enter fullscreen mode Exit fullscreen mode

The next section shows how to create the server side for the REST API.

Backend Server Setup (index.js)

The server code is a simple backend that exposes one single public route GET /api/message and serve the webapp files from the webapp sub directory. The random "buzzwords" is generated by combining 3 arrays of random words imported from the buzzword.js file.

Note that we also use the build in Key Value datastore to increment the total count of generated buzzwords.

The complete server code is shown below.

* backend example app
import {app, datastore} from 'codehooks-js'
import { buzzwords1, buzzwords2, buzzwords3 } from './buzzwords';

function generateBS() {
  const word1 = buzzwords1[Math.floor(Math.random() * buzzwords1.length)];
  const word2 = buzzwords2[Math.floor(Math.random() * buzzwords2.length)];
  const word3 = buzzwords3[Math.floor(Math.random() * buzzwords3.length)];

  return `${word1} ${word2} ${word3}`;

// allow api access without api token
app.auth('/api/message*', (req, res, next) => {
  if (req.method === 'GET') {
  } else {
    next('Only GET is allow public access');

// api route for generating a buzzword message and a count
app.get('/api/message', async (req, res) => {
  const db = await;
  const bsCount = await db.incr('bsCount', 1)
  console.log('Count', bsCount)
  res.json({bsCount, message: generateBS()})

// serve the webapp directory on the / route
app.static({route: "/", directory: "/webapp"})

// bind to serverless runtime
export default app.init();
Enter fullscreen mode Exit fullscreen mode

In this simple example we combine the arrays of words from the buzzwords.js file shown below.

export const buzzwords1 = [
    "Blockchain", "Quantum", "Synergistic", "Big Data", ...

export const buzzwords2 = [
    "driven", "enhanced", "optimized", "integrated", ...

export const buzzwords3 = [
    "solutions", "platforms", "paradigms", "algorithms", ...
Enter fullscreen mode Exit fullscreen mode

Deployment Using Codehooks CLI

We'll use the Codehooks CLI for deployment. And to automate things we create script deploy commands in our package.json as shown below.

  "name": "mywebapp",
  "version": "1.0.0",
  "description": "My awesome webapp",
  "main": "index.js",
  "scripts": {
    "predeploy": "codehooks upload ./webapp",
    "deploy": "codehooks deploy"
  "dependencies": {
    "codehooks-js": "^1.1.10"
Enter fullscreen mode Exit fullscreen mode

The 'deploy' command will upload all files in the webapp directory to the server and then deploy your backend server (index.js) to the serverless cloud.

To deploy the complete web app and the backend API run:

npm run deploy
Enter fullscreen mode Exit fullscreen mode

Testing and Domain Configuration

You can access your deployed app and verify its functionality in several ways.

  • Run the coho info command to find your project URL, in my example project the URL is:, copy this into your browser and test the Web App
  • You can also add a custom domain (e.g. that you control by adding an A-Record or C-Record and point it to Codehooks. This generates a free SSL certificate with auto renew. (Check how to setup this in your admin settings in the Codehooks Studio App)
  • Test the server REST API with Postman or cUrl by calling the canonical URL for the API, e.g. curl --location ''
  • Coming soon! Use the built in random domain for development, in my example app the public domain is:

Concluding Thoughts

The tutorial aims to demonstrate the simplicity and efficiency of combining DaisyUI, Alpine.js, and in web development, guiding through each stage from setup to deployment. The final product is a dynamic web application capable of generating random messages, showcasing the power of these tools in creating responsive and interactive web applications.


Top comments (0)