tailwind-css

4 개의 포스트

github

GitHub Copilot 앱에서 세션과 풀 리퀘스트 쌓기 (새 탭에서 열림)

10년 넘은 React 15·Less·구버전 react-bootstrap 기반 프로젝트를 GitHub Copilot 앱으로 현대화한 경험을 소개합니다. 한 번에 전체를 바꾸려 하지 않고, 기존 작업을 세션과 브랜치별로 나누어 순차적으로 진행하는 “스택 세션” 방식이 핵심입니다. AI가 계획 수립, 코드 변경, PR 생성, 브랜치 전환까지 지원하면서 오래된 프로젝트의 대규모 유지보수를 현실적으로 수행할 수 있었다는 결론입니다. ## 오래된 프런트엔드 현대화의 어려움 - 개인용 대시보드 애플리케이션을 2014년경부터 운영해 왔습니다. - React 15, Less, 구버전 `react-bootstrap` 등 의존성이 수년간 업데이트되지 않았습니다. - 애플리케이션 규모가 아주 크지는 않지만, 구조가 충분히 복잡해 수작업으로 정리하려면 수주가 걸릴 상황이었습니다. - 과거에도 현대화를 시도했지만 호환성 문제 때문에 중단한 경험이 있었습니다. ## 첫 시도: 전체 현대화를 한 번에 진행하기 - Copilot의 Plan 모드에서 다음 작업을 요청했습니다. - Tailwind와 vanilla CSS 중 적절한 방식 검토 - Less 제거 - 접근성 및 반응형 개선 - 의존성 현대화 - React 기능의 점진적 정리와 통합 - 링크의 hover/focus 스타일 개선 - 입력 필드의 테두리 반경 축소와 라벨 정리 - 컨테이너 최대 너비와 적절한 줄바꿈 적용 - Claude Opus 4.8과 GPT-5.5의 검토를 거쳐 계획을 다듬은 뒤 실제 변경을 시작했습니다. - 그러나 처음부터 `main` 브랜치를 기준으로 작업한 것이 문제였습니다. AI가 충분히 좋은 계획을 세웠더라도, 현재 운영 중인 코드의 실제 기준 브랜치를 잘못 선택하면 결과가 실행되지 않을 수 있었습니다. ## 기존 `dev` 브랜치와의 충돌 발견 - 과거에 중단한 줄 알았던 현대화 작업이 실제로는 `dev` 브랜치에 일부 남아 있었습니다. - 현재 배포 환경은 `main`이 아니라 부분적으로 업데이트된 `dev` 브랜치를 사용하고 있었습니다. - 따라서 새 작업을 `main`에서 시작하면 기존 기능과 설정이 누락될 수 있었습니다. - 변경 규모가 커서 `dev`의 내용을 `main`으로 병합하기보다, 기존 PR을 닫고 `dev`에서 새 작업을 시작하는 편이 안전했습니다. - Copilot은 사용자의 지시에 따라: - 기존 세션의 PR을 닫고 - `dev`에서 새 브랜치를 만들고 - 기존 스타일·접근성 개선안을 새 기준에 맞게 다시 적용했습니다. ## 테스트 중 발견한 오래된 의존성 문제 - 스타일 변경 후 테스트하는 과정에서 `findDOMNode`, `componentWillReceiveProps` 관련 경고가 나타났습니다. - 문제의 상당 부분은 애플리케이션 코드가 아니라 오래된 `react-bootstrap`에 있었습니다. - Copilot의 Plan 모드에 다음 두 가지 선택지를 검토하게 했습니다. - `react-bootstrap`을 업그레이드해 기존 컴포넌트를 마이그레이션하기 - 라이브러리를 완전히 제거하고 현대적인 대체 구현으로 교체하기 - 분석 결과, 기존 라이브러리를 유지하기보다 전체 교체하는 방향이 권장되었습니다. ## 스택 세션과 분리된 pull request - `react-bootstrap` 교체는 기존 스타일·접근성 작업과 관련이 있지만, 범위가 크게 늘어나는 별도 작업이었습니다. - AI를 활용하면 구현 비용이 낮아 보여 여러 문제를 한 번에 해결하고 싶어지지만, 결과적으로 1만 줄 규모의 거대한 PR이 될 수 있습니다. - 이를 방지하기 위해 작업을 다음처럼 나눴습니다. - 먼저 현재 스타일·접근성 작업을 하나의 PR로 제출 - 해당 작업을 기반으로 새 세션과 브랜치를 생성 - 새 세션에서 `react-bootstrap` 교체를 별도 PR로 진행 - 첫 번째 PR을 `dev`에 병합한 뒤 두 번째 PR을 병합 - 이렇게 각 세션이 이전 세션의 결과 위에 쌓이도록 구성하면 작업 간 의존성은 유지하면서도 변경 범위와 검토 단위를 작게 만들 수 있습니다. ## 실용적인 결론 - AI에게 전체 프로젝트를 한 번에 현대화하게 하기보다, 기준 브랜치와 작업 범위를 먼저 확인하는 것이 중요합니다. - 스타일 개선, 의존성 교체, 기능 리팩터링을 각각 독립적인 세션과 PR로 나누면 테스트와 롤백이 쉬워집니다. - 특히 오래된 저장소에서는 현재 배포 브랜치가 무엇인지 확인한 뒤, 그 브랜치에서 새 세션을 시작하는 방식을 추천합니다.

