BenixBenix DSv1.1.0

Installation

Two paths: the CLI handles everything for you, or configure manually.

Fastest — CLI

Detects your framework (Vite or Next.js 16+), installs every peer dependency, patches your main CSS and (for Next) wires up transpilePackages. With colored prompts for each step.

npx @kactostecnologia/benix-ds init

Manual

  1. 1. Install the package

    npm 7+ resolves every peer dependency automatically.

    npm install @kactostecnologia/benix-ds

    Charts (recharts), color picker (react-colorful), emoji picker (emoji-picker-react) and tables (@tanstack/react-table) are optional peers — install only if you use them.

  2. 2. Add to your main CSS

    In app/globals.css (Next) or src/index.css (Vite):

    @import "tailwindcss";
    @import "@kactostecnologia/benix-ds/styles.css";
    @source "../node_modules/@kactostecnologia/benix-ds/dist/**/*.{js,mjs}";

    The @source directive tells Tailwind 4 to scan utility classes used inside the package.

    Don't skip the @source line

    Without it Tailwind 4 purges every class used by the package — components render with zero styling and there's no build error to point you here. If buttons look like raw browser buttons, this is the line you forgot.
  3. 3a. Next.js — transpilePackages

    In next.config.mjs:

    export default {
    transpilePackages: ['@kactostecnologia/benix-ds'],
    };
  4. 3b. Vite — nothing extra

    With the @tailwindcss/vite plugin (default Tailwind 4 setup), it works with no extra config.

Requirements

React ≥ 19.0, Tailwind CSS ≥ 4.0 and Node ≥ 22. Tested versions: React 19.2 + Tailwind 4.3.

Quick test

Drop this into any page/component to verify the installation. Note that cn is exported from the same barrel — no extra subpath needed.

import { Button, Card, cn } from '@kactostecnologia/benix-ds';
export default function Test() {
return (
<Card title="Working?">
<Button className={cn('w-full')}>Yes, it works!</Button>
</Card>
);
}

With react-hook-form + Zod

The DS stays agnostic of form libraries — Input/Textarea/Select work standalone with their label / error / helperText props. Wiring RHF on top is a single register() spread for nativos and Controller for Radix-based controls (Select, Switch):

import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button, Input, Select, Switch } from '@kactostecnologia/benix-ds';
const schema = z.object({
email: z.string().email(),
kind: z.enum(['personal', 'business']),
newsletter: z.boolean(),
});
type FormValues = z.infer<typeof schema>;
export function SignupForm() {
const { register, control, handleSubmit, formState: { errors } } =
useForm<FormValues>({ resolver: zodResolver(schema) });
return (
<form onSubmit={handleSubmit((v) => console.log(v))} className="space-y-4">
<Input
label="Email"
type="email"
error={errors.email?.message}
{...register('email')}
/>
<Controller
name="kind"
control={control}
render={({ field }) => (
<Select
label="Account type"
options={[
{ value: 'personal', label: 'Personal' },
{ value: 'business', label: 'Business' },
]}
value={field.value}
onValueChange={field.onChange}
error={errors.kind?.message}
/>
)}
/>
<Controller
name="newsletter"
control={control}
render={({ field }) => (
<Switch
label="Subscribe to newsletter"
checked={field.value}
onCheckedChange={field.onChange}
/>
)}
/>
<Button type="submit">Sign up</Button>
</form>
);
}

Use {...register(name)} for native inputs (Input, Textarea) and <Controller>for Radix-backed components (Select, Switch, Checkbox, RadioCards) — they don't expose the native event RHF expects.

Next steps

Browse components

Live showcase of everything in the package.

Customize theme

Click the floating Playground button on any page to play with colors and radius in real time.