
지난 여름 Tailwind Connect에서 Oxide 미리보기를 공유했습니다 — Tailwind CSS를 위한 새로운 고성능 엔진으로, 개발자 경험을 단순화하고 최근 몇 년간 웹 플랫폼이 발전한 점을 활용하기 위해 개발 중입니다.
이 새로운 엔진은 원래 v3.x 릴리스로 출시될 예정이었지만, 하위 호환성을 유지하기로 약속했음에도 불구하고 이번 업데이트는 프레임워크의 새로운 세대임이 분명해 v4.0으로 출시하는 것이 적절하다고 판단했습니다.
아직 초기 단계이며 많은 작업이 남아 있지만, 오늘 개발 진행 상황을 오픈소스로 공개하고 첫 번째 공개 v4.0.0-alpha 버전을 태그했습니다. 여러분도 실험해 보고 올해 안에 안정적인 릴리스를 위해 도움을 주실 수 있습니다.
안정적인 릴리스 때의 흥미를 위해 간단히 설명하려고 합니다만, 매우 초기 단계의 실험적인 것을 다루는 것을 좋아한다면 여기서 충분한 정보를 얻을 수 있을 것입니다.
속도를 위해 새로 만든 엔진
새로운 엔진은 처음부터 다시 작성되었습니다. 프레임워크에 대해 현재 알고 있는 모든 것을 활용해 문제 공간을 더 잘 모델링하고, 훨씬 적은 코드로 더 빠르게 동작하도록 만들었습니다.
- 최대 10배 빠른 속도 — Tailwind CSS 웹사이트 전체 빌드가 960ms에서 105ms로, Catalyst UI 키트는 341ms에서 55ms로 단축되었습니다.
- 더 작은 용량 — Rust와 Lightning CSS로 다시 작성한 네이티브 패키지가 포함되었음에도 불구하고, 새 엔진은 설치 용량이 35% 이상 줄었습니다.
- 필요한 부분에 Rust 적용 — 프레임워크에서 가장 비용이 많이 들고 병렬화 가능한 부분을 Rust로 이전했으며, 확장성을 위해 프레임워크의 핵심은 TypeScript로 유지했습니다.
- 단일 의존성 — 새 엔진은 Lightning CSS에만 의존합니다.
- 커스텀 파서 — 자체 CSS 파서를 작성하고 필요에 맞춘 데이터 구조를 설계해, PostCSS를 사용할 때보다 2배 이상 빠른 파싱 속도를 달성했습니다.
통합 툴체인
Tailwind CSS v4는 더 이상 단순한 플러그인이 아닙니다. 이제는 CSS를 처리하는 올인원 도구로 거듭났습니다. Lightning CSS를 프레임워크에 직접 통합했기 때문에 CSS 파이프라인을 따로 설정할 필요가 없습니다.
- 내장된
@import
처리 —postcss-import
같은 도구를 설정하고 구성할 필요가 없습니다. - 내장된 벤더 프리픽싱 — 더 이상 프로젝트에
autoprefixer
를 추가할 필요가 없습니다. - 내장된 중첩 지원 — 중첩된 CSS를 평탄화하기 위해 플러그인이 필요하지 않습니다. 바로 사용할 수 있습니다.
- 구문 변환 —
oklch()
색상 및 미디어 쿼리 범위와 같은 모던 CSS 기능이 더 나은 브라우저 지원을 위한 구문으로 변환됩니다.
여전히 PostCSS 플러그인을 제공하고 있지만, 공식 번들러 플러그인도 탐구 중입니다. 이번 첫 번째 알파 릴리스와 함께 공식 Vite 플러그인도 제공하니 지금 바로 사용해 볼 수 있습니다.
모던 웹을 위해 설계됨
우리는 Tailwind CSS v4를 통해 미래를 내다보며 앞으로 몇 년 동안 최첨단으로 느껴질 프레임워크를 구축하려고 합니다.
- 네이티브 캐스케이드 레이어 — 이제 실제
@layer
규칙을 사용하여, 과거에 고민했던 많은 명시도 문제를 해결했습니다. - 명시적으로 정의된 커스텀 속성 —
@property
를 사용하여 적절한 타입과 제약 조건으로 내부 커스텀 속성을 정의합니다. 이를 통해 배경 그라데이션 트랜지션과 같은 작업이 가능해졌습니다. - 불투명도 수정자를 위한
color-mix
사용 — CSS 변수를 사용하여 색상을 지정하거나currentColor
의 불투명도를 조정할 때, 불투명도 수정자 구문을 사용하기가 이전보다 훨씬 쉬워졌습니다. - 코어에 통합된 컨테이너 쿼리 — 새로운
@min-*
및@max-*
변형을 통해 컨테이너 쿼리 범위를 지원하는 컨테이너 쿼리 기능을 코어에 직접 추가했습니다.
또한, 와이드 색영역 색상으로 색상 팔레트를 새롭게 구성하고, @starting-style
, 앵커 포지셔닝 등 다른 모던 CSS 기능에 대한 지원도 도입하고 있습니다.
조합 가능한 변형
새로운 아키텍처는 group-*
, peer-*
, has-*
와 같은 선택자에 작용하는 변형들을 조합할 수 있게 해줍니다. 또한 v4에서 새롭게 도입된 not-*
변형도 사용할 수 있습니다.
이전 버전에서는 group-has-*
와 같은 변형이 프레임워크 내에서 명시적으로 정의되었지만, 이제는 group-*
가 기존의 has-*
변형과 조합될 수 있습니다. 이 변형은 focus
와 같은 다른 변형과도 조합이 가능합니다:
<div class="group"> <div class="group-has-[&:focus]:opacity-100"> <div class="group-has-focus:opacity-100"> <!-- ... --> </div> </div></div>
이 조합성에는 제한이 없으며, 만약 어쩌다가 그런 끔찍한 상황이 필요하다면 group-not-has-peer-not-data-active:underline
과 같은 코드도 작성할 수 있습니다.
Zero-configuration content detection
여러분은 초기 알파 릴리스에서 content
경로를 설정할 수 없다는 것을 눈치챘을 겁니다. 대부분의 프로젝트에서는 이 설정을 다시 할 필요가 없습니다. Tailwind가 여러분의 템플릿 파일을 자동으로 찾아주기 때문입니다.
이 기능은 Tailwind를 프로젝트에 통합한 방식에 따라 두 가지 방법 중 하나로 동작합니다:
-
PostCSS 플러그인이나 CLI를 사용하는 경우, Tailwind는 프로젝트 전체를 크롤링하여 템플릿 파일을 찾습니다. 이때
.gitignore
파일에 포함된 디렉토리는 크롤링하지 않고, 바이너리 파일 형식은 무시하는 등 내장된 휴리스틱을 사용해 빠르게 동작합니다. -
Vite 플러그인을 사용하는 경우, 모듈 그래프에 의존합니다. 이 방식은 실제로 사용 중인 파일만 정확히 알 수 있어 최적의 성능을 보장하며, 오탐지나 미탐지가 발생하지 않습니다. 앞으로 다른 번들러 플러그인을 통해 Vite 생태계 외부에서도 이 방식을 확장할 계획입니다.
향후에는 명시적으로 content 경로를 설정할 수 있는 방법을 도입할 예정이지만, 이 자동화된 접근 방식이 얼마나 잘 동작하는지 지켜보고 싶습니다. 현재 우리 프로젝트에서는 훌륭하게 동작하고 있습니다.
CSS 우선 설정
Tailwind CSS v4.0의 주요 목표는 이 프레임워크를 CSS 네이티브처럼 느껴지게 하고, 자바스크립트 라이브러리처럼 느껴지지 않도록 하는 것입니다.
설치한 후에는 일반 CSS @import
문을 사용해 프로젝트에 추가할 수 있습니다:
@import "tailwindcss";
그리고 자바스크립트 설정 파일에서 모든 커스터마이징을 설정하는 대신, CSS 변수를 사용하면 됩니다:
@import "tailwindcss";@theme { --font-family-display: "Satoshi", "sans-serif"; --breakpoint-3xl: 1920px; --color-neon-pink: oklch(71.7% 0.25 360); --color-neon-lime: oklch(91.5% 0.258 129); --color-neon-cyan: oklch(91.3% 0.139 195.8);}
특별한 @theme
지시문은 Tailwind에게 이러한 변수를 기반으로 새로운 유틸리티와 변형을 사용할 수 있게 합니다. 이를 통해 마크업에서 3xl:text-neon-lime
와 같은 클래스를 사용할 수 있습니다:
<div class="max-w-lg 3xl:max-w-xl"> <h1 class="font-display text-4xl"> Data to <span class="text-neon-cyan">enrich</span> your online business </h1></div>
새로운 CSS 변수를 추가하는 것은 이전 버전의 extend
와 비슷하게 동작하지만, --color-*: initial
과 같은 구문으로 네임스페이스를 지우고 모든 커스텀 값을 정의할 수 있습니다:
@import "tailwindcss";@theme { --color-*: initial; --color-gray-50: #f8fafc; --color-gray-100: #f1f5f9; --color-gray-200: #e2e8f0; /* ... */ --color-green-800: #3f6212; --color-green-900: #365314; --color-green-950: #1a2e05;}
아직 몇 가지 네이밍 규칙을 조정 중이지만, GitHub에서 기본 테마를 탐색하여 커스터마이징할 수 있는 내용을 확인할 수 있습니다.
기본 테마를 명시적으로 지우지 않고 처음부터 시작하려면, "tailwindcss/preflight"
와 "tailwindcss/utilities"
를 직접 임포트하여 기본 테마를 임포트하지 않을 수 있습니다:
@import "tailwindcss";@import "tailwindcss/preflight" layer(base);@import "tailwindcss/utilities" layer(utilities);@theme { --color-*: initial; --color-gray-50: #f8fafc; --color-gray-100: #f1f5f9; --color-gray-200: #e2e8f0; /* ... */ --color-green-800: #3f6212; --color-green-900: #365314; --color-green-950: #1a2e05;}
또한 커스텀 CSS에서 모든 테마 값을 네이티브 CSS 변수로 사용할 수 있습니다:
:root { --color-gray-50: #f8fafc; --color-gray-100: #f1f5f9; --color-gray-200: #e2e8f0; /* ... */ --color-green-800: #3f6212; --color-green-900: #365314; --color-green-950: #1a2e05;}
이를 통해 theme()
함수 없이도 임의의 값에서 테마 값을 쉽게 참조할 수 있습니다:
<div class="p-[calc(var(--spacing-6)-1px)]"> <!-- ... --></div>
또한 Framer Motion과 같은 UI 라이브러리와 작업할 때 resolveConfig()
함수를 사용하지 않고도 테마 값을 사용할 수 있습니다:
import { motion } from "framer-motion";export const MyComponent = () => ( <motion.div initial={{ y: "var(--spacing-8)" }} animate={{ y: 0 }} exit={{ y: "var(--spacing-8)" }}> {children} </motion.div>);
변경 사항
우리는 호환성 깨짐(breaking changes)을 가볍게 다루지 않지만, v4에서 지금까지 달라진 몇 가지 사항을 공유할 가치가 있습니다:
- 더 이상 사용되지 않는 유틸리티 제거 — 오래 전부터 문서화를 중단한
text-opacity-*
,flex-grow-*
,decoration-slice
와 같은 유틸리티를 제거했습니다. 대신text-{color}/*
,grow-*
,box-decoration-slice
와 같은 현대적인 대체품을 사용합니다. - PostCSS 플러그인과 CLI가 별도의 패키지로 분리 — 메인
tailwindcss
패키지에는 더 이상 이들이 포함되지 않습니다. 모든 사람이 필요로 하지 않기 때문입니다. 대신@tailwindcss/postcss
와@tailwindcss/cli
를 별도로 설치해야 합니다. - 기본 테두리 색상 없음 —
border
유틸리티는 이전에gray-200
을 기본값으로 사용했지만, 이제는 브라우저처럼currentColor
를 기본값으로 사용합니다. 이 변경은 여러분이zinc
나slate
또는 다른 색상을 주요 회색으로 사용할 때 실수로 잘못된 회색을 도입하는 것을 방지하기 위해 이루어졌습니다. - 링 두께가 기본 1px로 변경 —
ring
유틸리티는 이전에 기본적으로 3px 파란색 링이었지만, 이제는currentColor
를 사용하는 1px 링으로 변경되었습니다. 우리는 프로젝트에서ring-*
유틸리티를 테두리 대안으로 사용하고, 포커스 링에는outline-*
를 사용하는 경우가 많아 이 부분을 일관성 있게 만드는 것이 유용한 변경이라고 생각했습니다.
이 외에도 프로젝트에서 어떤 식으로든 드러날 수 있는 몇 가지 저수준 구현 세부 사항 변경이 있지만, 이들처럼 의도적인 변경은 아닙니다. 만약 예상치 못한 문제를 발견한다면 알려주세요.
v4.0 로드맵
이 새로운 엔진은 처음부터 다시 작성된 것이며, 지금까지는 새로운 설정 방식을 사용한 개발자 경험에만 집중해 왔습니다.
우리는 하위 호환성에 큰 가치를 두고 있으며, 올해 안에 안정적인 v4.0 릴리스를 태그하기 전에 대부분의 작업이 여기에 집중될 것입니다.
- JavaScript 설정 파일 지원 — 클래식
tailwind.config.js
파일과의 호환성을 다시 도입하여 v4로의 마이그레이션을 쉽게 만듭니다. - 명시적인 콘텐츠 경로 설정 — 자동 콘텐츠 감지가 설정에 충분하지 않을 때, Tailwind에게 템플릿이 어디에 있는지 정확히 알릴 수 있게 합니다.
- 다른 다크 모드 지원 — 현재는 미디어 쿼리를 사용한 다크 모드만 지원하며, 선택자와 변형 전략을 다시 구현해야 합니다.
- 플러그인과 커스텀 유틸리티 — 아직 플러그인 지원이나 변형과 자동으로 작동하는 커스텀 유틸리티 작성 기능이 없습니다. 당연히 안정적인 릴리스 전에 이를 구현할 것입니다.
- 접두사 지원 — 아직 클래스에 접두사를 설정할 방법이 없지만, 반드시 다시 도입할 것입니다.
- 안전 목록과 차단 목록 — 특정 클래스를 강제로 생성하거나 다른 클래스의 생성을 방지할 수 있는 기능이 아직 없습니다.
important
설정 지원 — 현재 유틸리티가 모두!important
로 생성되도록 설정할 방법이 없지만, 이를 구현할 계획입니다.theme()
함수 지원 — 새로운 프로젝트에서는var()
를 사용할 수 있기 때문에 필요하지 않지만, 하위 호환성을 위해 구현할 것입니다.- 독립형 CLI — 새로운 엔진을 위한 독립형 CLI는 아직 작업하지 않았지만, v4.0 릴리스 전에 반드시 제공할 것입니다.
이 외에도, 많은 버그를 수정하고, 몇 가지 흥미로운 새로운 CSS 기능을 추가하며, 적절한 릴리스 전에 더 다듬어야 할 새로운 API를 개선할 것입니다.
특정 릴리스 타임라인에 대해 약속하고 싶지는 않지만, 개인적으로는 여름 휴가 시즌이 시작되기 전에 v4.0을 안정적으로 표시하고 싶습니다.
알파 버전 사용해 보기
이미 몇 가지 알파 버전을 출시했으니, 여러분의 프로젝트에서 지금 바로 사용해 볼 수 있습니다.
VS Code용 Tailwind CSS IntelliSense 확장을 사용 중이라면, 확장 페이지에서 프리릴리스 버전으로 전환하세요. Prettier 플러그인을 사용 중이라면 최신 버전을 설치하세요.
문제를 발견하면 GitHub에서 알려주세요. 안정적인 버전을 출시하기 전에 이 기능이 완벽하게 동작하길 바라며, 발견한 문제를 보고해 주시면 큰 도움이 됩니다.
Vite 사용하기
Tailwind CSS v4 알파 버전과 새로운 Vite 플러그인을 설치하세요:
npm install tailwindcss@next @tailwindcss/vite@next
그런 다음 vite.config.ts
파일에 플러그인을 추가하세요:
import tailwindcss from "@tailwindcss/vite";import { defineConfig } from "vite";export default defineConfig({ plugins: [tailwindcss()],});
마지막으로, 메인 CSS 파일에서 Tailwind를 불러오세요:
@import "tailwindcss";
PostCSS 사용하기
Tailwind CSS v4 알파 버전과 별도의 PostCSS 플러그인 패키지를 설치하세요:
npm install tailwindcss@next @tailwindcss/postcss@next
그런 다음 postcss.config.js
파일에 플러그인을 추가하세요:
module.exports = { plugins: { "@tailwindcss/postcss": {}, },};
마지막으로, 메인 CSS 파일에서 Tailwind를 불러오세요:
@import "tailwindcss";
CLI 사용하기
Tailwind CSS v4 알파 버전과 별도의 CLI 패키지를 설치합니다:
npm install tailwindcss@next @tailwindcss/cli@next
다음으로, 메인 CSS 파일에서 Tailwind를 불러옵니다:
@import "tailwindcss";
마지막으로, CLI 도구를 사용해 CSS를 컴파일합니다:
npx @tailwindcss/cli@next -i app.css -o dist/app.css