travel-planning-app/
├─ apps/
│ └─ web/
│ ├─ src/
│ │ ├─ App.tsx
│ │ ├─ index.css
│ │ └─ ...
│ ├─ package.json
│ ├─ postcss.config.js
│ └─ ...
└─ packages/
└─ ui/
├─ src/
│ ├─ style.css
│ └─ ...
├─ package.json
├─ postcss.config.mjs
└─ ...
루트 또는 각 패키지에서 다음을 설치합니다.
pnpm add -w tailwindcss@^4 postcss autoprefixer
packages/ui/package.json:
{
"name": "@repo/ui",
"version": "1.0.0",
"main": "src/index.ts",
"types": "src/index.ts",
"style": "src/style.css",
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts"
},
"./style": {
"import": "./src/style.css",
"default": "./src/style.css"
}
},
"files": [
"src"
]
}
.: ..../style:style: "src/style.css"files: ["src"]Tip:
실제 배포 환경에서는 빌드 결과물(dist/style.css)로 경로를 맞추는 것이 더 안전합니다.
개발 중에는 src/style.css로도 충분히 동작합니다.
packages/ui/src/style.css:
@import "tailwindcss";
/* 디자인 토큰 */
:root {
--color-primary: #2563eb;
--color-secondary: #64748b;
--radius-base: 8px;
--font-sans: 'Inter', sans-serif;
}
/* 토큰 활용 커스텀 유틸리티 */
.btn {
/* tailwind 유틸리티와 CSS 변수 혼합 */
padding: 0.5rem 1rem;
border-radius: var(--radius-base);
background: var(--color-primary);
color: #fff;
font-family: var(--font-sans);
transition: background 0.2s;
}
.btn-secondary {
background: var(--color-secondary);
}
.card {
border-radius: var(--radius-base);
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
background: #fff;
padding: 1.5rem;
}
핵심:
Tailwind v4에서는@import "tailwindcss";한 줄로 모든 유틸리티가 자동 적용됩니다.
커스텀 유틸리티와 디자인 토큰은 그 아래에 자유롭게 작성하면 됩니다.
packages/ui/postcss.config.mjs:
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
apps/web/src/index.css:
@import '@repo/ui/style';
:root {
--color-primary: #10b981; /* 앱 전용 색상 오버라이드 */
}
/* 앱 전용 커스텀 유틸리티 확장 */
.card {
border: 1px solid #e5e7eb; /* tailwind border-gray-200 */
}
apps/web/postcss.config.js:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
사용하는 쪽에서 postcss.config.js가 이렇게 안되어있다면 tailwindcss가 적용이 되지 않습니다. 따라서 @repo/ui를 사용하는 쪽인 web에서도 postcss.config.js가 필요합니다
apps/web/src/main.tsx:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css'; // 반드시 import
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
apps/web/src/index.css에서 원하는 토큰만 덮어쓰기:
:root {
--color-primary: #10b981; /* 앱 전용 색상 */
}
apps/web/src/App.tsx:
import React from 'react';
export default function App() {
return (
<div className="card">
<h1 className="text-2xl font-bold mb-4" style={{ color: 'var(--color-primary)' }}>
여행 플래너
</h1>
<button className="btn">시작하기</button>
<button className="btn btn-secondary ml-2">둘러보기</button>
<div className="mt-6 p-4 bg-gray-50 rounded-lg">
<p className="text-gray-600">Tailwind v4 유틸리티와 디자인 토큰이 함께 동작합니다.</p>
</div>
</div>
);
}
{
"name": "@repo/ui",
"version": "1.0.0",
"main": "src/index.ts",
"types": "src/index.ts",
"style": "src/style.css",
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts"
},
"./style": {
"import": "./src/style.css",
"default": "./src/style.css"
}
},
"files": [
"src"
]
}
@import "tailwindcss";
:root {
--color-primary: #2563eb;
--color-secondary: #64748b;
--radius-base: 8px;
--font-sans: 'Inter', sans-serif;
}
.btn {
padding: 0.5rem 1rem;
border-radius: var(--radius-base);
background: var(--color-primary);
color: #fff;
font-family: var(--font-sans);
transition: background 0.2s;
}
.btn-secondary {
background: var(--color-secondary);
}
.card {
border-radius: var(--radius-base);
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
background: #fff;
padding: 1.5rem;
}
@import '@repo/ui/style';
:root {
--color-primary: #10b981; /* 앱 전용 색상 */
}
.card {
border: 1px solid #e5e7eb; /* tailwind border-gray-200 */
}
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
import React from 'react';
export default function App() {
return (
<div className="card">
<h1 className="text-2xl font-bold mb-4" style={{ color: 'var(--color-primary)' }}>
여행 플래너
</h1>
<button className="btn">시작하기</button>
<button className="btn btn-secondary ml-2">둘러보기</button>
<div className="mt-6 p-4 bg-gray-50 rounded-lg">
<p className="text-gray-600">Tailwind v4 유틸리티와 디자인 토큰이 함께 동작합니다.</p>
</div>
</div>
);
}
@repo/ui/style을 import하여, 디자인 토큰과 커스텀 유틸리티를 손쉽게 공유할 수 있습니다.이 방식은 Tailwind CSS v4의 최신 방식과
디자인 토큰/유틸리티의 패키지화를 결합한
현대적인 monorepo UI 확장 패턴입니다.