github

GitHub Copilot CLI로 개인용 정리 커맨드 센터 구축하기 (새 탭에서 열림)

여러 앱에 흩어진 업무 정보를 하나로 모으기 위해, GitHub 엔지니어 Brittany Ellich가 개인용 조직 관리 커맨드 센터를 만들었다. 이 프로젝트는 일상적인 디지털 파편화 문제를 해결하는 데 초점을 맞췄으며, GitHub Copilot을 기획과 구현 전반에 활용해 하루 만에 v1을 완성했다. 글은 작은 개인적 불편에서 출발해 AI 도구로 실제 생산성 도구를 만드는 과정을 소개한다. ## 디지털 파편화를 해결하는 개인용 커맨드 센터 - 여러 앱을 오가며 발생하는 컨텍스트 전환과 정보 분산을 해결하기 위해 중앙 집중형 작업 공간을 구축했다. - 사용자가 정보를 시각적으로 파악하고 사고하는 방식에 맞춘 “차분하고 시각적인 홈 화면”을 목표로 했다. - 캘린더, 업무 정보, 음성 비서 등 다양한 기능을 한곳에서 사용할 수 있도록 설계했다. ## 기획 후 구현하는 AI 협업 방식 - Brittany는 먼저 요구사항을 정리한 뒤 구현하는 `plan-then-implement` 방식을 사용한다. - 기획 단계에서 Copilot이 질문을 연속적으로 던지도록 해 다음 사항을 구체화했다. - 애플리케이션이 어떻게 동작해야 하는지 - 사용자가 어떤 흐름으로 기능을 이용하는지 - 구현에 필요한 요구사항과 우선순위 - 충분히 구체화된 계획을 Copilot에 전달하고, 이를 기반으로 실제 구현을 진행했다. - 이 방식 덕분에 다른 업무를 병행하면서도 아이디어에서 작동하는 v1까지 하루 만에 도달할 수 있었다. ## 동기·비동기 에이전트 활용 - 동기식 개발에는 VS Code의 Agent Mode를 사용한다. - 서로 충돌하지 않는 작업은 최대 2개의 에이전트 워크플로로 동시에 진행한다. - 감독이 필요한 작업은 VS Code에서 직접 처리하고, 다음과 같은 범위가 명확한 작업은 Copilot Cloud Agent에 맡긴다. - 버그 수정 - 기술 부채 정리 - 비동기적으로 처리 가능한 소규모 변경 - 이를 통해 집중적인 개발과 백그라운드 작업을 병렬화한다. ## 기술 스택과 프로젝트 공개 - 애플리케이션은 다음 기술로 구성됐다. - **Electron**: 크로스 플랫폼 데스크톱 애플리케이션 프레임워크 - **React**: UI 컴포넌트와 상태 관리 - **Vite**: 빠른 개발 서버와 Hot Module Replacement를 제공하는 빌드 도구 - **Tailwind CSS**: 유틸리티 기반 CSS 프레임워크 - **WorkIQ MCP**: Microsoft 365 데이터에 접근하기 위한 MCP 서버와 CLI - 초기 구현 대부분을 Agent Mode로 진행했기 때문에 Electron 자체를 깊이 학습하지는 않았다고 설명한다. - 다만 공개 저장소로 정리하는 과정에서는 직접 코드를 읽고 불필요한 코드를 제거했다. - 에이전트는 코드를 추가하는 데는 능숙하지만, 불필요한 코드를 삭제하고 저장소를 단순화하는 작업에는 상대적으로 소극적이라는 경험도 공유한다. - 프로젝트는 `brittanyellich/command-center-lite` 저장소에서 확인할 수 있다. ## 실행에 필요한 환경 - 직접 프로젝트를 실행하려면 다음 조건이 필요하다. - Node.js 18 이상 - WorkIQ 설정을 위한 GitHub Copilot CLI - 캘린더 동기화를 위한 Microsoft 365 계정 - 음성 비서 기능을 위한 ElevenLabs 계정 - 구체적인 설치 및 실행 절차는 프로젝트의 README에 정리되어 있다. ## 작은 불편에서 시작하는 개발 - 가장 유용한 프로젝트는 거대한 아이디어보다 일상적인 불편을 해결하려는 시도에서 시작될 수 있다. - 기술 스택을 완벽히 이해한 뒤 시작하기보다, AI 도구의 도움을 받아 새로운 프레임워크와 서비스를 빠르게 조합할 수 있다. - Brittany의 조언은 간단하다. 직접 무언가를 만들어 보면서 새로운 AI 도구를 사용하는 방법을 익히라는 것이다. 개인 업무에서 반복적으로 앱을 전환하거나 정보를 수동으로 모으고 있다면, 먼저 해결할 불편을 하나 정한 뒤 Copilot으로 요구사항을 인터뷰하고 작은 v1을 만들어보는 접근이 실용적이다.

