← 목록으로

폰이 리모컨이 되는 마법! 망작에서 명작으로, VKara 카라오케 앱 재탄생기

2026. 6. 1.

폰이 리모컨이 되는 마법! 망작에서 명작으로, VKara 카라오케 앱 재탄생기

안녕하세요, 10년 차 IT 개발자이자 테크 블로거, 레지입니다. 이번 GitHub Finish-Up-A-Thon Challenge에 참여하며 오랫동안 묵혀뒀던 프로젝트를 다시 꺼내 들었는데요. 바로 'VKara'라는 웹 기반 노래방 앱입니다. 한때는 저를 좌절시켰던 이 앱이 어떻게 부활했는지, 그리고 이 과정에서 GitHub Copilot을 어떻게 활용했는지 그 이야기를 들려드리려 합니다.

VKara, 무엇을 만들었나

VKara는 친구나 가족과 함께 집에서 노래를 부를 수 있는 브라우저 기반의 카라오케 룸 앱입니다.

유튜브를 대체하려는 거창한 목표는 아닙니다. 유튜브는 영상 재생에 이미 탁월하고, 우리가 원하는 대부분의 노래방 곡들을 보유하고 있죠. 하지만 여러 사람이 함께 곡을 고르고 재생 목록을 관리해야 하는 '노래방의 밤'을 위해 설계된 서비스는 아닙니다.

VKara는 바로 이 지점의 공백을 채우려 합니다.

거실 TV나 노트북을 메인 재생 화면으로 켜두고, 각자 자신의 스마트폰으로 4자리 룸 코드나 QR 코드를 이용해 같은 룸에 참여합니다. 그러면 누구든 원하는 곡을 검색해서 대기열에 추가하고, 재생/일시정지/건너뛰기 등의 컨트롤을 할 수 있게 되죠.

TV는 그저 영상을 재생하는 역할만 수행합니다.

모두의 스마트폰이 각자의 리모컨이 되는 겁니다.

이게 바로 VKara의 핵심 아이디어입니다.

한 문장으로 설명하기엔 더할 나위 없이 간단합니다. 하지만 이걸 주말 뚝딱 프로젝트로 만들기엔 결코 간단치 않았다는 것을, 저는 아주 쓰디쓴 경험으로 깨달았습니다.

데모 살펴보기

아래 링크에서 직접 VKara를 경험해 볼 수 있습니다.

작은 경고 하나 드리자면, 데모는 제한된 리소스로 운영되고 있습니다. 혹시 느리더라도 잠시 기다려 주세요. 아직 학생 지갑이라 서버 비용이 빠듯합니다. 하하.

기본적인 사용 흐름은 이렇습니다:

  1. TV나 노트북으로 VKara를 엽니다.
  2. 스마트폰으로 코드 또는 QR을 통해 룸에 참여합니다.
  3. 카라오케 영상을 검색합니다.
  4. 공유 대기열에 추가합니다.
  5. 다 같이 재생을 제어합니다.

Old VKara version: desktop, mobile search, and mobile controls

이전 버전: 아이디어는 통했지만, 영상 앱에 노래방 기능을 억지로 끼워 넣은 느낌이 강했습니다.

Current VKara mobile flow

현재 버전: 모바일 흐름은 룸 참여, 검색, 액션 선택, 재생 제어에 집중하도록 재설계되었습니다.

무엇이 달라졌나

이전:

  • 프런트엔드와 백엔드가 별도의 저장소에 분리되어 있었습니다.
  • 모바일 UI는 데스크톱 UI를 단순히 압축한 형태였습니다.
  • WebSocket 계약이 여러 프로젝트에 흩어져 있었습니다.
  • TV 화면에 너무 많은 제어 기능이 있었습니다.

이후:

  • 모든 것을 Bun 워크스페이스 모노레포로 통합했습니다.
  • 공유 API/WebSocket 계약을 packages/shared-types로 분리했습니다.
  • TV는 화면, 폰은 리모컨이라는 두 가지 역할에 맞춰 제품을 재구축했습니다.
  • 모바일 흐름을 룸 참여, 검색, 대기열, 제어 중심으로 단순화했습니다.
  • 룸 상태 관리, 재접속 동작, 재생 동기화, 배포 과정을 개선했습니다.

부활 스토리

VKara는 2025년 초쯤 처음 시작했습니다.

그때의 목표는 아주 개인적이었습니다. 친구들과 집에서 더 나은 방식으로 노래방을 즐기고 싶었거든요. 보통은 TV로 유튜브를 켜고, 노래방 영상을 검색한 다음, 리모컨을 돌려가며 컨트롤하는 식이었죠.

이 방식도 작동은 했습니다. 하지만 뭔가 어색했어요.

한 명이 곡을 검색하고 있으면 다른 한 명이 실수로 바로 재생해 버리거나, 다음 곡이 뭔지 알고 싶어 해도 알 길이 없었습니다. 대기열도 불분명했고요. 캐스팅 기능조차 모두가 같은 Wi-Fi 네트워크에 연결되어 있어야 하는 경우가 많았죠.

