이 글에서 정리하는 내용
shadcn/ui 컴포넌트 생성 후 @ alias와 실제 폴더 구조가 맞지 않아 import가 깨지는 상황을 기준으로 원인을 좁히고, 실제 프로젝트에서 어떤 설정과 코드 구조를 확인해야 하는지 정리합니다. 단순 개념 소개가 아니라 오류가 난 순간 바로 확인할 순서와 선택 기준을 중심으로 설명합니다.
- shadcn/ui 설치 후 import 오류가 나는 이유
- components.json에서 먼저 확인할 값
- tsconfig paths와 @ alias 맞추기
- Next.js와 Vite에서 다른 점
- 새 컴포넌트 추가 전 체크리스트
shadcn/ui 설치 후 import 오류가 나는 이유

shadcn/ui 컴포넌트 생성 후 import가 깨진다면 먼저 components.json의 aliases와 tsconfig.json 또는 jsconfig.json의 paths가 같은 루트를 가리키는지 확인해야 합니다. CLI가 만든 import 경로와 번들러가 해석하는 alias가 다르면 컴포넌트 파일은 있어도 모듈을 찾지 못합니다.
먼저 실제 파일 위치를 봅니다. 예를 들어 버튼 파일이 src/components/ui/button.tsx에 있는데 alias는 @/components를 프로젝트 루트로 보고 있다면 경로가 어긋납니다. Tailwind 설정 문제와 함께 보인다면 Tailwind CSS 클래스 적용 오류 해결도 같이 확인합니다.
components.json에서 먼저 확인할 값
components.json의 aliases는 shadcn/ui CLI가 컴포넌트를 어디에 만들고 import를 어떻게 쓸지 정하는 값입니다. 이 값만 맞아도 충분하지는 않고, TypeScript나 번들러가 같은 alias를 해석할 수 있어야 합니다.
공식 문서 기준으로 aliases는 components, ui, lib, hooks, utils 같은 import root를 CLI에 알려주는 역할입니다. 실제 프로젝트에서는 이 값이 compilerOptions.paths 또는 package imports와 맞아야 합니다.
{
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
위 예시는 CLI가 @/components와 @/lib/utils를 기준으로 import를 만들겠다는 의미입니다. 이제 @/*가 실제로 어느 폴더를 가리키는지 tsconfig.json에서 확인해야 합니다.
팀마다 src 폴더를 쓰는지, 루트에 components를 두는지 다릅니다. 그래서 다른 프로젝트의 components.json을 그대로 복사하면 import 경로가 깨질 수 있습니다.
tsconfig paths와 @ alias 맞추기
@ alias가 프로젝트 루트를 가리키는지, src 폴더를 가리키는지부터 정해야 합니다. components.json은 CLI 기준이고, tsconfig paths는 에디터와 빌드가 import를 해석하는 기준입니다. 둘이 달라지면 생성은 되지만 사용 단계에서 깨집니다.
경로를 고친 뒤에는 dev server와 TypeScript server를 다시 시작해야 에디터 오류가 사라지는 경우가 있습니다. shadcn/ui의 역할 차이가 헷갈린다면 Radix UI와 shadcn/ui 차이도 함께 보면 좋습니다.
Next.js와 Vite에서 다른 점

Next.js에서는 tsconfig.json의 paths만으로 @/* alias를 쓰는 구성이 흔합니다. Vite에서는 TypeScript paths와 별개로 Vite resolve alias나 관련 플러그인 설정이 필요할 수 있으므로, 사용하는 빌드 도구 기준을 확인해야 합니다.
JS 프로젝트라면 jsconfig.json을 봐야 하고, TS 프로젝트라면 tsconfig.json을 봐야 합니다. 모노레포에서는 앱 패키지의 설정과 루트 설정이 달라서 CLI 실행 위치도 같이 확인해야 합니다.
새 컴포넌트 추가 전 체크리스트
새 컴포넌트를 추가하기 전에는 components.json의 aliases, 실제 폴더 구조, tsconfig 또는 jsconfig paths를 같은 기준으로 맞춥니다. 그다음 npx shadcn@latest add button처럼 작은 컴포넌트 하나로 먼저 확인하는 편이 빠릅니다.
기록은 “@/*는 ./src/* 기준”, “components alias는 @/components”, “utils alias는 @/lib/utils”처럼 남기면 충분합니다. 나중에 폴더를 옮길 때 이 세 값이 함께 바뀌어야 한다는 기준이 됩니다.
가능하면 수정 전후를 한 줄로 기록해 두세요. 예를 들어 “components.json의 ui alias를 @/components/ui로 수정”, “tsconfig paths를 @/* -> ./src/*로 통일”, “dev server 재시작 후 button import 확인”처럼 남기면 됩니다.
피해야 할 방식은 import 경로만 상대 경로로 바꿔 오류를 숨기는 것입니다. 당장은 빌드가 지나갈 수 있지만 다음에 shadcn/ui CLI로 컴포넌트를 추가하면 다시 같은 alias 기준으로 코드가 생성됩니다.
수정 후에는 새 컴포넌트 하나를 추가하고 실제 페이지에서 import해 봅니다. 에디터 자동완성, TypeScript 체크, dev server 빌드가 모두 같은 alias를 해석해야 해결된 것입니다.
이 글의 핵심은 components.json만 고치는 것이 아닙니다. shadcn/ui CLI가 쓰는 alias와 프로젝트가 실제로 해석하는 alias를 같은 기준으로 맞추는 것입니다.