figma

디자인에서 코드로의 자동화를 (새 탭에서 열림)

Dev Mode의 코드 생성(codegen)은 디자인을 완성된 코드로 자동 변환하는 기능이라기보다, 개발자가 구현을 시작할 수 있도록 돕는 출발점이다. Figma는 기본 코드 스니펫을 제공하고, 팀의 디자인 시스템과 기술 스택에 맞춰 다양한 codegen 플러그인으로 확장할 수 있다고 설명한다. Anima, Builder, Figma to Code, Locofy.ai 같은 도구는 React·HTML·Tailwind부터 Flutter·SwiftUI까지 지원하며 반응형 구현과 컴포넌트화를 가속한다. ## Dev Mode와 codegen의 역할 - Codegen은 정해진 규칙이나 명세를 바탕으로 코드를 자동 생성하는 과정이다. - Figma Dev Mode에서 캔버스의 객체를 선택하면 Inspect 패널에 자동 코드 스니펫이 표시된다. - 사용자는 코드 언어와 단위 체계를 드롭다운에서 선택할 수 있다. - codegen은 디자인을 개발로 옮기는 작업을 완전히 대체하기보다, 매번 빈 화면에서 시작하지 않도록 구현의 출발점을 제공한다. - 성숙한 디자인 시스템을 운영하는 팀은 자체 규칙과 컴포넌트를 반영하기 위해 custom codegen 플러그인을 만들 수 있다. ## Anima를 활용한 디자인 코드 변환 - Figma의 레이어·컴포넌트·프레임을 React 또는 HTML 코드로 내보낼 수 있다. - CSS, SCSS, Tailwind 형식의 스타일 코드와 함께 인터랙티브하고 반응형인 결과물을 생성한다. - 반복되는 컴포넌트를 자동으로 감지해 코드 중복을 줄인다. - 팀이 사용하는 코드 스타일과 관례를 학습해 더 적절한 코드 스니펫을 제공한다. - Dev Mode에서 애니메이션을 추가하거나 특정 스타일에 맞게 코드를 조정하도록 요청할 수 있다. ## Builder의 AI 기반 코드 컴포넌트 활용 - React, Svelte, HTML 등의 코드를 AI로 생성한다. - 팀의 기존 코드 컴포넌트를 활용해 디자인과 실제 구현 사이의 간극을 줄인다. - 생성된 코드에 대해 대화형으로 수정 사항을 요청할 수 있다. - 팀의 코드 스타일에 맞도록 AI를 학습시키고, 디자인을 자동으로 반응형으로 변환할 수 있다. - Figma 밖의 별도 웹 인터페이스에서 생성 코드를 시험하고 수정할 수 있다. ## Figma to Code로 웹·모바일 코드 생성 - Figma Community에서 제공되는 무료 오픈 소스 플러그인이다. - 반응형 웹을 위해 HTML 또는 Tailwind 코드를 생성한다. - 모바일 앱 개발을 위해 Flutter와 SwiftUI 코드도 지원한다. - 플러그인에서 생성된 Tailwind 코드를 확인한 뒤 코드 에디터로 복사해 사용할 수 있다. - 별도의 유료 도구 없이 디자인을 여러 플랫폼의 코드로 빠르게 변환할 수 있다는 점이 특징이다. ## Locofy.ai를 통한 웹·모바일 프로토타입 구현 - React, HTML/CSS, Next.js, Gatsby, Vue 기반의 인터랙티브 코드를 생성한다. - 개별 컴포넌트뿐 아니라 전체 화면 단위의 코드 생성도 지원한다. - 자동 레이아웃과 프레임 그룹화 같은 디자인 최적화를 적용한다. - 시맨틱 HTML 요소, 라이브러리, 동작을 태깅해 인터랙션을 구성한다. - 화면 크기에 따른 반응형 동작을 지원한다. - 컴포넌트와 props를 생성해 결과물을 모듈화한다. - 사람이 이해하기 쉬운 문맥 기반 클래스명을 사용해 협업과 확장성을 높인다. - 생성 코드를 다듬은 뒤 프로토타입을 공유하고, 데이터를 연결하며, 코드나 Storybook 파일로 내보낼 수 있다. - GitHub와 직접 동기화하고 자동 병합 및 충돌 해결을 지원해 지속적 통합 흐름에 연결할 수 있다. 실무에서는 생성된 코드를 최종 결과물로 그대로 사용하기보다, 팀의 디자인 시스템·컴포넌트 구조·접근성·상태 관리·성능 기준에 맞게 검토하고 수정하는 것이 좋다. codegen 플러그인은 반복적인 초기 구현을 줄이고 협업을 빠르게 만드는 보조 도구로 활용할 때 가장 효과적이다.

