Tailwind CSS

Learn how JopiJS integrates with Tailwind CSS and how to use the built-in ShadCN installer for modular development.

Overview

JopiJS provides deep integration with Tailwind CSS, allowing you to use utility classes directly in your components or via CSS Modules. Additionally, JopiJS features a custom ShadCN/UI installer designed specifically to work with its modular architecture.


1. Tailwind CSS

Tailwind CSS is a utility-first CSS framework that allows you to build custom designs directly in your markup using pre-defined classes. JopiJS provides native, zero-config support for Tailwind, meaning you can start using its classes immediately without any setup.

The global.css file

In JopiJS, global.css is a transverse file that is automatically included in every HTML page of your application. It is the ideal place to define:

  • Global Tailwind directives.
  • Common CSS rules and resets.
  • Project-wide CSS variables (e.g., brand colors, typography tokens).

Best Practice: Keep your global.css as minimal as possible. Since this file is loaded on every page, heavy styles can impact performance. For component-specific styling, we strongly recommend using CSS Modules (see section 2) to maintain better encapsulation and smaller initial payloads.

Intelligent Merging System

To support modular development, JopiJS allows you to distribute your global styles across different modules. These are merged intelligently at build time into a single, optimized global.gen.css file.

  • Project Root: Use a global.css at the project root (next to package.json) for core styles.
  • Modular Styles: Each module can have its own global.css for styles specific to that module's domain.
Intelligent CSS Merging Structure
|- package.json
|- global.css            # Root styles (e.g., brand colors, typography)
|- mod_moduleA/
   |- global.css         # moduleA-specific global styles
|- mod_moduleB/
   |- global.css         # moduleB-specific global styles

2. Tailwind in CSS Modules

While you can use Tailwind classes directly in your components via className, JopiJS encourages the use of CSS Modules.

What are CSS Modules?

CSS Modules are CSS files in which all class names and animation names are scoped locally by default. When you import a CSS module, the build system generates unique class names (e.g., .button becomes .button_abc123), ensuring:

  • Zero Naming Conflicts: You can use common names like .container or .button in different components without them interfering with each other.
  • Encapsulation: Styles are strictly bound to the component that imports them.
  • Better Maintainability: Deleting a component automatically makes its associated styles obsolete, preventing "dead CSS" accumulation.
  • Tailwind Power: You can use the @apply directive to leverage Tailwind's utility classes within these scoped modules.
Sample CSS module using Tailwind
.button {
    /* Combine Tailwind utilities using @apply */
    @apply bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded transition-colors shadow-lg;
    
    /* Custom CSS can still be added here */
    display: inline-flex;
    align-items: center;
}

The useCssModule Hook

To use CSS Modules in JopiJS, you must use the useCssModule hook. This ensures that the styles are correctly injected into the page and managed during client-side navigation.

Button.tsx
import style from "./style.module.css";
import { useCssModule } from "jopijs/ui";

export default function MyButton() {
    // Inject the CSS module styles
    useCssModule(style);
    
    return (
        <div className={style.button}>
            Click Me
        </div>
    );
}

Why useCssModule?

While some frameworks handle CSS modules automatically, JopiJS requires this manual step to enable its advanced optimization engine:

  • HTML Inlining: JopiJS inlines the CSS directly into the HTML during server-side rendering. This eliminates extra HTTP requests for CSS files, resulting in near-instant styling.
  • SEO & Web Vitals: By inlining CSS, you achieve significantly better Google Core Web Vitals scores (specifically LCP and CLS), which directly boosts your SEO ranking.
  • Email Compatibility: Because styles are inlined, your React components become natively compatible for use in HTML Emails, where external stylesheets are often blocked.
  • Optimized Delivery: Components only "pay" for the CSS they actually use, keeping the initial payload as lean as possible.

The "Manual" Trade-off: The hook is mandatory. If you forget to call useCssModule(style) your component will render without its scoped styles. This is a deliberate design choice that prioritizes performance over automatic magic.


3. Modular ShadCN/UI Installer

JopiJS includes a dedicated CLI tool to install ShadCN/UI components. Unlike the standard ShadCN installer, the JopiJS version is module-aware, allowing you to isolate components within a specific module instead of a global components folder.

Adding a Component

Here is how you add ShadCN blocks and components to your modules:

JopiJS ShadCN Tool (Modular installation):

npx jopi shadcn-add dashboard-01 --mod myModule
# Installs block "dashboard-01" into module "myModule"

npx jopi shadcn-add button --mod myModule
# Installs component "button" into module "myModule"

You can compare the official installation vs. the JopiJS modular approach:

Official ShadCN CLI (Global installation):

npx shadcn@latest add dashboard-01
# Installs block "dashboard-01"

npx shadcn@latest add button
# Installs component "button"

Generated Structure

When you install a ShadCN component through JopiJS, it organizes the files to maintain module isolation:

Module Structure After Installation
|- src/
   |- mod_myModule/
      |- shadCN/                 # Dedicated ShadCN directory for this module
         |- components/          # UI components (Button, Input, etc.)
         |- lib/                 # Shared utilities (utils.ts)
         |- app/                 # Layouts and global providers
         |- styles/              # Component-specific styles
      |- @routes/
         |- shadPages/
            |- dashboard-01      # Demo pages are automatically registered
               |- page.tsx
               |- data.json      # Sample data for the block

Previewing the Result

Once installed, if the block includes a demo page, it is automatically available in your development environment. For example: http://localhost:3000/shadPages/dashboard-01

Encapsulation: By installing ShadCN inside a module, you ensure that its components and styles are scoped. This prevents "CSS leak" and naming conflicts between different parts of your application.


3. Key Features

Zero Config

Tailwind CSS is pre-configured and works out of the box with instant Hot Module Replacement (HMR).

Module Aware

Keep your project organized by installing UI components directly into the modules that use them.

Standard Compliant

Full support for @apply and standard Tailwind configurations within CSS Modules.

Automatic Routing

Complex ShadCN blocks and demo pages are automatically integrated into your module's routing system.