DevInsight

기술 뉴스와 개발 블로그 흐름을 가볍게 따라가는 곳

Frontend
조회 28분 읽기

디자인 시스템이 늦어질수록 MUI가 다시 호출되는 이유

MUI는 예쁜 버튼 몇 개를 빨리 붙이는 도구에 그치지 않는다. React 팀이 제품 일관성, theme 확장성, 접근성, 개발 속도를 한 번에 맞추려 할 때 왜 다시 Material UI를 검토하게 되는지, 그 실전 감각을 따라가는 에세이에 맞춘 메타데이터다.

#mui#material-ui#react#design-system#theming#accessibility#component-library#frontend

디자인 시스템이 늦어지는 팀에서 UI 라이브러리 선택은 취향의 문제가 아니라 시간의 문제로 바뀐다. 초반에는 누구나 가볍게 시작하고 싶어 한다. button, modal, input 몇 개쯤은 직접 만들 수 있다고 생각하고, 브랜드 톤도 아직 유동적이니 너무 큰 체계를 들이는 건 과하다고 느낀다. 그런데 제품이 커지고 화면 수가 늘어나고, 팀이 둘에서 열로 불어나는 순간 분위기가 달라진다. 바로 그때 이상하리만큼 자주 다시 거론되는 이름이 MUI다.

이 장면은 꽤 반복적이다. 처음에는 “너무 Material스럽지 않나”, “우리 서비스 느낌이 안 난다”, “디자인 시스템이 정리되면 그때 다시 보자” 같은 말이 나온다. 한동안은 Tailwind 같은 utility 중심 접근이나, 얇은 headless 조합, 혹은 사내 공용 컴포넌트의 느린 축적이 대안처럼 보인다. 그런데 어느 시점부터는 미묘한 비용이 쌓인다. 화면은 늘었는데 버튼 높이가 조금씩 다르고, disabled 상태의 대비가 페이지마다 흔들리고, dialog의 focus 이동이 애매해지고, dark mode는 늘 백로그 맨 아래에 남는다. 그때 MUI는 “예쁜 기본 컴포넌트 모음”이 아니라, 뒤늦게라도 질서를 회수할 수 있는 도구로 다시 읽히기 시작한다.

늦어질수록 기준선의 가치가 커진다

초기 제품에서는 속도가 제일 중요해 보인다. 실제로도 그렇다. 문제는 속도를 구성하는 요소를 종종 너무 좁게 본다는 점이다. 첫 화면을 만드는 속도와, 열다섯 번째 화면까지 같은 규칙으로 유지하는 속도는 다르다. 직접 만든 컴포넌트는 첫 주에는 빠르다. 둘째 달부터는 그 컴포넌트가 아니라 그 컴포넌트를 둘러싼 합의가 느려진다.

디자인 시스템이 아직 없는 팀은 대개 두 가지를 동시에 처리해야 한다. 제품을 만들어야 하고, 제품을 만들면서 규칙도 발견해야 한다. 이때 가장 위험한 상태는 “규칙이 없는데 자유롭다고 느끼는 상태”다. 자유로워 보이지만 사실은 모든 PR에서 spacing, typography, hover, error state를 다시 협상하고 있는 셈이다. MUI가 다시 소환되는 이유는 여기에 있다. 기준선이 이미 존재하기 때문이다. 기준선이 있다는 것은 미감이 고정된다는 뜻만이 아니다. 컴포넌트의 상태 모델, 접근성의 최소선, theme의 확장 경로, breakpoint 문법, override 방식까지 함께 정리된다는 뜻이다.

이 기준선은 완벽해서가 아니라, 충분히 넓고 오래 검증돼서 유리하다. 팀이 아직 자기 언어를 갖지 못했을 때는 “최적”보다 “안전한 공통어”가 더 큰 생산성을 만든다. 그리고 MUI는 React 생태계에서 그 공통어 역할을 오래 맡아 왔다.

버튼보다 무서운 것은 상태다

UI 라이브러리를 평가할 때 사람들은 자주 정적인 스크린샷을 떠올린다. 버튼이 예쁜지, input이 촌스럽지 않은지, 카드가 우리 브랜드와 어울리는지 같은 질문이다. 실전에서는 그보다 상태가 더 무섭다. hover, focus-visible, disabled, loading, selected, validation error, dense layout, mobile breakpoint, high contrast 환경, keyboard navigation 같은 것들 말이다.

사내에서 버튼 하나를 직접 만드는 일은 어렵지 않다. 하지만 그 버튼이 모든 상태에서 일관되게 동작하고, 다른 입력 컴포넌트와 시각적 위계를 공유하고, form helper text와 spacing rhythm을 맞추고, dialog 안에서도 기대한 대로 focus를 받으며, screen reader에 과도한 혼란을 주지 않게 만드는 일은 금세 복잡해진다. 이 복잡도는 화면이 예뻐 보이는지와는 다른 층위의 문제다.