figma

Tailwind UI 공식 피그 (새 탭에서 열림)

Tailwind Labs는 Tailwind UI의 코드 컴포넌트를 디자이너와 개발자가 함께 사용할 수 있는 공식 Figma 키트로 재구성했다. 약 1,400개의 컴포넌트와 10,000개의 요소를 제작하면서, 최종 코드 구조를 디자인 파일의 기준으로 삼고 레이어 이름·구조·변형을 체계화했다. 핵심 결론은 디자인 시스템을 실제 제품처럼 배포하려면 시각적 완성도뿐 아니라 일관된 구조와 사용성까지 세밀하게 설계해야 한다는 것이다. ## Tailwind UI Figma 키트 제작 배경 - Tailwind UI는 Tailwind CSS 기반의 반응형 HTML 컴포넌트 모음이다. - 고객들의 Figma 파일 요청이 지속적으로 늘어나 공식 Figma 키트를 제작하게 됐다. - 400개가 넘는 코드 컴포넌트를 바탕으로 1,400개 이상의 Figma 컴포넌트와 10,000개의 개별 요소를 구축했다. - 일반적인 작업용 디자인 파일과 달리, 상용 디자인 키트는 파일 자체가 최종 제품이므로 모든 세부 요소가 사용자 경험에 영향을 준다. ## 디자인 파일을 코드의 구조에 맞추기 - 최종 HTML 코드가 디자인 파일이 따라야 할 픽셀 단위 기준이 되도록 했다. - Figma의 오토 레이아웃, 레이아웃 그리드, 레이아웃 제약 조건을 활용해 HTML 마크업과 유사한 레이어 구조를 만들었다. - 디자인과 코드가 비슷한 구조를 가지면 디자이너와 개발자가 레이아웃 가능성을 공통으로 이해할 수 있다. - 반복되는 반응형 패딩이나 중앙 정렬된 최대 너비 컨테이너 같은 패턴을 디자인 파일에서 발견하고, 이를 개발자가 재사용 가능한 컨테이너 구조로 구현할 수 있었다. ## 일관된 레이어 이름 - 모든 레이어에 일관된 명명 규칙을 적용했다. - 예를 들어 버튼의 텍스트 레이어를 항상 `Text`로 지정하면, 버튼 크기나 변형을 바꿔도 사용자가 입력한 텍스트가 그대로 유지된다. - 복잡한 컴포넌트에서도 아이콘, 제목, 본문, 링크 등의 사용자 지정 내용이 다른 인스턴스나 변형으로 교체할 때 보존된다. - 일관된 레이어 이름은 단순한 정리 규칙이 아니라 Figma의 오버라이드 동작을 안정적으로 만드는 기반이다. ## 변형으로 컴포넌트 수 줄이기 - 여러 개의 유사한 컴포넌트를 개별적으로 관리하는 대신, 하나의 컴포넌트에 다양한 변형을 정의했다. - 예를 들어 80개의 배지 컴포넌트를 따로 만드는 대신 `type`, `size`, `theme`, 보조 요소 등의 속성을 가진 하나의 Badge 컴포넌트를 구성했다. - 코드 컴포넌트에서 사용하는 속성과 Figma의 변형 속성에 동일한 이름과 개념을 사용해 디자인과 개발 사이의 대응 관계를 명확히 했다. - 여러 컴포넌트에서 반복적으로 사용할 수 있는 변형 이름은 다음과 같다. - `type` - `size` - `theme` - `position` - `breakpoint` - `state` - 변형 패널 자체가 컴포넌트의 가능한 상태와 옵션을 설명하는 문서 역할을 한다. - 최종 키트에는 평균 7개의 변형을 가진 1,430개 컴포넌트가 포함됐다. - 변형을 사용하지 않았다면 컴포넌트 수가 10,000개를 넘었겠지만, 변형 덕분에 실제 코드 컴포넌트 수인 약 400개에 가까운 수준으로 관리할 수 있었다. ## 실용적인 결론 상용 Figma 키트를 만들 때는 화면을 예쁘게 복제하는 것보다 코드와 디자인의 구조를 일치시키는 일이 중요하다. 레이어 이름과 변형 속성을 처음부터 표준화하고, 반복되는 레이아웃 규칙을 컴포넌트 구조에 반영하면 사용자는 더 쉽게 커스터마이즈할 수 있고 디자인·개발 간 협업도 효율적으로 유지할 수 있다.