그래서 저는 프로토타입을 만들었습니다.

첫 버전은 기술적으로는 '작동'했습니다. 여기서 '작동했다'는 건 다소 위험한 의미였죠. 아이디어를 증명하기엔 충분했지만, 실제 노래방 밤에 자신 있게 내놓을 정도는 아니었습니다.

제품에는 여러 문제가 있었습니다:

  • 데스크톱 화면에 영상 주변으로 너무 많은 컨트롤이 있었습니다.
  • 모바일 UI는 압축된 데스크톱 앱 같은 느낌이었습니다.
  • 검색, 대기열, 컨트롤이 너무 가깝게 배치되어 혼란스러웠습니다.
  • 실시간 상태 관리가 불안정했습니다.
  • 프런트엔드와 백엔드가 별도의 저장소에 있었습니다.
  • 공유 타입과 WebSocket 계약이 한곳에서 깔끔하게 관리되지 않았습니다.

마지막 부분은 제가 예상했던 것보다 훨씬 더 중요했습니다.

VKara는 실시간 앱입니다. 프런트엔드와 백엔드는 룸 상태, 대기열 상태, 비디오 메타데이터, 플레이어 명령, WebSocket 메시지에 대해 정확히 일치해야 합니다. 이런 계약들이 분리된 곳에 있으면, 작은 변경조차도 위험하게 느껴집니다.

결국 저는 이 프로젝트 작업을 멈췄습니다.

아이디어가 나빠서가 아니었습니다.

프로젝트를 변경하기가 너무 어려웠기 때문이죠.

올해 다시 돌아왔을 때, 저는 새로운 기능을 추가하는 것부터 시작하지 않았습니다. 대신 프로젝트를 '안전하게 변경할 수 있도록' 만드는 일부터 시작했습니다.

첫 번째 주요 단계는 이전 프런트엔드 저장소와 백엔드 저장소를 하나의 Bun 워크스페이스 모노레포로 병합하는 것이었습니다:

apps/web                # Next.js 프런트엔드
apps/api                # Elysia + WebSocket 백엔드
packages/shared-types   # 공유 API/WebSocket 계약
packages/shared-utils   # 공유 헬퍼 함수

이는 단순히 폴더를 정리하는 작업 그 이상이었습니다. 프로젝트를 다루는 방식 자체를 바꿨죠.

모노레포 마이그레이션 이후, 웹과 API 변경 사항을 함께 확인할 수 있게 되었습니다. 공유 계약은 packages/shared-types에 모아둘 수 있었죠. 이제 룸 이벤트나 비디오 형태를 변경할 때, 두 개의 저장소를 찾아다니며 모든 것을 기억하고 있는지 걱정할 필요가 없어졌습니다. 제가 실무에서 여러 프로젝트를 진행하며 뼈저리게 느낀 점 중 하나는, 특히 실시간 동기화가 필요한 앱일수록 이런 공유 타입 관리가 얼마나 중요한가 하는 것이었습니다. 초기 개발 단계에서는 간과하기 쉽지만, 결국 유지보수성과 확장성을 해치는 주범이 되곤 하죠.

두 번째 주요 변경 사항은 UX였습니다.

처음에는 VKara를 일반적인 반응형 웹사이트처럼 취급했습니다:

데스크톱 레이아웃. 모바일 레이아웃. 끝.

이건 잘못된 사고방식이었습니다.

TV는 단순히 큰 스마트폰이 아닙니다. 그리고 스마트폰도 단지 작은 TV가 아니고요.

이들은 각기 다른 역할을 수행합니다.

그래서 VKara는 이제 두 가지 역할로 생각합니다:

  • TV / 노트북: 재생 화면
  • 스마트폰: 리모컨

이 한 가지 결정이 제품을 훨씬 명확하게 만들었습니다.

TV는 깔끔함을 유지해야 합니다. 영상, 룸 코드 또는 QR, 그리고 기본적인 룸 컨트롤만 보여줘야 하죠.

스마트폰은 룸 참여, 검색, 대기열 추가, 재생 액션을 처리해야 합니다.

실제 사용 흐름은 이렇게 바뀌었습니다:

룸에 참여 → 노래 검색 → 대기열에 추가 → 계속 노래 부르기.

이번 부활 작업의 많은 부분은 전혀 화려하지 않았습니다. 사용자들은 실패했을 때 비로소 알아차리는 그런 종류의 작업이었죠. WebSocket 룸 상태 관리, 재접속 동작, 재생 동기화, 대기열 업데이트, 룸 정리, 유튜브 메타데이터 형태 처리, Docker 빌드, GitHub Actions, 그리고 모노레포 마이그레이션 이후의 Vercel 배포까지.

노래방 밤에 누가 아키텍처가 얼마나 똑똑한지 신경 쓰겠습니까?

그들은 그저 버튼을 탭했을 때, 룸이 반응하는지에만 관심이 있습니다.

GitHub Copilot과의 경험

첫 번째 버전과 이번 부활 버전 사이의 가장 큰 차이는 비단 GitHub Copilot 자체만이 아니었습니다.

