This guide will walk you through creating a Django project with DaisyUI styling without requiring Node.js. We'll create a simple two-page application to demonstrate DaisyUI components.
Prerequisites
- Python 3.8+ installed
- curl command available (for downloading files)
Step 1: Create Django Project
# Create a virtual environment
python3 -m venv .venv
# Activate virtual environment
# On Windows:
.venv\Scripts\activate
# On macOS/Linux:
source .venv/bin/activate
# Install Django
pip install django
# Create Django project
django-admin startproject myproject
cd myproject
# Create an app
python manage.py startapp myapp
Step 2: Configure Django Settings
Edit myproject/settings.py
:
# Add your app to INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', # Add this line
]
# Configure static files (if not already configured)
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / "static",
]
# Add template directory
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # Add this
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Step 3: Create Directory Structure
# Create necessary directories
mkdir -p static/css
mkdir -p templates
Step 4: Download Tailwind CSS Standalone
Choose the appropriate command for your operating system:
- Linux
# For x64
curl -sLo ./static/css/tailwindcss https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64
# For ARM64
curl -sLo ./static/css/tailwindcss https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-arm64
- macOS
# For Apple Silicon (M1/M2)
curl -sLo ./static/css/tailwindcss https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-arm64
# For Intel
curl -sLo ./static/css/tailwindcss https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-x64
- Windows
curl -sLo ./static/css/tailwindcss.exe https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-windows-x64.exe
Step 5: Make Tailwind Executable (Linux/macOS only)
chmod +x ./static/css/tailwindcss
Step 6: Download DaisyUI Files
curl -sLo ./static/css/daisyui.js https://github.com/saadeghi/daisyui/releases/latest/download/daisyui.js
curl -sLo ./static/css/daisyui-theme.js https://github.com/saadeghi/daisyui/releases/latest/download/daisyui-theme.js
Step 7: Create Input CSS File
Create myapp/static/css/input.css
:
@import "tailwindcss" source(none);
@plugin "./daisyui.js";
@source "../../templates";
Step 8: Create Base Template
Create templates/base.html
:
{% load static %}
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Django + DaisyUI{% endblock %}</title>
<link rel="stylesheet" href="{% static 'css/output.css' %}">
</head>
<body>
<!-- Navbar -->
<div class="navbar bg-base-100 shadow-lg">
<div class="navbar-start">
<div class="dropdown">
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16" />
</svg>
</div>
<ul tabindex="0" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
<li><a href="{% url 'home' %}">Home</a></li>
<li><a href="{% url 'about' %}">About</a></li>
</ul>
</div>
<a class="btn btn-ghost text-xl">Django + DaisyUI</a>
</div>
<div class="navbar-center hidden lg:flex">
<ul class="menu menu-horizontal px-1">
<li><a href="{% url 'home' %}">Home</a></li>
<li><a href="{% url 'about' %}">About</a></li>
</ul>
</div>
<div class="navbar-end">
<label class="swap swap-rotate">
<input type="checkbox" class="theme-controller" value="dark" />
<svg class="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"/>
</svg>
<svg class="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"/>
</svg>
</label>
</div>
</div>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8">
{% block content %}
{% endblock %}
</main>
<!-- Footer -->
<footer class="footer footer-center p-10 bg-base-200 text-base-content rounded">
<div class="grid grid-flow-col gap-4">
<a class="link link-hover">About us</a>
<a class="link link-hover">Contact</a>
<a class="link link-hover">Jobs</a>
<a class="link link-hover">Press kit</a>
</div>
<div>
<p>Copyright © 2024 - All right reserved by Django + DaisyUI Demo</p>
</div>
</footer>
<script>
// Theme toggle script
document.querySelector('.theme-controller').addEventListener('change', function(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
}
});
</script>
</body>
</html>
Step 9: Create Home Page Template
Create templates/home.html
:
{% extends 'base.html' %}
{% block title %}Home - Django + DaisyUI{% endblock %}
{% block content %}
<!-- Hero Section -->
<div class="hero min-h-screen bg-base-200">
<div class="hero-content text-center">
<div class="max-w-md">
<h1 class="text-5xl font-bold">Welcome to Django + DaisyUI</h1>
<p class="py-6">Build beautiful Django applications without Node.js using DaisyUI components.</p>
<a href="{% url 'about' %}" class="btn btn-primary">Get Started</a>
</div>
</div>
</div>
<!-- Features Section -->
<div class="py-16">
<h2 class="text-3xl font-bold text-center mb-12">DaisyUI Components Showcase</h2>
<!-- Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12">
<div class="card bg-base-100 shadow-xl">
<figure class="px-10 pt-10">
<div class="rounded-xl bg-primary h-32 w-32 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-primary-content" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
</div>
</figure>
<div class="card-body items-center text-center">
<h2 class="card-title">Fast Setup</h2>
<p>Get started quickly without Node.js dependencies</p>
<div class="card-actions">
<button class="btn btn-primary">Learn More</button>
</div>
</div>
</div>
<div class="card bg-base-100 shadow-xl">
<figure class="px-10 pt-10">
<div class="rounded-xl bg-secondary h-32 w-32 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-secondary-content" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />
</svg>
</div>
</figure>
<div class="card-body items-center text-center">
<h2 class="card-title">Beautiful Design</h2>
<p>Pre-styled components with multiple themes</p>
<div class="card-actions">
<button class="btn btn-secondary">Explore</button>
</div>
</div>
</div>
<div class="card bg-base-100 shadow-xl">
<figure class="px-10 pt-10">
<div class="rounded-xl bg-accent h-32 w-32 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-accent-content" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" />
</svg>
</div>
</figure>
<div class="card-body items-center text-center">
<h2 class="card-title">Customizable</h2>
<p>Easy to customize with Tailwind CSS utilities</p>
<div class="card-actions">
<button class="btn btn-accent">Customize</button>
</div>
</div>
</div>
</div>
<!-- Stats -->
<div class="stats shadow w-full">
<div class="stat">
<div class="stat-figure text-primary">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
</svg>
</div>
<div class="stat-title">Total Components</div>
<div class="stat-value text-primary">50+</div>
<div class="stat-desc">Ready to use</div>
</div>
<div class="stat">
<div class="stat-figure text-secondary">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<div class="stat-title">Themes</div>
<div class="stat-value text-secondary">30+</div>
<div class="stat-desc">Built-in themes</div>
</div>
<div class="stat">
<div class="stat-figure text-accent">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
</div>
<div class="stat-title">Setup Time</div>
<div class="stat-value text-accent">5min</div>
<div class="stat-desc">Without Node.js</div>
</div>
</div>
</div>
<!-- Alert Examples -->
<div class="py-8 space-y-4">
<h3 class="text-2xl font-bold mb-4">Alert Components</h3>
<div class="alert alert-info">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span>This is an info alert using DaisyUI!</span>
</div>
<div class="alert alert-success">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span>Your setup was successful!</span>
</div>
</div>
{% endblock %}
Step 10: Create About Page Template
Create templates/about.html
:
{% extends 'base.html' %}
{% block title %}About - Django + DaisyUI{% endblock %}
{% block content %}
<div class="min-h-screen">
<!-- Page Header -->
<div class="text-center py-12">
<h1 class="text-4xl font-bold mb-4">About This Demo</h1>
<p class="text-xl text-base-content/70">Showcasing DaisyUI components in Django</p>
</div>
<!-- Accordion Section -->
<div class="max-w-4xl mx-auto mb-12">
<h2 class="text-2xl font-bold mb-6">Frequently Asked Questions</h2>
<div class="join join-vertical w-full">
<div class="collapse collapse-arrow join-item border border-base-300">
<input type="radio" name="my-accordion-4" checked="checked" />
<div class="collapse-title text-xl font-medium">
What is DaisyUI?
</div>
<div class="collapse-content">
<p>DaisyUI is a component library for Tailwind CSS. It provides semantic component classes that you can use to build your UI faster.</p>
</div>
</div>
<div class="collapse collapse-arrow join-item border border-base-300">
<input type="radio" name="my-accordion-4" />
<div class="collapse-title text-xl font-medium">
Why use DaisyUI without Node.js?
</div>
<div class="collapse-content">
<p>Using DaisyUI without Node.js simplifies the setup process for Django developers who prefer Python-only environments. It reduces dependencies and makes deployment easier.</p>
</div>
</div>
<div class="collapse collapse-arrow join-item border border-base-300">
<input type="radio" name="my-accordion-4" />
<div class="collapse-title text-xl font-medium">
How does it work?
</div>
<div class="collapse-content">
<p>We use the standalone Tailwind CSS binary and DaisyUI plugin files directly, without npm or Node.js package management.</p>
</div>
</div>
</div>
</div>
<!-- Form Examples -->
<div class="max-w-4xl mx-auto mb-12">
<h2 class="text-2xl font-bold mb-6">Form Components</h2>
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<h3 class="card-title">Contact Form Example</h3>
<form class="space-y-4">
<div class="form-control">
<label class="label">
<span class="label-text">Your Name</span>
</label>
<input type="text" placeholder="John Doe" class="input input-bordered" />
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Email</span>
</label>
<input type="email" placeholder="[email protected]" class="input input-bordered" />
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Message</span>
</label>
<textarea class="textarea textarea-bordered h-24" placeholder="Your message"></textarea>
</div>
<div class="form-control">
<label class="label cursor-pointer">
<span class="label-text">Subscribe to newsletter</span>
<input type="checkbox" class="toggle toggle-primary" />
</label>
</div>
<div class="card-actions justify-end">
<button type="button" class="btn btn-ghost">Cancel</button>
<button type="submit" class="btn btn-primary">Send Message</button>
</div>
</form>
</div>
</div>
</div>
<!-- Modal Example -->
<div class="max-w-4xl mx-auto mb-12">
<h2 class="text-2xl font-bold mb-6">Modal Component</h2>
<button class="btn" onclick="my_modal_1.showModal()">Open Modal</button>
<dialog id="my_modal_1" class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Hello!</h3>
<p class="py-4">This is a DaisyUI modal component. Press ESC key or click the button below to close</p>
<div class="modal-action">
<form method="dialog">
<button class="btn">Close</button>
</form>
</div>
</div>
</dialog>
</div>
<!-- Progress and Loading -->
<div class="max-w-4xl mx-auto mb-12">
<h2 class="text-2xl font-bold mb-6">Progress Components</h2>
<div class="space-y-4">
<div>
<p class="mb-2">Project Progress</p>
<progress class="progress progress-primary w-full" value="70" max="100"></progress>
</div>
<div>
<p class="mb-2">Loading State</p>
<progress class="progress progress-secondary w-full"></progress>
</div>
<div class="flex items-center gap-4">
<span class="loading loading-spinner loading-lg"></span>
<span class="loading loading-dots loading-lg"></span>
<span class="loading loading-ring loading-lg"></span>
<span class="loading loading-ball loading-lg"></span>
</div>
</div>
</div>
<!-- Badges and Tags -->
<div class="max-w-4xl mx-auto mb-12">
<h2 class="text-2xl font-bold mb-6">Badges and Tags</h2>
<div class="flex flex-wrap gap-2">
<div class="badge badge-primary">primary</div>
<div class="badge badge-secondary">secondary</div>
<div class="badge badge-accent">accent</div>
<div class="badge badge-ghost">ghost</div>
<div class="badge badge-info gap-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-4 h-4 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
info
</div>
<div class="badge badge-success gap-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-4 h-4 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
success
</div>
<div class="badge badge-warning gap-2">warning</div>
<div class="badge badge-error gap-2">error</div>
</div>
</div>
</div>
{% endblock %}
Step 11: Create Views
Edit myapp/views.py
:
from django.shortcuts import render
def home(request):
return render(request, 'home.html')
def about(request):
return render(request, 'about.html')
Step 12: Configure URLs
Create myapp/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('about/', views.about, name='about'),
]
Edit myproject/urls.py
:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')),
]
Step 13: Update .gitignore
Create or update .gitignore
:
# Python
*.pyc
__pycache__/
venv/
.env
db.sqlite3
# Django
media/
staticfiles/
# Compiled CSS
myapp/static/css/output.css
myapp/static/css/tailwindcss
myapp/static/css/tailwindcss.exe
# IDE
.vscode/
.idea/
# DaisyUI
static/css/output.css
static/css/tailwindcss
Step 14: Build CSS
Run the Tailwind CSS compiler:
- Linux/macOS
./static/css/tailwindcss -i ./static/css/input.css -o ./static/css/output.css --watch
- Windows
./static/css/tailwindcss.exe -i ./static/css/input.css -o ./static/css/output.css --watch
Note: Keep this running in a separate terminal while developing. For production, run without --watch
.
Step 15: Run Django Server
In another terminal:
python manage.py migrate
python manage.py runserver
Visit http://127.0.0.1:8000/
to see your Django + DaisyUI application!
Production Deployment
For production:
-
Build CSS without watch mode:
./static/css/tailwindcss -i ./static/css/input.css -o ./static/css/output.css --minify
-
Collect static files:
python manage.py collectstatic
-
Set
DEBUG = False
in settings.py -
Configure your web server to serve static files
Tips
- The
--watch
flag automatically rebuilds CSS when templates change - Use
--minify
flag for production builds - DaisyUI themes can be changed via the
data-theme
attribute on the HTML element - All Tailwind CSS utilities are available alongside DaisyUI components
- Check DaisyUI documentation for more components: https://daisyui.com/
Troubleshooting
CSS not updating?
- Make sure the Tailwind process is running with
--watch
- Check that the source paths in
input.css
match your template directories
Components not styled?
- Verify
output.css
is being generated - Check that the static file path in templates is correct
- Ensure DaisyUI plugin files are downloaded properly
Permission denied error?
- Make sure Tailwind binary has execute permissions (Linux/macOS)
- On Windows, ensure the .exe file is not blocked by security settings
Theme not switching?
- Check that the JavaScript for theme switching is included
- Verify
data-theme
attribute is being updated on the HTML element
Summary
You now have a fully functional Django application with DaisyUI styling, all without Node.js! This setup provides:
- Beautiful, pre-styled components
- Dark/light theme switching
- Responsive design
- Fast development workflow
- Simple deployment process
The standalone Tailwind CSS approach eliminates Node.js dependencies while maintaining all the benefits of utility-first CSS and DaisyUI's component library.