Prowler Ui

Master Prowler's UI conventions with shadcn/ui and Tailwind patterns

✨ The solution you've been looking for

Verified
Tested and verified by our team
12565 Stars

Prowler UI-specific patterns. For generic patterns, see: typescript, react-19, nextjs-15, tailwind-4. Trigger: When working inside ui/ on Prowler-specific conventions (shadcn vs HeroUI legacy, folder placement, actions/adapters, shared types/hooks/lib).

prowler react nextjs shadcn-ui tailwind typescript frontend ui-patterns
Repository

See It In Action

Interactive preview & real-world examples

Live Demo
Skill Demo Animation

AI Conversation Simulator

See how users interact with this skill

User Prompt

I need to create a new data table component for the findings page. What's the right approach using Prowler's UI patterns?

Skill Processing

Analyzing request...

Agent Response

Guidance on using shadcn/ui components with proper folder structure, styling with Tailwind, and following the component placement decision tree

Quick Start (3 Steps)

Get up and running in minutes

1

Install

claude-code skill install prowler-ui

claude-code skill install prowler-ui
2

Config

3

First Trigger

@prowler-ui help

Commands

CommandDescriptionRequired Args
@prowler-ui creating-new-ui-componentsBuild new components following Prowler's shadcn/ui conventions while avoiding legacy HeroUINone
@prowler-ui form-validation-with-zodImplement forms using React Hook Form with Zod 4 schema validation following Prowler patternsNone
@prowler-ui project-structure-organizationOrganize code following Prowler's scope rules and folder conventionsNone

Typical Use Cases

Creating New UI Components

Build new components following Prowler's shadcn/ui conventions while avoiding legacy HeroUI

Form Validation with Zod

Implement forms using React Hook Form with Zod 4 schema validation following Prowler patterns

Project Structure Organization

Organize code following Prowler's scope rules and folder conventions

Overview

  • typescript - Const types, flat interfaces
  • react-19 - No useMemo/useCallback, compiler
  • nextjs-15 - App Router, Server Actions
  • tailwind-4 - cn() utility, styling rules
  • zod-4 - Schema validation
  • zustand-5 - State management
  • ai-sdk-5 - Chat/AI features
  • playwright - E2E testing (see also prowler-test-ui)

Tech Stack (Versions)

Next.js 15.5.9 | React 19.2.2 | Tailwind 4.1.13 | shadcn/ui
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8
NextAuth 5.0.0-beta.30 | Recharts 2.15.4
HeroUI 2.8.4 (LEGACY - do not add new components)

CRITICAL: Component Library Rule

  • ALWAYS: Use shadcn/ui + Tailwind (components/shadcn/)
  • NEVER: Add new HeroUI components (components/ui/ is legacy only)

DECISION TREES

Component Placement

