Open Source 34 / 34
Pines
Pines is DevDojo's Alpine.js + Tailwind CSS UI library — copy-paste, dependency-free interactive components like modals, dropdowns, tabs, and tooltips that drop into any Tailwind project.
Pines is DevDojo's UI library built on Alpine.js and Tailwind CSS. It's a collection of interactive components — modals, dropdowns, tooltips, tabs, accordions, popovers, notifications, and more — designed to be copied into your project rather than installed as a dependency. Each element is a self-contained snippet of Tailwind markup plus a little Alpine behavior, so you own the code the moment you paste it.
Copy-paste, not a package. Pines isn't a JavaScript bundle you npm install — it's a library of patterns you copy into your own markup. Your only runtime dependencies are Alpine.js and Tailwind CSS, both of which you almost certainly already have.
Why "just Alpine and Tailwind"
Most component libraries hand you a framework: a build step, a component runtime, and an API to learn. Pines deliberately doesn't. Its two ingredients are ones the whole DevDojo ecosystem already leans on:
- Alpine.js provides the behavior — open/close state, focus handling, transitions, keyboard interaction — declared right in your HTML with
x-data,x-show, and friends. - Tailwind CSS provides the styling — utility classes you can restyle freely, with no opaque component CSS to override.
Because a Pines component is only those two things, there's nothing to keep in sync, nothing to fight, and nothing between you and the markup. Paste it, read it, change it.
How you use it
The workflow has almost no ceremony:
- Make sure your project includes Alpine.js and Tailwind CSS.
- Browse the Pines library and find the element you want.
- Copy its markup into your page.
- Restyle the Tailwind classes and adjust the Alpine behavior to taste.
A Pines component looks like ordinary Alpine — state on a wrapper, behavior wired to elements inside it:
<div x-data="{ open: false }" class="relative">
<button @click="open = ! open" class="rounded-lg px-4 py-2">
Menu
</button>
<div
x-show="open"
@click.outside="open = false"
x-transition
class="absolute mt-2 w-48 rounded-lg border bg-white p-1 shadow-lg"
>
<!-- menu items -->
</div>
</div>
That snippet shows the shape Pines patterns take — declarative Alpine state plus Tailwind utilities. The library's real elements are more complete (transitions, accessibility affordances, edge cases handled), but they read the same way, so you can always understand and modify what you paste.
Source of truth. Copy the real, current markup from the Pines library rather than hand-writing components — the maintained versions handle transitions, focus, and accessibility details you don't want to reinvent.
Where Pines shows up in the ecosystem
Pines is the interaction layer the rest of the DevDojo toolbox shares. The components Blade library and the platform UI reach for the same Alpine + Tailwind patterns, so a dropdown or modal you learn in Pines behaves the way you'd expect everywhere else. It pairs naturally with:
components— the copy-in Blade component library, which packages many of these patterns as reusable Blade tags.- Sites — where a "sprinkle of Alpine" powers things like a mobile-nav toggle inside otherwise-static pages.
- Wave and any Tailwind project — Pines has no framework requirement beyond Alpine and Tailwind.
When to reach for Pines
Choose Pines when you want interactive UI without adopting a component framework — you're already in Tailwind, you already have Alpine (or are happy to add it), and you want a modal that you fully own and can restyle. If you'd rather consume components as ready-made Blade tags in a Laravel app, look at the components package instead; it builds on the same ideas. For the rest of the toolbox, see the open source overview.