Skip to main content
Technology & EngineeringUi Components Services187 lines

Park UI

Park UI: pre-designed styled components built on Ark UI primitives, available for React, Vue, and Solid with Panda CSS or Tailwind CSS styling

Quick Summary21 lines
You are an expert in building interfaces with Park UI.

## Key Points

- Use the CLI to add components rather than copying manually; the CLI handles dependencies and file structure correctly.
- Keep the Ark UI documentation alongside Park UI docs since Park UI components inherit Ark UI's API for behavior and accessibility.
- When customizing components, modify the generated source files in your project rather than wrapping them in additional layers.
- Confusing Ark UI and Park UI: Ark UI is headless (no styles), Park UI is the styled layer on top. Installing only Ark UI will not give you Park UI's design system.
- Forgetting to run `panda codegen` after modifying `panda.config.ts`; style changes won't take effect until the styled-system output is regenerated.

## Quick Example

```bash
npm install @park-ui/panda-preset
```

```bash
npx @park-ui/cli init
```
skilldb get ui-components-services-skills/Park UIFull skill: 187 lines
Paste into your CLAUDE.md or agent config

Park UI — UI Components

You are an expert in building interfaces with Park UI.

Core Philosophy

Overview

Park UI is a styled component library built on top of Ark UI's headless primitives. While Ark UI provides unstyled, state-machine-driven components, Park UI adds a curated design system with pre-built themes. It supports React, Vue, and Solid, and offers two styling approaches: Panda CSS and Tailwind CSS. Components are installed into your project as source code, similar to the shadcn/ui model, giving you full ownership and customization control.

Setup & Configuration

Installation with Panda CSS (React)

npm install @park-ui/panda-preset

Add the preset to your panda.config.ts:

import { defineConfig } from '@pandacss/dev'
import { createPreset } from '@park-ui/panda-preset'

export default defineConfig({
  preflight: true,
  presets: [
    '@pandacss/preset-base',
    createPreset({
      accentColor: 'amber',
      grayColor: 'sand',
      borderRadius: 'sm',
    }),
  ],
  include: ['./src/**/*.{js,jsx,ts,tsx}'],
  jsxFramework: 'react',
  outdir: 'styled-system',
})

Installation with Tailwind CSS (React)

npx @park-ui/cli init

Follow the CLI prompts to select your framework and styling approach. The CLI sets up the necessary configuration and installs base dependencies.

Adding Components

npx @park-ui/cli components add button
npx @park-ui/cli components add dialog
npx @park-ui/cli components add select

Components are copied into your project source, typically under src/components/ui/.

Core Patterns

Using styled components (Panda CSS)

import { Button } from '~/components/ui/button'
import { Dialog } from '~/components/ui/dialog'
import { Select } from '~/components/ui/select'

export function MyForm() {
  return (
    <div>
      <Button variant="solid" size="md">
        Submit
      </Button>
      <Button variant="outline" size="sm">
        Cancel
      </Button>
    </div>
  )
}

Dialog pattern

import { Dialog } from '~/components/ui/dialog'
import { Button } from '~/components/ui/button'

export function ConfirmDialog() {
  return (
    <Dialog.Root>
      <Dialog.Trigger asChild>
        <Button>Open Dialog</Button>
      </Dialog.Trigger>
      <Dialog.Backdrop />
      <Dialog.Positioner>
        <Dialog.Content>
          <Dialog.Title>Confirm Action</Dialog.Title>
          <Dialog.Description>
            Are you sure you want to proceed?
          </Dialog.Description>
          <Dialog.CloseTrigger asChild>
            <Button variant="outline">Cancel</Button>
          </Dialog.CloseTrigger>
        </Dialog.Content>
      </Dialog.Positioner>
    </Dialog.Root>
  )
}

Select pattern

import { Select, createListCollection } from '~/components/ui/select'

const frameworks = createListCollection({
  items: [
    { label: 'React', value: 'react' },
    { label: 'Vue', value: 'vue' },
    { label: 'Solid', value: 'solid' },
  ],
})

export function FrameworkSelect() {
  return (
    <Select.Root collection={frameworks}>
      <Select.Label>Framework</Select.Label>
      <Select.Control>
        <Select.Trigger>
          <Select.ValueText placeholder="Select a framework" />
        </Select.Trigger>
      </Select.Control>
      <Select.Positioner>
        <Select.Content>
          {frameworks.items.map((item) => (
            <Select.Item key={item.value} item={item}>
              <Select.ItemText>{item.label}</Select.ItemText>
              <Select.ItemIndicator />
            </Select.Item>
          ))}
        </Select.Content>
      </Select.Positioner>
    </Select.Root>
  )
}

Theme customization

Park UI themes are configured through the preset. You can customize accent colors, gray scale, and border radius at the preset level, and individual component recipes can be extended in your Panda config:

createPreset({
  accentColor: 'blue',   // amber, blue, green, red, etc.
  grayColor: 'neutral',  // sand, slate, neutral, etc.
  borderRadius: 'md',    // none, xs, sm, md, lg, xl, 2xl
})

Best Practices

  • Use the CLI to add components rather than copying manually; the CLI handles dependencies and file structure correctly.
  • Keep the Ark UI documentation alongside Park UI docs since Park UI components inherit Ark UI's API for behavior and accessibility.
  • When customizing components, modify the generated source files in your project rather than wrapping them in additional layers.

Common Pitfalls

  • Confusing Ark UI and Park UI: Ark UI is headless (no styles), Park UI is the styled layer on top. Installing only Ark UI will not give you Park UI's design system.
  • Forgetting to run panda codegen after modifying panda.config.ts; style changes won't take effect until the styled-system output is regenerated.

Anti-Patterns

Using the service without understanding its pricing model. Cloud services bill differently — per request, per GB, per seat. Deploying without modeling expected costs leads to surprise invoices.

Hardcoding configuration instead of using environment variables. API keys, endpoints, and feature flags change between environments. Hardcoded values break deployments and leak secrets.

Ignoring the service's rate limits and quotas. Every external API has throughput limits. Failing to implement backoff, queuing, or caching results in dropped requests under load.

Treating the service as always available. External services go down. Without circuit breakers, fallbacks, or graceful degradation, a third-party outage becomes your outage.

Coupling your architecture to a single provider's API. Building directly against provider-specific interfaces makes migration painful. Wrap external services in thin adapter layers.

Install this skill directly: skilldb add ui-components-services-skills

Get CLI access →