모노레포

Monorepo

개념

여러 프로젝트의 코드를 저장소 하나에 모아 함께 이력을 관리하는 방식으로, 공통 코드를 한 번에 고칠 때 씁니다.

등장 배경

제품이 하나여도 코드는 금세 여러 벌이 됩니다. 웹 화면, 모바일 앱, 서버, 그리고 셋이 함께 쓰는 버튼과 색과 아이콘 묶음이 따로 있습니다. 예전에는 이것들을 저장소마다 하나씩 나눠 담았습니다. 저장소는 코드와 그 코드의 모든 변경 이력이 함께 담긴 공간입니다.

나눠 담고 나니 공통 코드를 고칠 때마다 같은 절차가 반복됐습니다. 버튼의 여백을 2픽셀 줄이는 일에 다음이 따라붙었습니다. 공통 저장소에서 고치고, 버전 번호를 0.4.2 에서 0.4.3 으로 올려 내보내고, 웹과 앱과 서버 저장소를 각각 열어 그 번호를 올려 잡은 뒤 세 번 리뷰를 받는 것입니다. 한 줄 수정에 요청이 네 개 생기고, 넷을 다 합치기까지 이틀이 걸렸습니다.

더 성가신 것은 중간 상태였습니다. 웹은 0.4.3 을 쓰는데 앱은 아직 0.4.2 를 쓰는 기간이 며칠씩 생겼고, 그동안 같은 버튼이 두 화면에서 다르게 보였습니다. 누가 아직 안 올렸는지 확인하려면 저장소 네 개를 일일이 열어 봐야 했습니다.

모노레포는 이 절차를 없애려고 나온 선택입니다. 나뉘어 있던 것을 한 저장소에 모으면 버튼 수정과 그것을 쓰는 세 곳의 수정이 한 번의 변경으로 묶입니다. 버전 번호를 주고받는 일 자체가 사라집니다.

작동 방식

한 저장소 안에 프로젝트를 폴더로 나눠 둡니다. 보통 실행되는 것과 공유되는 것을 갈라 놓습니다.

  1. 실행되는 것을 모아 둔 폴더에 웹, 앱, 서버가 각각 들어갑니다. 저마다 따로 빌드되고 따로 배포됩니다.
  2. 공유되는 것을 모아 둔 폴더에 디자인 부품, 공통 함수, API 요청과 응답의 형태를 적어 둔 파일이 들어갑니다. API 는 프로그램끼리 주고받기로 약속한 창구를 말합니다.
  3. 실행되는 쪽이 공유되는 쪽을 가져다 쓸 때 배포된 버전 번호가 아니라 같은 저장소 안의 폴더를 직접 가리킵니다. 그래서 공통 코드를 고치면 세 곳이 그 즉시 고쳐진 코드를 씁니다.

여기까지만 하면 저장소가 커질수록 느려집니다. 변경 한 줄에 전체를 다시 빌드하고 전체 검사를 돌리면 5분이던 것이 40분이 됩니다. 그래서 모노레포는 도구를 한 겹 깔고 씁니다. 도구가 하는 일은 두 가지입니다.

첫째는 무엇이 무엇에 기대는지 지도를 그리는 것입니다. 디자인 부품을 웹과 앱은 쓰고 서버는 안 쓴다는 사실을 알고 있으면, 부품을 고쳤을 때 웹과 앱만 다시 검사하고 서버는 건너뜁니다.

둘째는 결과를 기억해 두는 것입니다. 같은 코드로 이미 한 번 빌드했으면 그 결과를 저장해 두었다가 그대로 꺼내 씁니다. 동료가 이미 돌린 검사를 내 컴퓨터에서 다시 돌리지 않아도 되고, 저장소에 프로젝트가 스무 개여도 한 번에 걸리는 시간은 실제로 바뀐 둘셋에만 듭니다.

쓰이는 곳

고르는 기준은 저장소 개수가 아니라 변경이 경계를 얼마나 자주 넘느냐입니다. 넘는 일이 잦으면 모아 두는 쪽이 싸고, 드물면 나눠 두는 쪽이 싸집니다.

