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. Install the package
npm 7+ resolves every peer dependency automatically.
npm install @kactostecnologia/benix-dsCharts (
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. Add to your main CSS
In
app/globals.css(Next) orsrc/index.css(Vite):@import "tailwindcss";@import "@kactostecnologia/benix-ds/styles.css";@source "../node_modules/@kactostecnologia/benix-ds/dist/**/*.{js,mjs}";The
@sourcedirective 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.3a. Next.js — transpilePackages
In
next.config.mjs:export default {transpilePackages: ['@kactostecnologia/benix-ds'],};3b. Vite — nothing extra
With the
@tailwindcss/viteplugin (default Tailwind 4 setup), it works with no extra config.
Requirements
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"><Inputlabel="Email"type="email"error={errors.email?.message}{...register('email')}/><Controllername="kind"control={control}render={({ field }) => (<Selectlabel="Account type"options={[{ value: 'personal', label: 'Personal' },{ value: 'business', label: 'Business' },]}value={field.value}onValueChange={field.onChange}error={errors.kind?.message}/>)}/><Controllername="newsletter"control={control}render={({ field }) => (<Switchlabel="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.