# Comparison 01

> Two-column us-and-them panel: a featured column of checked points beside a muted column of the usual trade-offs, split by a divider that stacks on mobile.

A shadcn/ui block from the [@hirael](https://hirael.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/hirael/comparison-01).

- Page, with a live preview: https://shadcn.exchange/r/hirael/comparison-01
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/hirael/comparison-01-light-212f0537af532329.png
- Registry item: https://hirael.com/r/comparison-01.json
- Categories: blocks, comparison
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://hirael.com/r/comparison-01.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`
- Registry items: `button`

## Files

### `registry/hirael/bases/radix/blocks/comparison-01/comparison-01.tsx`

```tsx
// Comparison 01 from Hirael <https://hirael.com/blocks/comparison/comparison-01>
// MIT · Mohammad Shehadeh · https://github.com/MohammadShehadeh/hirael

import type * as React from 'react';
import { Check, Minus } from 'lucide-react';

import { cn } from '@/lib/utils';
import { Button } from '@/registry/hirael/bases/radix/ui/button';

const ENTER =
  'animate-in fade-in slide-in-from-bottom-4 duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] fill-mode-both motion-reduce:animate-none';

const stagger = (index: number): React.CSSProperties => ({ animationDelay: `${index * 60}ms` });

const HIRAEL = [
  'Source copied straight into your repo',
  'No runtime package and no version pin',
  'Compound parts with data-slot styling hooks',
  'RTL and light or dark theming built in',
  'Edit, extend, or delete any line, it is yours',
] as const;

const USUAL = [
  'A black-box dependency you cannot edit',
  "Locked to the maintainer's release cadence",
  "Restyling fights the library's internals",
  'RTL and theming bolted on after the fact',
  'Fork or eject the moment you outgrow it',
] as const;

const Comparison01 = () => {
  return (
    <section data-slot="comparison" className="bg-background py-20 sm:py-28">
      <div className="mx-auto w-full max-w-4xl px-6 md:px-10">
        <div data-slot="comparison-header" className="flex flex-col items-center gap-5 text-center">
          <span className={cn(ENTER, 'text-xs text-muted-foreground uppercase')}>Comparison</span>
          <h2
            style={stagger(1)}
            className={cn(ENTER, 'max-w-2xl font-serif text-4xl leading-[1.04] font-medium tracking-tight sm:text-5xl')}
          >
            The difference is ownership.
          </h2>
          <p style={stagger(2)} className={cn(ENTER, 'max-w-xl text-base text-muted-foreground sm:text-lg')}>
            Same install command you already use, a very different relationship with the code it leaves behind.
          </p>
        </div>

        <div
          data-slot="comparison-grid"
          className={cn(
            ENTER,
            'relative mt-12 grid overflow-hidden rounded-xl border border-border shadow-[0_24px_60px_-34px_color-mix(in_oklch,var(--foreground)_22%,transparent)] md:grid-cols-2',
          )}
          style={stagger(3)}
        >
          <span
            aria-hidden
            className="absolute start-1/2 top-1/2 z-20 hidden size-11 -translate-x-1/2 -translate-y-1/2 place-items-center rounded-full border border-border bg-background text-xs text-muted-foreground uppercase shadow-sm md:grid rtl:translate-x-1/2"
          >
            vs
          </span>

          <div
            data-slot="comparison-ours"
            className="relative border-b border-border bg-card p-7 sm:p-8 md:border-e md:border-b-0"
          >
            <div
              aria-hidden
              className="pointer-events-none absolute inset-0 bg-[radial-gradient(110%_80%_at_50%_0%,color-mix(in_oklch,var(--primary)_11%,transparent),transparent_62%)]"
            />
            <div className="relative z-10 flex flex-col gap-6">
              <div className="flex flex-col gap-1">
                <span className="text-xs text-muted-foreground uppercase">With Hirael</span>
                <h3 className="text-xl font-semibold tracking-[-0.01em]">Code you keep</h3>
              </div>
              <ul className="flex flex-col gap-3.5">
                {HIRAEL.map((item) => (
                  <li key={item} className="flex items-start gap-3 text-sm">
                    <span className="mt-0.5 inline-flex size-5 shrink-0 items-center justify-center rounded-full border border-primary/40 bg-transparent">
                      <Check className="size-3 text-primary" />
                    </span>
                    <span className="text-foreground">{item}</span>
                  </li>
                ))}
              </ul>
              <Button asChild className="mt-1 w-full sm:w-auto">
                <a href="#">Browse the registry</a>
              </Button>
            </div>
          </div>

          <div data-slot="comparison-theirs" className="bg-muted/20 p-7 sm:p-8">
            <div className="flex flex-col gap-6 opacity-80">
              <div className="flex flex-col gap-1">
                <span className="text-xs text-muted-foreground uppercase">The usual way</span>
                <h3 className="text-xl font-semibold tracking-[-0.01em] text-muted-foreground">Code you rent</h3>
              </div>
              <ul className="flex flex-col gap-3.5">
                {USUAL.map((item) => (
                  <li key={item} className="flex items-start gap-3 text-sm text-muted-foreground">
                    <span className="mt-0.5 inline-flex size-5 shrink-0 items-center justify-center rounded-full border border-border">
                      <Minus className="size-3 text-muted-foreground/60" />
                    </span>
                    <span>{item}</span>
                  </li>
                ))}
              </ul>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};

export default Comparison01;
```