모아 두는 쪽이 유리한 자리는 셋입니다.

  1. 공통 부품을 여러 팀이 같이 씁니다. 디자인 시스템의 버튼과 입력창을 웹과 앱이 함께 쓰는 상황이 대표적입니다.
  2. 서버와 화면이 같은 약속을 공유합니다. 응답 형태가 바뀌면 화면 코드도 같이 바뀌어야 하는데, 한 저장소 안에 있으면 둘을 같은 변경에 담아 검사까지 한 번에 받습니다. 나뉘어 있으면 서버만 먼저 나가서 화면이 깨지는 일이 생깁니다.
  3. 트렁크 기반 개발처럼 본류에 자주 합치는 방식을 씁니다. 자주 합치는 팀일수록 저장소를 넘나드는 대기 시간이 크게 느껴집니다.

반대로 나눠 두는 편이 나은 자리도 있습니다. 릴리스 주기가 아주 다르면 한곳에 둘 이유가 줄어듭니다. 분기에 한 번 나가는 것과 하루에 다섯 번 나가는 것을 같은 이력에 섞으면 검사 대상만 늘어납니다. 바깥 협력사가 특정 코드만 봐야 하는 경우도 그렇습니다. 저장소 하나에서 폴더별로 권한을 나누는 일은 저장소를 나누는 것보다 손이 많이 갑니다.

실무 용례

"이건 모노레포로 가죠. 타입을 서버랑 화면이 같이 써야 해요."

같은 약속을 공유하는 코드를 한 변경에 담자는 제안입니다.

"모노레포인데 매번 전체가 빌드돼요. 캐시 설정이 안 돼 있는 것 같은데요."

저장소만 합치고 도구를 안 깔아 느려졌다는 진단입니다.

"모노레포라고 해서 한 덩어리로 배포하는 건 아닙니다."

코드를 모아 둔 것과 배포 단위를 하나로 두는 것은 다른 이야기라는 설명입니다.

페이지덱은 지난해 저장소 네 개를 하나로 합쳤습니다. 계기는 디자인 부품이었습니다. 민서가 입력창의 오류 문구 위치를 바꿨는데 웹에는 반영되고 앱에는 3주 뒤에야 반영됐고, 그사이 같은 화면을 찍은 스크린숏 두 장이 회의에서 나란히 올라왔습니다.

합친 뒤 태오가 먼저 한 일은 검사 시간을 재는 것이었습니다. 합치자마자 한 번의 변경에 걸리는 시간이 6분에서 31분으로 늘었기 때문입니다. 의존 지도와 캐시를 붙이고 나서 9분으로 내려갔습니다. 저장소를 합치는 결정과 도구를 까는 일은 사실상 한 묶음입니다.

흔한 오해

모놀리스와 같은 말로 읽는 경우가 가장 많습니다. 둘 다 하나로 모은다는 뜻의 앞말이 붙어 있으니 헷갈릴 만합니다. 하지만 모으는 대상이 다릅니다. 모노레포는 코드를 어디에 두느냐이고 모놀리스는 서버에 몇 덩어리로 올리느냐입니다. 저장소 하나에 서비스 스무 개를 두고 각각 따로 올릴 수 있고, 저장소 넷에 나눠 두고도 한 덩어리로 올릴 수 있습니다. 둘을 같은 말로 묶으면 "모노레포로 합치면 나중에 쪼개기 어렵다" 같은 반대가 나오는데, 실제로는 배포 단위를 그대로 둔 채 저장소만 합치는 일입니다.

저장소만 합치면 끝이라고 여기는 것도 흔합니다. 폴더를 옮기는 일이라 하루면 될 것처럼 보입니다. 그런데 합친 직후에는 대개 더 느려집니다. 검사 도구가 무엇이 바뀌었는지 모르니 매번 전체를 돌리고, 프로젝트가 늘어난 만큼 그 시간이 곱해집니다. 그 상태로 몇 주를 버티면 팀은 검사를 건너뛰기 시작하고, 합치기 전보다 충돌이 더 자주 나면서 저장소를 다시 나누자는 이야기가 나옵니다. 충돌은 두 사람이 같은 곳을 다르게 고쳐 자동으로 합칠 수 없는 상태를 말합니다.

자주 헷갈리는 용어

용어무엇을 하나로 두는가모노레포와의 차이
모놀리스서버에 올리는 배포 단위코드의 보관 위치가 아니라 실행되는 덩어리의 수를 가리킵니다. 둘은 서로를 강제하지 않고 네 조합이 모두 가능합니다

같이 보면 좋은 페이지

연관 용어

마지막 업데이트 2026-09-16