WebPiki
tutorial

Tailwind CSS v4 마이그레이션 가이드 — v3에서 뭐가 달라졌나

Tailwind CSS v4의 주요 변경점과 v3에서의 마이그레이션 방법. CSS 기반 설정, 새 유틸리티, 성능 개선까지 정리.

Tailwind CSS v4는 v3와 겉보기에는 비슷해 보이지만, 내부 구조가 상당히 달라졌다. 가장 눈에 띄는 변화는 tailwind.config.js가 사라지고 CSS 파일에서 직접 설정하는 방식으로 바뀐 거다. 처음엔 낯설 수 있는데, 적응하면 오히려 더 직관적이다.

가장 큰 변화 — 설정이 CSS로 갔다

v3에서는 tailwind.config.js에 색상, 폰트, 브레이크포인트 등을 JavaScript 객체로 정의했다. v4에서는 이걸 CSS 파일 안에서 @theme 지시어로 정의한다.

/* v3: tailwind.config.js */
/* module.exports = {
  theme: {
    extend: {
      colors: {
        brand: '#3b82f6',
      },
      fontFamily: {
        sans: ['Pretendard', 'sans-serif'],
      },
    },
  },
} */

/* v4: app.css */
@import "tailwindcss";

@theme {
  --color-brand: #3b82f6;
  --font-sans: 'Pretendard', sans-serif;
}

CSS 커스텀 프로퍼티(CSS 변수)를 직접 정의하는 방식이다. JavaScript 설정 파일이 없어지니까 빌드 체인이 단순해지고, CSS만 보면 전체 디자인 토큰을 파악할 수 있다.

content 설정이 필요 없다

v3에서 가장 자주 실수하던 부분이 content 배열 설정이었다. 어떤 파일에서 Tailwind 클래스를 쓰는지 지정해야 했고, 이걸 빠뜨리면 스타일이 적용되지 않았다.

// v3: 이거 빠뜨려서 한 번쯤 삽질해봤을 거다
module.exports = {
  content: ['./src/**/*.{js,ts,jsx,tsx}'],
}

v4에서는 자동 콘텐츠 감지가 기본이다. 프로젝트 디렉토리를 알아서 스캔해서 사용 중인 클래스를 찾아낸다. content 설정이 필요 없어졌다. 이것만으로도 마이그레이션할 가치가 있다고 느끼는 사람도 있을 거다.

특정 경로를 제외하거나 추가하고 싶으면 @source 지시어를 쓴다:

@import "tailwindcss";
@source "../node_modules/some-ui-lib";

새 엔진 — Oxide

v4는 Rust로 작성된 새 엔진(Oxide)을 사용한다. 체감되는 차이점:

빌드 속도 — v3 대비 상당히 빨라졌다. 대규모 프로젝트에서 특히 차이가 크다. PostCSS 플러그인 방식이 아니라 독립적인 CSS 처리 엔진으로 동작하기 때문.

설치 간소화postcssautoprefixer를 별도로 설치할 필요가 없다. @tailwindcss/postcss@tailwindcss/vite 플러그인 하나만 설치하면 된다.

# v3
npm install tailwindcss postcss autoprefixer

# v4
npm install tailwindcss @tailwindcss/vite  # Vite 프로젝트

달라진 유틸리티들

색상 불투명도

<!-- v3 -->
<div class="bg-blue-500/50">

<!-- v4 — 동일. 근데 CSS 변수로도 제어 가능 -->
<div class="bg-blue-500/50">
<div class="bg-[oklch(0.5_0.2_250/50%)]">

v4는 내부적으로 oklch 색상 공간을 사용한다. 사용자가 직접 oklch 값을 쓸 수도 있는데, oklch는 인간의 색 인지와 더 가까워서 색상 팔레트를 만들 때 일관된 밝기를 유지하기 쉽다.

새로운 유틸리티들

<!-- 컨테이너 쿼리 -->
<div class="@container">
  <div class="@lg:flex @md:grid">...</div>
</div>

<!-- 3D 변환 -->
<div class="rotate-x-45 perspective-800">

<!-- 그라디언트 개선 -->
<div class="bg-linear-to-r from-blue-500 to-purple-500">
<!-- bg-gradient-to-r → bg-linear-to-r 로 변경 -->

컨테이너 쿼리가 네이티브 지원된다. v3에서는 @tailwindcss/container-queries 플러그인이 필요했는데, v4에서는 내장이다. 컴포넌트가 자기 부모의 크기에 따라 레이아웃을 바꿀 수 있어서, 재사용 가능한 컴포넌트를 만들 때 유용하다.

이름이 바뀐 것들

일부 유틸리티의 이름이 더 일관성 있게 바뀌었다:

v3v4
bg-gradient-to-rbg-linear-to-r
bg-opacity-50bg-black/50 (이미 v3에서도 가능)
shadow-smshadow-xs (새 단계 추가)
ring-offset-2ring-offset-2 (동일)

대부분은 v3 문법이 그대로 작동하고, 변경된 것도 자동 마이그레이션 도구로 처리할 수 있다.

마이그레이션 실전

1. 자동 마이그레이션 도구

공식 마이그레이션 도구가 제공된다:

npx @tailwindcss/upgrade

이 도구가 해주는 것:

  • tailwind.config.js의 설정을 CSS @theme 블록으로 변환
  • 변경된 유틸리티 이름을 자동 치환
  • import 구조 업데이트
  • PostCSS 설정 정리

완벽하진 않지만 대부분의 변환을 자동으로 처리해준다. 나머지는 수동으로 잡으면 된다.

2. 주의할 점

플러그인 호환성 — v3 플러그인은 v4에서 작동하지 않을 수 있다. @tailwindcss/typography, @tailwindcss/forms 같은 공식 플러그인은 v4용으로 업데이트됐지만, 커뮤니티 플러그인은 확인이 필요하다.

PostCSS 설정 변경 — v4는 PostCSS 플러그인 방식 대신 전용 플러그인(@tailwindcss/postcss 또는 @tailwindcss/vite)을 사용한다. 기존 postcss.config.js를 수정해야 한다.

JavaScript 설정에서 하던 복잡한 커스터마이징tailwind.config.js에서 함수를 써서 동적으로 값을 생성하던 패턴은 CSS @theme으로 1:1 변환이 안 될 수 있다. 이 경우 CSS 커스텀 프로퍼티와 @utility 지시어를 조합해서 해결해야 한다.

3. 권장 순서

  1. 프로젝트를 git commit으로 깨끗한 상태로 만든다
  2. npx @tailwindcss/upgrade 실행
  3. 빌드해서 에러 확인
  4. 화면 확인하면서 깨진 스타일 수동 수정
  5. 플러그인 호환성 확인

규모가 큰 프로젝트는 한번에 다 바꾸기보다, 페이지 단위로 점진적으로 확인하는 게 안전하다.

바꿔야 하나

신규 프로젝트는 v4로 시작하면 된다. 설정이 간소하고 빌드가 빠르고 새 기능이 많다.

기존 프로젝트는 급하지 않다. v3도 당분간 유지보수된다. 다만 새 유틸리티(컨테이너 쿼리, 3D 변환 등)를 쓰고 싶거나, 빌드 속도 개선이 절실하다면 마이그레이션할 이유가 충분하다. 자동 마이그레이션 도구가 있어서 생각보다 큰 작업은 아니다.

#TailwindCSS#CSS#프론트엔드#마이그레이션#웹개발

관련 글