Ray Book
에세이

오버라이드는 왜 생기나

컴포넌트를 덮어쓰는 건 규칙 위반이 아니라 쓰는 사람이 코드로 남긴 요구사항이다.

essaydesign-systemfrontendopinion

"우리도 디자인시스템 있는데, 아무도 안 써요"

이 말을 참 많이 듣는다. 그런데 막상 코드를 열어보면 안 쓰는 경우는 드물더라. 쓴다. 대신 덮어쓴다.

Button 가져다가 className으로 패딩을 덮는다. Modal은 한 번 감싸서 팀 폴더에 따로 빼둔다. 그것도 번거로우면 이름만 살짝 바꿔서 비슷한 컴포넌트를 새로 만든다.

만든 사람 입장에서는 서운하다. 통일해보자고 만들어둔 걸 다들 자기 편한 대로 쓰고 있으니까. 나도 그 자리에 있어봐서 그 마음을 안다.

그래서 보통 막는다

순서도 대체로 비슷하다. props를 잠그고 className을 안 받게 한다. 린트 규칙을 걸어서 따로 만든 컴포넌트를 쓰면 경고가 뜨게 한다. 리뷰에서는 "그거 시스템에 있어요" 하고 알려준다.

그 마음도 이해가 간다. 하나 봐주면 둘이 되고 둘이 되면 셋이 된다. 그쯤 가면 통일할 이유가 흐려진다.

그런데 여기에는 전제가 하나 깔려 있다. 시스템이 맞고 덮어쓴 쪽이 틀렸다는 전제다.

덮어쓴 코드는 요구사항이다

쓰는 사람이 이슈를 안 올리는 게 게을러서일까. 아니다. 당장 오늘 화면을 내야 하니까, 발등에 불이 떨어져서다.

마감이 이틀 남았는데 "Select에 이런 옵션 하나만 추가해주세요" 하고 적어 올리고, 답변을 기다리고, 다음 배포까지 참으라는 건 무리다. 그래서 그냥 덮어쓰고 넘어간다.

그렇게 남은 코드가 곧 요구사항이다. "이 컴포넌트에 이게 없어서 제가 직접 넣었습니다." 이슈로 안 올라왔을 뿐이지 내용은 똑같고 이미 코드 안에 다 들어 있다.

오버라이드는 두 종류다

같은 오버라이드처럼 보여도 사연은 다르다.

하나는 있는 줄 몰라서 새로 만든 경우다. 시스템에 거의 똑같은 컴포넌트가 있는데 팀 폴더에도 하나 더 있다. 기능도 겹치고 생긴 것도 비슷하다. 설계가 잘못돼서 이렇게 되는 게 아니다. 있는 줄 몰랐거나 찾기가 번거로웠던 것뿐이다.

문서를 안 써서 생기는 일도 아니다. 컴포넌트가 백 개쯤 되는 시스템에 문서가 없을 리 없다. 문서가 많은 것과 필요할 때 찾아지는 건 다른 문제다. 나도 스토리북이 있는 건 아는데 도통 뭐라고 검색해야 할지 감이 안 오던 적이 있다.

다른 하나는 알고 썼는데 기능이 모자라서 덮어쓴 경우다. 시스템 컴포넌트를 분명히 import해두고 그 위에 스타일을 덮었거나, 한 번 감싸서 동작을 바꿨다. 못 찾은 게 아니다. 찾았고, 썼고, 부족했다.

겉으로는 둘 다 똑같이 "디자인시스템이 안 지켜진다"로 보인다. 그런데 손봐야 할 데가 완전히 다르다. 앞쪽은 검색이 잘 되게 하거나 문서를 정리하면 줄어든다. 요즘은 여기에 AI를 붙이기도 한다. 뒤쪽은 그렇게 해도 안 줄어든다. 잘 찾아준다고 없던 기능이 생기지는 않으니까.

이 둘을 구분하지 않으면 문서만 계속 늘리면서 왜 그대로인지 모르게 된다. 밑 빠진 독에 물 붓는 셈이다.

감으로 하는 얘기는 아니다. zeroheight가 2026년에 디자인시스템 실무자 147명에게 물어본 결과가 있다.

디자인시스템 채택이 잘 안 되는 이유. 회사 차원의 강제 부재 73%, 약한 거버넌스 55%, 컴포넌트 완성도 45%, 소통과 커뮤니티 부족 36%, 문서 완성도 27%, 자동화 부족 24%
채택이 안 되는 이유를 물었을 때, 컴포넌트가 모자란다는 응답(45%)이 문서가 부실하다는 응답(27%)보다 위에 있다. zeroheight, Design Systems Report 2026