MUI가 자주 재평가되는 이유는 이 상태의 복잡도를 라이브러리 차원에서 흡수해 주기 때문이다. 팀은 그 위에서 브랜드를 덧입히면 된다. 여기서 중요한 판단이 하나 생긴다. “우리는 시각 언어를 직접 만들고 싶은가”와 “상태 모델까지 직접 책임지고 싶은가”는 전혀 다른 질문이라는 점이다. 앞의 질문에는 많은 팀이 예라고 답하지만, 뒤의 질문까지 흔쾌히 예라고 답할 수 있는 팀은 생각보다 많지 않다.

MUI는 Material Design의 복제품이 아니라 조정 가능한 뼈대에 가깝다

MUI를 한 번 멀리했던 팀이 다시 돌아올 때 가장 크게 바뀌는 인식은 이것이다. “MUI를 쓰면 우리 서비스가 전부 Google처럼 보이지 않나?”라는 오래된 반응이, “생각보다 껍데기는 많이 바꿀 수 있네”로 이동한다는 점이다. 이 변화는 단순한 취향 문제가 아니다. theme와 component override가 팀의 설계 언어를 담는 그릇이 될 수 있다는 경험이 쌓였기 때문이다.

MUI의 강점은 기본 컴포넌트 수 자체보다, 그것들을 같은 theme 축 아래에서 다룰 수 있다는 데 있다. 색상, 타이포그래피, spacing, breakpoint, elevation, shape 같은 토큰이 중심에 있고, 각 컴포넌트가 그 토큰을 어떻게 소비하는지 연결돼 있다. 그래서 디자인 시스템이 늦어진 팀이라도 “완성된 시스템을 들여오는” 대신 “진행 중인 시스템을 토큰 단위로 정리하는” 방식으로 접근할 수 있다.

예를 들어 브랜드 색을 primary 하나로만 바꾸는 수준에서 출발해도 된다. 조금 지나면 typography 스케일을 손보고, 그다음에는 MuiButton, MuiTextField, MuiDialog에 공통 override를 얹는다. 더 성숙해지면 palette를 semantic color 중심으로 재구성하고, spacing을 촘촘하게 다듬고, mode 전환이나 CSS variable 기반 토큰 관리까지 검토한다. 중요한 것은 이 여정이 단절되지 않는다는 점이다. MUI는 “초기 MVP용”과 “운영 단계용”이 완전히 다른 길로 갈라지는 라이브러리가 아니라, 같은 중심을 가지고 점진적으로 깊어질 수 있는 쪽에 가깝다.

짧은 예시 하나만 보자.

import { createTheme, ThemeProvider } from '@mui/material/styles'; const theme = createTheme({ palette: { primary: { main: '#1459c7' }, error: { main: '#c62828' }, }, shape: { borderRadius: 10, }, components: { MuiButton: { defaultProps: { disableElevation: true }, styleOverrides: { root: { textTransform: 'none', fontWeight: 700, }, }, }, }, });

이 코드 자체는 대단하지 않다. 그런데 실무에서는 이런 작은 중심축이 팀 전체의 시각적 드리프트를 줄인다. 중요한 것은 버튼 하나가 아니라, “버튼은 이 팀에서 이렇게 생기고 이렇게 행동한다”는 선언이 코드 형태로 중앙에 존재한다는 사실이다.

디자인 시스템이 늦어질 때 가장 먼저 무너지는 곳

팀이 디자인 시스템 없이도 꽤 오래 버틸 수 있는 영역이 있다. 마케팅 페이지나 일회성 랜딩은 의외로 버틴다. 정말 빨리 균열이 생기는 쪽은 업무 흐름이 긴 화면이다. 예를 들면 설정 페이지, 관리자 콘솔, 결제 플로우, 데이터 입력이 많은 백오피스, 상태가 복잡한 대시보드 같은 곳이다. 이런 화면들은 예쁘기만 해서는 안 된다. 빠르게 읽히고, 오류를 덜 만들고, 상호작용이 예측 가능해야 한다.

바로 이 지점에서 component library의 힘이 드러난다. MUI는 폼, 피드백, 내비게이션, 레이아웃, 오버레이 같은 흔한 UI 문제를 꽤 넓은 범위로 덮는다. 덕분에 팀은 “무엇을 어떻게 조합할지”에 집중할 수 있고, 기본적인 상호작용의 하부 비용을 줄일 수 있다. 직접 만든 시스템은 여기서 자주 늦어진다. 토큰은 어느 정도 정했는데, 정작 Date Picker나 Autocomplete, 복합 테이블, keyboard focus가 많은 overlay 계열은 후순위로 밀린다. 그러면 디자인 시스템은 있어도 실제 제품은 여전히 일관되지 않다.