제가 Copilot을 '어떻게' 사용했느냐에 달려 있었죠.

첫 버전에서는 AI 지원 워크플로우가 너무 순진했습니다. 코드를 요청하고, 버그는 수동으로 패치하며 빠르게 움직였죠. 이는 프로토타입을 만드는 데는 도움이 되었지만, 제가 신뢰할 만한 코드를 남기지는 못했습니다.

이번에는 GitHub Copilot을 마치 '마무리 파트너'처럼 활용했습니다.

코드를 변경하기 전에, 'Ask Mode'를 사용해 프로젝트를 다시 이해하는 시간을 가졌습니다. VKara는 오랫동안 방치되어 있었고, 솔직히 제가 내렸던 모든 결정을 기억하지 못했습니다.

가장 먼저 던진 질문 중 하나는 기본적으로 이랬습니다:

"이 프런트엔드에서 SWR이나 React Query를 사용하지 않는 이유는 무엇인가? 대신 실제로 무엇을 사용하고 있는가?"

답변은 이 앱이 클라이언트 상태를 위해 Zustand 스토어를, 서버 데이터는 직접 fetch 호출을, 그리고 룸/플레이어 상태를 위해 WebSocket 기반의 실시간 동기화를 사용하고 있음을 상기시켜주었습니다.

이 질문 덕분에 엉뚱한 레이어를 건드리는 실수를 피할 수 있었습니다.

Using Ask Mode in VS Code to understand the old frontend data flow

Ask Mode는 코드를 수정하기 전에 기존 데이터 흐름을 이해하는 데 큰 도움이 되었습니다.

더 큰 작업을 할 때는 실행 전에 'Plan Mode'를 사용했습니다.

단순히 이렇게 말하는 대신:

"이 두 프로젝트를 더 깔끔하게 만들어줘."

실제 마이그레이션 계획을 요청했습니다:

"vkaravkara-api를 하나의 모노레포로 병합하고, 히스토리를 유지하며, Bun 워크스페이스를 사용하고, 공유 타입을 찾아 공유 패키지로 이동시켜줘."

Using Plan Mode in VS Code for the monorepo migration

Plan Mode는 막연한 리팩토링 작업을 훨씬 안전한 마이그레이션 경로로 바꿔주었습니다.

이것이 저의 반복적인 작업 루프가 되었습니다:

생각 → 질문 → 계획 → 실행 → 검증 → 반복

버그가 발생하면 정확한 TypeScript 오류나 Docker 로그를 붙여 넣었습니다.

UI 작업의 경우, 스크린샷을 사용하고 무엇이 문제인지 설명했습니다.

아키텍처 질문에 대해서는 코드를 건드리기 전에 대안을 물어봤죠.

이것이 바로 진정한 업그레이드였습니다. 솔직히 저도 처음에는 코파일럿을 단순히 코드 생성 도구로만 활용했습니다. 하지만 이번 프로젝트를 통해 'AI를 어떻게 활용하느냐'가 결과물의 질을 완전히 바꿀 수 있다는 것을 확실히 깨달았습니다. 마치 주니어 개발자와 시니어 개발자가 다른 방식으로 협업하는 것과 비슷하다고 할까요? 단순한 코딩 요청보다는 아키텍처나 문제 해결 과정을 함께 고민하는 파트너로서 코파일럿을 활용하니 효율이 비약적으로 상승하더군요.

첫 버전에서는 주로 AI에게 코드를 생성해 달라고 요청했습니다.

이번 부활 버전에서는 GitHub Copilot에게 조사하고, 비교하고, 계획하고, 리팩토링하고, 검증하고, 트레이드오프를 설명해 달라고 요청했습니다.

최종 결과물도 여전히 완벽하지는 않습니다.

하지만 이제 저는 '진정으로 중요한 것'이 무엇인지 알게 되었습니다.

'AI 가사'나 로드맵에서 멋지게 들리는 거대한 기능 따위가 아닙니다.

진정한 문제들은 더 작고, 더 인간적인 것들입니다: 누가 건너뛸 권한이 있는지, 누가 이 노래를 추가했는지, 누구 차례인지, 한 사람이 전체 대기열을 채우는 것을 어떻게 막을지, 누군가 폰을 닫았을 때 어떻게 빠르게 재접속할지, 다음 노래방 밤을 위해 같은 대기열을 어떻게 다시 불러올지 같은 것들이죠.

유튜브는 이미 우리에게 영상을 제공합니다.

VKara는 룸이 '평온하게' 느껴지도록 만들어야 합니다.

이제 VKara는 더 이상 제가 혼자만 간직하는 프로토타입이 아닙니다.

이젠 TV를 켜고, 친구에게 폰을 건네주며 이렇게 말할 수 있는 무언가가 되었습니다:

"다음 곡 골라봐."

그리고 솔직히, 이것만으로도 이미 큰 승리라고 느껴집니다.


원문: https://dev.to/lehuygiang28/i-rebuilt-my-karaoke-app-so-everyones-phone-could-be-a-remote-4k8b 수집일: 2026-06-01 02:13:28