New feature UI? → shadcn/ui + Tailwind
Existing HeroUI feature? → Keep HeroUI (don't mix)
Used 1 feature? → features/{feature}/components/
Used 2+ features? → components/shared/
Needs state/hooks? → "use client"
Server component? → No directive needed

Code Location

Server action      → actions/{feature}/{feature}.ts
Data transform     → actions/{feature}/{feature}.adapter.ts
Types (shared 2+)  → types/{domain}.ts
Types (local 1)    → {feature}/types.ts
Utils (shared 2+)  → lib/
Utils (local 1)    → {feature}/utils/
Hooks (shared 2+)  → hooks/
Hooks (local 1)    → {feature}/hooks.ts
shadcn components  → components/shadcn/
HeroUI components  → components/ui/ (LEGACY)

Styling Decision

Tailwind class exists? → className
Dynamic value?         → style prop
Conditional styles?    → cn()
Static only?           → className (no cn())
Recharts/library?      → CHART_COLORS constant + var()

Scope Rule (ABSOLUTE)

  • Used 2+ places → lib/ or types/ or hooks/ (components go in components/{domain}/)
  • Used 1 place → keep local in feature directory
  • This determines ALL folder structure decisions

Project Structure

ui/
├── app/
│   ├── (auth)/              # Auth pages (login, signup)
│   └── (prowler)/           # Main app
│       ├── compliance/
│       ├── findings/
│       ├── providers/
│       ├── scans/
│       ├── services/
│       └── integrations/
├── components/
│   ├── shadcn/              # shadcn/ui (USE THIS)
│   ├── ui/                  # HeroUI (LEGACY)
│   ├── {domain}/            # Domain-specific (compliance, findings, providers, etc.)
│   ├── filters/             # Filter components
│   ├── graphs/              # Chart components
│   └── icons/               # Icon components
├── actions/                 # Server actions
├── types/                   # Shared types
├── hooks/                   # Shared hooks
├── lib/                     # Utilities
├── store/                   # Zustand state
├── tests/                   # Playwright E2E
└── styles/                  # Global CSS

Recharts (Special Case)

For Recharts props that don’t accept className:

 1const CHART_COLORS = {
 2  primary: "var(--color-primary)",
 3  secondary: "var(--color-secondary)",
 4  text: "var(--color-text)",
 5  gridLine: "var(--color-border)",
 6};
 7
 8// Only use var() for library props, NEVER in className
 9<XAxis tick={{ fill: CHART_COLORS.text }} />
10<CartesianGrid stroke={CHART_COLORS.gridLine} />

Form + Validation Pattern

 1"use client";
 2import { useForm } from "react-hook-form";
 3import { zodResolver } from "@hookform/resolvers/zod";
 4import { z } from "zod";
 5
 6const schema = z.object({
 7  email: z.email(),  // Zod 4 syntax
 8  name: z.string().min(1),
 9});
10
11type FormData = z.infer<typeof schema>;
12
13export function MyForm() {
14  const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
15    resolver: zodResolver(schema),
16  });
17
18  const onSubmit = async (data: FormData) => {
19    await serverAction(data);
20  };
21
22  return (
23    <form onSubmit={handleSubmit(onSubmit)}>
24      <input {...register("email")} />
25      {errors.email && <span>{errors.email.message}</span>}
26      <button type="submit">Submit</button>
27    </form>
28  );
29}

Commands

 1# Development
 2cd ui && pnpm install
 3cd ui && pnpm run dev
 4
 5# Code Quality
 6cd ui && pnpm run typecheck
 7cd ui && pnpm run lint:fix
 8cd ui && pnpm run format:write
 9cd ui && pnpm run healthcheck    # typecheck + lint
10
11# Testing
12cd ui && pnpm run test:e2e
13cd ui && pnpm run test:e2e:ui
14cd ui && pnpm run test:e2e:debug
15
16# Build
17cd ui && pnpm run build
18cd ui && pnpm start

QA Checklist Before Commit

  • pnpm run typecheck passes
  • pnpm run lint:fix passes
  • pnpm run format:write passes
  • Relevant E2E tests pass
  • All UI states handled (loading, error, empty)
  • No secrets in code (use .env.local)
  • Error messages sanitized (no stack traces to users)
  • Server-side validation present (don’t trust client)
  • Accessibility: keyboard navigation, ARIA labels
  • Mobile responsive (if applicable)

Migrations Reference

FromToKey Changes
React 1819.1Async components, React Compiler (no useMemo/useCallback)
Next.js 1415.5Improved App Router, better streaming
NextUIHeroUI 2.8.4Package rename only, same API
Zod 34z.email() not z.string().email(), error not message
AI SDK 45@ai-sdk/react, sendMessage not handleSubmit, parts not content

Resources

  • Documentation: See references/ for links to local developer guide

What Users Are Saying

Real feedback from the community

Environment Matrix

Dependencies

Node.js (compatible with pnpm)
pnpm package manager

Framework Support

Next.js 15.5.9 ✓ (recommended) React 19.2.2 ✓ (recommended) Tailwind 4.1.13 ✓ (recommended) shadcn/ui ✓ (recommended) Zod 4.1.11 ✓ React Hook Form 7.62.0 ✓ Zustand 5.0.8 ✓ NextAuth 5.0.0-beta.30 ✓ Recharts 2.15.4 ✓ HeroUI 2.8.4 (legacy - no new components)

Context Window

Token Usage ~3K-8K tokens for component patterns and architectural decisions

Security & Privacy

Information

Author
prowler-cloud
Updated
2026-01-30
Category
frontend