MUI가 다시 검토되는 순간은 대체로 이 간극이 보일 때다. 토큰과 컴포넌트 카탈로그를 만들고는 있는데, 제품은 지금 돌아가야 하고, 복합 입력 UI는 계속 늘어나며, 팀은 모든 edge case를 직접 학습할 시간이 없다. 이때 MUI는 미학보다 운영 비용의 언어로 설득력을 가진다.

접근성은 선언보다 구현 디테일에서 갈린다

접근성은 많은 팀이 중요하다고 말하지만, 실제로는 마지막 QA 단계에서 “심각한 문제만 없으면” 정도로 흘러가기 쉽다. 이유는 간단하다. 접근성은 디자인 시안에서 잘 보이지 않고, 코드 리뷰에서도 종종 기능 우선순위에 밀리기 때문이다. 하지만 운영 단계에서는 접근성 결함이 아주 다른 방식으로 나타난다. 키보드만으로 탐색할 때 특정 dialog에서 빠져나오지 못하거나, label과 helper text 연결이 뒤틀려 form 오류가 과도하게 난해해지거나, 색 대비가 다크 모드에서 급격히 무너지는 식이다.

MUI를 다시 보게 되는 팀들은 대개 여기서 현실적인 판단을 한다. 접근성을 “완벽히 해결해 준다”는 기대보다는, 최소한의 안전장치를 갖춘 출발점을 얻는다는 감각이다. 이 차이는 크다. 출발점이 있는 팀은 예외를 다루면 되지만, 출발점이 없는 팀은 매번 정의부터 다시 해야 한다.

특히 디자인 시스템이 늦어진 조직에서는 accessibility와 design consistency가 별개 이슈처럼 취급되기 쉽다. 실제로는 둘이 한 몸이다. focus style이 일관되다는 것은 브랜드 통일성만이 아니라 탐색 가능성의 문제이고, spacing 규칙이 정교하다는 것은 미감만이 아니라 오독을 줄이는 정보 구조의 문제다. MUI는 이 둘을 같은 설계 층위에서 다루게 해 준다. 그게 생각보다 큰 차이를 만든다.

왜 다른 선택지들이 있는데도 다시 돌아오게 될까

React 생태계에는 이미 선택지가 많다. headless UI 철학도 강하고, utility-first 스타일링도 널리 쓰이며, component primitive 중심 접근도 성숙해졌다. 그래서 MUI 회귀를 단순히 “보수적인 선택”으로 읽으면 반만 본 셈이다. 실제로는 팀의 현재 조건이 바뀌었기 때문에 판단이 달라지는 경우가 많다.

직접 설계한 UI 레이어가 잘 작동하려면 몇 가지 전제가 필요하다. 컴포넌트 책임을 길게 관리할 사람이 있어야 하고, 디자인과 프런트엔드 사이의 합의 비용을 감당해야 하며, 토큰 체계와 문서화가 지속적으로 유지돼야 하고, 상태 복잡도가 높은 컴포넌트를 직접 품을 역량도 있어야 한다. 이 전제들이 갖춰진 팀이라면 MUI 없이도 강한 시스템을 만들 수 있다. 문제는 많은 팀이 그 문턱을 넘기 전 이미 제품이 커진다는 점이다.

MUI가 강해지는 순간은 바로 그 중간지대다. 완전한 사내 디자인 시스템을 운영할 만큼 여유롭지는 않지만, 이제 아무 컴포넌트나 붙이는 단계는 끝난 팀. 브랜드 차별화는 필요하지만, 기본 동작의 안정성을 일일이 재구현하고 싶지는 않은 팀. 이 팀들에게 MUI는 임시방편이 아니라 균형점이다.

함정도 분명하다

이쯤 되면 반대편 비용도 봐야 한다. MUI가 만능이었다면 이런 논쟁은 진작 끝났을 것이다. 실제로 MUI 도입이 실패하는 경우도 적지 않다. 가장 흔한 이유는 “조금만 건드리면 되겠지”라는 과소평가다.

첫 번째 함정은 override의 범위를 통제하지 못하는 것이다. 팀 공통 theme에서 풀어야 할 문제와, 특정 화면에서만 필요한 예외를 구분하지 못하면 스타일링 규칙이 급격히 지저분해진다. sx가 지나치게 퍼지고, 같은 Button이 페이지마다 다른 radius와 padding을 갖기 시작하면, 라이브러리를 도입했는데도 일관성은 회복되지 않는다. MUI의 문제라기보다 체계 없이 override를 남발한 문제지만, 체감은 라이브러리 탓으로 돌아가기 쉽다.