컴포넌트가 모자란다는 응답이 45%, 문서가 부실하다는 응답이 27%다. 반대로 채택이 잘 되는 이유를 물었을 때는 컴포넌트 완성도가 79%로 1위였다. 잘 굴러가는 시스템은 문서가 많은 게 아니라 필요한 게 다 있었다.

솔직히 내 주장에 불리한 숫자도 있다. 이 대목에서는 괜히 뜨끔했다. 채택이 안 되는 이유 1위가 회사 차원의 강제가 없다는 것으로 73%다. 나는 막지 말자고 하는데 현장에서는 더 세게 밀어붙여야 한다고 답한 셈이다.

그래도 두 목록을 겹쳐 놓고 보면 얘기가 달라진다. 강제는 잘 되는 이유에서 3위(55%)로 내려가고, 1위 자리는 컴포넌트 완성도(79%)가 가져간다. 보고서도 이 어긋남을 짚는다. 거버넌스가 약해서 안 된다고들 하는데, 정작 채택이 잘 되는 팀 넷 중 셋은 거버넌스를 언급조차 하지 않았다.

안 될 때는 안 시켜서라고 답하고, 잘 될 때는 다 있어서라고 답한다.

막으면 팀 폴더에 새로 만든다

props를 잠갔다고 해보자. 그렇다고 회의를 잡지는 않는다. 자기 폴더에 컴포넌트 하나 만들고 넘어간다. 급한 건 화면이지 시스템이 아니니까.

문제는 그렇게 해도 숫자가 안 떨어진다는 것이다. 원래 쓰던 컴포넌트는 계속 쓰니까 import 개수는 그대로거나 오히려 늘어난다. 새로 만든 것만 시스템 바깥에 생긴다. 채택률은 멀쩡해 보이는데 시스템에 새 컴포넌트는 더 안 들어온다.

게다가 오버라이드는 코드에서 검색으로 찾을 수 있다. className=이 붙은 곳을 세면 된다. 팀 폴더에 새로 만든 컴포넌트는 그렇게 못 찾는다. 이름도 다르고 위치도 제각각이다. 막는다는 건 결국 눈에 보이던 걸 안 보이는 데로 밀어넣는 일이더라.

같은 조사에 이런 것도 있다. 시스템을 신뢰하냐고 물었을 때 높다는 응답이 42%, 보통이 49%였고 낮다는 8%뿐이었다. 그런데 전면 채택은 7%다.

디자인시스템 신뢰도 조사 결과. 높은 신뢰 42%, 보통 49%, 낮은 신뢰 8%
신뢰는 멀쩡하다. 보고서는 사람들이 시스템을 신뢰하기는 하는데 그냥 안 쓴다고 정리한다. zeroheight, Design Systems Report 2026

못 믿어서 안 쓰는 거라면 설득하면 된다. 믿는데도 안 쓰는 거라면 설득으로 안 풀린다. 그러면 남는 게 아까 그 두 번째다. 믿고 썼는데 기능이 모자랐던 경우.

막기 전에 세어보자

거창한 걸 하자는 얘기가 아니다.

  • className이랑 style을 막는 대신 뭘 덮어쓰는지 세어보자. 같은 컴포넌트에 같은 오버라이드가 반복되면 그게 다음 버전에 넣을 props다.
  • 팀 폴더 컴포넌트 중에 시스템 것과 기능이 겹치는 게 있는지 가끔 훑어보자. 몰라서 만든 건지 부족해서 만든 건지는 코드만 봐도 대충 갈린다.
  • 리뷰에서 시스템 거 쓰라고 하기 전에 왜 안 썼는지 한 번만 물어보자. "그런 게 있었어요?"면 앞쪽, "그건 이게 안 돼서요"면 뒤쪽이다. 물어보면 금방 갈린다.

손으로 하기 버거우면 Omlet 같은 도구를 붙여도 된다. 코드베이스를 훑어서 시스템 컴포넌트와 커스텀 컴포넌트 사용을 비교해준다.

오버라이드가 하나도 없으면 더 나쁘다

디자인시스템은 한 번 만들어놓고 끝나는 규칙집이 아니다. 쓰는 사람이 부족한 걸 말하고 만든 사람이 채워 넣으면서 계속 바뀐다. 오버라이드는 그 과정에서 당연히 나온다.

그래서 오버라이드가 하나도 없다면 잘 만들어서가 아니다. 아무도 새 화면에 안 쓰고 있거나, 말해봤자 안 바뀐다고 다들 접은 거다. 둘 다 좋지 않다.

참고 자료