A beautifully designed, heavily optimized component library built from the ground up for Nix.js. Powered by Tailwind CSS v4 styling, but completely open for Vanilla CSS overrides when you need maximum control.
Nix UI leverages the ultra-lightweight signals architecture of Nix.js combined with the utility-first power of Tailwind CSS to deliver 16 essential components that are ready to use, accessible, and look stunning out of the box.
- Native Nix.js Performance: Fully reactive, no VDOM overhead.
- Fully Animated: Deeply integrated with Nix.js
transition()for buttery smooth 60fps animations. - Tailwind v4 First: Pre-styled with modern Tailwind utilities while exposing CSS custom properties.
- Vanilla CSS Escape Hatch: Override ANY component using the
classmapping or standard inlinestyle.
# Core framework
npm i @deijose/nix-js
# UI Library
npm i @deijose/nix-ui(Note: Tailwind CSS v4 setup is recommended in your project to fully apply the utility classes used by Nix UI).
Drop Nix-UI components straight into your application!
import { html, signal } from "@deijose/nix-js";
import { Button, Input, Card, Modal, showToast } from "@deijose/nix-ui";
// You MUST import the base styles once in your entry point:
import "@deijose/nix-ui/styles";
export function App() {
const isModalOpen = signal(false);
return html`
<div class="p-8 max-w-2xl mx-auto space-y-6">
${Card({
children: html`
<h2 class="text-2xl font-bold mb-4">Welcome to Nix UI</h2>
<div class="flex gap-4 items-end">
${Input({ label: "Your Email", placeholder: "test@example.com" })}
${Button({
children: "Subscribe",
onClick: () => showToast("Subscribed successfully!", "success")
})}
</div>
<div class="mt-6">
${Button({
variant: "outline",
children: "Open Settings",
onClick: () => isModalOpen.value = true
})}
</div>
`
})}
${Modal({
open: isModalOpen,
title: "Account Settings",
children: html`<p>Manage your account details and preferences here.</p>`,
footer: html`
${Button({ variant: "ghost", children: "Cancel", onClick: () => isModalOpen.value = false })}
${Button({ children: "Save Changes", onClick: () => isModalOpen.value = false })}
`
})}
</div>
`;
}A versatile container with optional header and footer slots.
Card({
header: html`<h3 class="font-bold">Card Title</h3>`,
children: "Inner body content here...",
footer: html`<span class="text-sm">Footer text</span>`
})A vertically stacked set of interactive headings that each reveal a section of content.
Accordion({
items: [
{ title: "Section 1", content: "Content for section 1" },
{ title: "Section 2", content: "Content for section 2" }
]
})Primary interactive element with 5 variants (primary, secondary, outline, danger, ghost) and 3 sizes (sm, md, lg).
Button({
variant: "primary",
size: "lg",
loading: false,
onClick: () => console.log('clicked'),
children: "Click Me"
})Text input with visual label formatting, focused states, and external error state formatting.
Input({
label: "Username",
placeholder: "Enter username",
type: "text"
})Multi-line text input with custom styling and standard attributes.
Textarea({
label: "Description",
placeholder: "Write something...",
rows: 4
})Native <select> dropdown styled to match the UI system.
Select({
label: "Country",
options: [
{ label: "Select a country...", value: "" },
{ label: "USA", value: "us" },
]
})Custom styled checkbox element supporting checked bindings.
Checkbox({
label: "I agree to the terms",
checked: mySignal.value,
onChange: (e) => mySignal.value = e.target.checked
})Animated toggle switch component.
Toggle({
label: "Enable notifications",
checked: mySignal.value,
onChange: (e) => mySignal.value = e.target.checked
})Small status indicators displaying inline information. Sizes (sm, md, lg) and variants (default, primary, success, warning, error).
Badge({
variant: "success",
children: "Completed"
})Circular image wrapper with automatic fallback parsing to display initials. Sizes (sm, md, lg, xl).
// With image
Avatar({ src: "/avatar.jpg", alt: "John Doe" })
// With fallback initials (renders "JD")
Avatar({ fallback: "John Doe" }) Loading indicator. Variants (primary, white, neutral) and sizes (sm, md, lg).
Spinner({ size: "md", variant: "primary" })Static banner for displaying important messages. Variants (info, success, warning, error). Native animated close button support.
Alert({
title: "Update Available",
children: "A new version of the software is ready.",
variant: "info",
onClose: () => hideAlert()
})Dialog window overlay taking focus over everything else. Smooth enter/exit transition animations.
Modal({
open: modalStateSignal,
title: "Confirm Action",
closeButton: true,
children: html`<p>Are you sure you want to do this?</p>`,
})Small popover providing contextual information on hover.
Tooltip({
content: "This does something special",
position: "top", // top, bottom, left, right
children: Button({ children: "Hover Me" })
})Organize content into selectable panels.
Tabs({
tabs: [
{ id: "tab1", label: "Profile", content: () => html`Profile Data` },
{ id: "tab2", label: "Settings", content: () => html`Settings Data` },
],
defaultTab: "tab1"
})Non-blocking notifications floating above content. Automatically expires with progress bar. Top-level API usage showToast().
import { showToast } from "@deijose/nix-ui";
// Trigger anywhere!
showToast("Profile saved successfully!", "success", {
position: "bottom-right",
duration: 4000
});Every component accepts class and style props. Nix UI intelligently merges your custom classes with its own base styling via an internal cx() engine powered by intelligent tailwind-class manipulation.
// Changing a button's specific Tailwind classes
Button({
class: "bg-purple-600 hover:bg-purple-700 shadow-xl rounded-full px-8",
children: "Custom Pill Button"
})
// Or using inline CSS / CSS Modules
Button({
style: "background: linear-gradient(90deg, #ff00cc, #333399); border-radius: 999px;",
children: "Gradient Button"
})We welcome contributions to Nix-UI! Please see our CONTRIBUTING.md for details on how to set up the repository, run the demo locally, and submit Pull Requests.
This project is licensed under the MIT License - see the LICENSE file for details.