프론트엔드 개발 시작.

디자인에서 몇 번이나 꺾여버렸는지 모르겠다만 드디어 개발에 들어간다.

Shadcn /ui ??

다양한 프레임워크와 해당 생태계의 UI 라이브러리가 있지만. 대부분의 경우 내부 구현을 커스터마이징 하거나, 특정 요구 사항에 맞춰 수정하려면 오히려 내가 만드는게 빠를듯 이라는 생각이 들 정도로 복잡할 때가 있다.

collection of reusable components 는 철학 하에,

shadcn/ui는 해당 컴포넌트를 설치하는 것이 아니라 컴포넌트 코드를 복사해온다.

공식 페이지

특징

  1. npx shadcn@latest init 을 통해 가져온다. (npm install 과 같은 설치 방식이 아님!)
  2. npx shadcn@latest add button와 같이 필요한 요소를 추가할 수 있다.

위에서 보았듯 npm install 이 아니기 때문에, node_modules와 같은 곳에 갇혀있는 코드가 아닌, 프로젝트 내부에 생성된다.

  1. Radix UI에 기초한다.
  • 커스텀 하기 용이함
  • 고품질의 접근성 + 상호작용 로직 제공
  • 기본적인 스타일이 거의 없음

Shadcn/ui 컴포넌트는 TailwindCSS + Radix UI 를 통해 스타일과 기능을 제공한다.

장점

  • 개발 생산성
  • 복잡한 컴포넌트의 재사용성
  • 커스터마이징 가능성
  • 기본적으로 제공되는 접근성
  • 필요한 컴포넌트만 추가됨

사용해보기

Next.js 환경에서 진행합니다.

  1. 테스트용 Next.js 생성
npx create-next-app@latest

# 위의 명령어를 실행하면 아래와 같은 질문이 나온다. 원하는 설정에 맞춰서 선택
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like your code inside a `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to use Turbopack for `next dev`?  No / Yes
Would you like to customize the import alias (`@/*` by default)? No / Yes
What import alias would you like configured? @/*

  1. 생성된 Next.js 파일 이동 & shadcn 명령어 실행
cd my-app # 위에서 입력한 앱 이름으로 폴더를 이동
npx shadcn@latest init
# 색상 추가 선택 후 완료

별거없음.

shadCn Install

  1. init이 완료된 후 필요한 컴포넌트 추가
npx shadcn@latest add button input

사용 가능한 컴포넌트는 공식 문서에 잘 정리되어 있다.

실제로 위의 명령어를 통해 추가된 파일은 src/components/ui/input.tsx 와 같은 이름으로 추가된 모습을 확인할 수 있다.

해당 파일을 이용해서 컴포넌트 확장을 진행해도 되고, 사용하는 시점에 tailwindCss 를 통해 커스텀을 진행해도 된다.

import * as React from "react";
import { cn } from "@/lib/utils";

function Input({ className, type, ...props }: React.ComponentProps<"input">) {
  return (
    <input
      type={type}
      data-slot="input"
      className={cn(
        // 외부에서 전달하는 클래스를 조합
        "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
        "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
        "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
        className // 외부에서 전달받는 커스텀 클래스!
      )}
      {...props}
    />
  );
}
export { Input };

마무리

재사용 가능한 컴포넌트들을 직접 통합하고 완벽하게 제어하여, 강력하고 유연한 디자인 시스템을 구축

요약

  1. 내 파일에 생성됨
  2. 내가 모든 코드를 소유하는 만큼 유지보수 책임도 개발자 (나) 본인에게 있음
  3. 커스텀 편함
  4. 필요한 것만 생성됨