Not FoundElixir UI

Installation

Templates

Vite Installation

Setting up Elixir UI in a Vite React project is quick and efficient. This guide covers both new and existing Vite projects.

New Vite Project

If you're starting fresh, create a new Vite React project:

npm create vite@latest my-app -- --template react-ts
cd my-app
npm install

Install Tailwind CSS

Vite doesn't include Tailwind CSS by default, so install it first:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Configure Tailwind CSS

Update your tailwind.config.js:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Add Tailwind directives to your src/index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

Install Elixir UI

Now install Elixir UI in your Vite project:

npx @elixir-labs/ui init

The init command will automatically configure Vite-specific settings:

  • Install required dependencies (clsx, framer-motion)
  • Update your tailwind.config.js
  • Configure Vite path aliases
  • Set up the components directory structure
  • Add CSS variables to your stylesheet

Vite Configuration

The init command will update your vite.config.ts to include path aliases:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
})

Updated Tailwind Config

Your tailwind.config.js will be updated with Elixir UI theme configuration:

/** @type {import('tailwindcss').Config} */
export default {
  darkMode: ["class"],
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    container: {
      center: true,
      padding: "2rem",
      screens: {
        "2xl": "1400px",
      },
    },
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
        popover: {
          DEFAULT: "hsl(var(--popover))",
          foreground: "hsl(var(--popover-foreground))",
        },
        card: {
          DEFAULT: "hsl(var(--card))",
          foreground: "hsl(var(--card-foreground))",
        },
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
      keyframes: {
        "accordion-down": {
          from: { height: "0" },
          to: { height: "var(--radix-accordion-content-height)" },
        },
        "accordion-up": {
          from: { height: "var(--radix-accordion-content-height)" },
          to: { height: "0" },
        },
      },
      animation: {
        "accordion-down": "accordion-down 0.2s ease-out",
        "accordion-up": "accordion-up 0.2s ease-out",
      },
    },
  },
  plugins: [],
}

TypeScript Configuration

Your tsconfig.json will include path aliases:

{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

Adding Your First Component

Add a component to your Vite project:

npx @elixir-labs/ui add button

Update your src/App.tsx to use the component:

import { Button } from "@/components/ui/button";
import "./App.css";

function App() {
  return (
    <div className="min-h-screen bg-background flex items-center justify-center">
      <div className="max-w-md mx-auto text-center space-y-6">
        <h1 className="text-4xl font-bold text-foreground">
          Vite + Elixir UI
        </h1>
        
        <p className="text-muted-foreground">
          Fast, modern React development with beautiful components
        </p>
        
        <div className="flex gap-4 justify-center">
          <Button>Get Started</Button>
          <Button variant="secondary">Learn More</Button>
          <Button variant="outline">GitHub</Button>
        </div>
      </div>
    </div>
  );
}

export default App;

Development Server

Start your development server to see your changes:

npm run dev

Your Vite development server will start, typically on http://localhost:5173

Building for Production

Build your project for production:

npm run build

Vite will create an optimized production build in the dist/ directory.

Performance Tips

Optimize your Vite + Elixir UI setup:

Tree Shaking

Import only the components you need to keep your bundle size small.

// Good - specific imports
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";

// Avoid - importing everything
import * as UI from "@/components/ui";

Code Splitting

Use React.lazy() for code splitting larger components:

import { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

Troubleshooting

Common Vite-specific issues:

Path alias not working

Ensure both vite.config.ts and tsconfig.json have the correct path aliases configured.

CSS not loading

Make sure you've imported your CSS file in main.tsx or App.tsx, and Tailwind directives are in your CSS.

Fast Refresh issues

If components aren't updating, try restarting the dev server or clearing the cache.

Next Steps

Your Vite project is ready! Start exploring components and building your application.