두 번째 함정은 Material Design의 그림자를 너무 의식하는 것이다. 기본값이 강한 만큼, 브랜드를 분명하게 바꾸려면 토큰과 component-level override에 대한 의지가 필요하다. “기본 상태로 쓰되 우리 느낌도 나야 한다”는 욕심은 종종 둘 다 놓친다. 이때 필요한 건 대규모 리빌드가 아니라 핵심 컴포넌트 몇 개에 대한 선명한 재정의다. Button, TextField, Surface, Navigation 계열만 제대로 다뤄도 제품 인상은 꽤 달라진다.

세 번째 함정은 디자인 시스템의 책임을 라이브러리에 전가하는 것이다. MUI는 시스템을 대신 운영해 주지 않는다. naming, semantic token, domain-specific component, 콘텐츠 밀도 기준, 제품별 variation 정책은 결국 팀이 정해야 한다. MUI가 해결하는 것은 그 논의를 시작할 수 있는 공통 바닥과 구현 인프라에 가깝다.

운영에서 먼저 보이는 신호

흥미로운 점은 MUI 같은 선택의 성패가 launch day에 바로 드러나지 않는다는 데 있다. 운영에서 더 빨리 보이는 신호는 다른 곳에 있다. 새 화면을 붙일 때 UI 회의 시간이 줄어드는지, 색상이나 spacing 관련 코멘트가 반복되지 않는지, 다크 모드나 밀도 조절 같은 가로축 요구가 나왔을 때 “안 된다”보다 “어디를 손보면 된다”가 먼저 나오는지, QA에서 interaction defect가 스타일 결함보다 적어지는지 같은 것들이다.

팀이 성숙해질수록 속도는 구현 속도보다 변경 속도로 측정된다. MUI가 다시 채택되는 조직은 이 사실을 이미 체감한 경우가 많다. 새 기능 하나를 만드는 시간보다, 그 기능이 제품 전체 톤을 해치지 않게 넣는 시간이 더 비싸졌다는 사실 말이다. 그때 theme는 단순한 스타일 설정 파일이 아니라 변경을 저렴하게 만드는 인터페이스가 된다.

디자인 시스템의 진짜 효용은 “예쁜 화면”이 아니라 “반복되는 결정의 중앙화”에 있다. MUI는 바로 그 중앙화를 상당히 빠르게 시작하게 해 준다. 그래서 디자인 시스템이 늦어질수록, 오히려 더 자주 다시 거론된다. 이미 늦어졌기 때문에, 이제는 취향보다 비용을 봐야 하기 때문이다.

다시 호출되는 이유는 결국 같은 질문으로 수렴한다

결국 팀이 MUI를 다시 들여다보는 이유는 단 하나의 질문으로 모인다. 지금 필요한 것은 독창성의 최대치인가, 일관성의 회복인가. 많은 경우 둘 다 필요하다고 답하고 싶겠지만, 현실에서는 먼저 해결해야 할 쪽이 있다. 제품이 커질수록 대개 우선순위는 후자다. 일관성이 회복돼야 그 위에서 독창성도 안정적으로 자란다.

MUI는 가장 화려한 선택지라서 반복 호출되는 것이 아니다. React 팀이 theme 확장성, 접근성의 최소선, 공통 컴포넌트의 상태 모델, 출시 속도, 유지 비용을 한꺼번에 저울에 올렸을 때 꽤 자주 남는 이름이라서 돌아온다. 그리고 이 귀환은 후퇴가 아니다. 오히려 “우리가 직접 만들어야 할 것”과 “굳이 다시 증명할 필요가 없는 것”을 구분하기 시작했다는 신호에 가깝다.

디자인 시스템은 보통 늦게 온다. 문제는 늦게 왔을 때 무엇으로 시간을 되돌릴 수 있느냐다. 많은 팀이 그 답을 완전한 재창조에서 찾지 못하고, 검증된 뼈대를 자신들의 언어로 재해석하는 쪽에서 찾는다. MUI가 자꾸 다시 호출되는 이유는 그 선택이 의외로 덜 화려하고, 대신 훨씬 더 오래 버티기 때문이다.

댓글

댓글을 읽어오는 중입니다.

같이 읽으면 좋은 글

방금 읽은 주제와 이어지는 글을 골랐습니다.

Frontend 전체 보기

이전 글

GPU 클러스터 대신 Job 하나: Gemma 4 커스터마이징이 서버리스로 넘어가는 순간