Sign In
실험기록

실패한 프론트 실험, 그리고 우리가 선택한 새로운 개발 전략

J
Joshua
Category
  1. LLM
  2. Tech

실패한 가설: Chainlit UI만으로 MVP는 충분할까?

실험 결과, 이 가설은 실패로 결론 내렸다.
처음엔 Chainlit이 꽤 매력적으로 보였다. 별도 프론트 없이도 대화형 UI가 바로 뜨고, LangChain과의 연동이나 세션 관리, 히스토리 기록도 잘 되어 있었다. 우리는 이를 FastAPI와 docker-compose로 구성해, 서비스 UI와 Chainlit을 따로 분리하고 필요할 때만 연결하는 구조를 시도했다.
하지만 곧 한계에 부딪혔다. Chainlit은 독립적인 프레임워크로 동작하는 것을 전제로 설계되어 있다. 외부 컨테이너나 프론트엔드에서 값을 넘겨주거나, 세션을 유기적으로 연결하는 방식은 구조적으로 어려웠다. 작은 커스터마이징(로고, 말풍선, 색상 변경)은 가능했지만, 브랜드 UI에 맞춰 유연하게 바꾸기에는 제한이 많았다.
결국, "Chainlit만으로 서비스 UI를 커버한다"는 전략은 현실적으로 어렵다는 판단을 내렸다. 빠르게 실험하긴 좋지만, 실제 제품에 통합해 쓰기엔 애매했다.

한때 주목한 대안: Lovable + Supabase

다음으로 주목한 건 Lovable이었다.
Lovable은 ChatGPT 스타일의 프론트를 빠르게 생성해주는 서비스로, Supabase와도 연동이 쉬웠다. 로그인, DB 저장, 프롬프트 관리 같은 기능이 자동으로 세팅되고, 빠른 프로토타이핑에 최적화되어 있었다. 최근 빠르게 MVP를 만들어야 하는 스타트업에서 자주 언급되는 조합이기도 하다.
하지만 이 역시 제한적이었다. 생성된 프론트는 커스터마이징이 어렵고, 백엔드 로직은 자동 생성되지만 재사용 가능한 구조로 짜여 있지 않으며, 결국 직접 수정하거나, 처음부터 다시 짜야 하는 부분이 많았다.
v0.dev도 함께 살펴봤지만, 생성된 프론트의 구조가 복잡했고, 기존 API와 붙이기엔 오히려 리소스가 더 많이 들었다.
디자인은 깔끔했지만, 실제 서비스 구조에 통합하려면 너무 많은 수작업이 필요했다.

그럼에도 살아남은 실용 스택: Supabase

Lovable과 v0.dev는 결국 버릴 수밖에 없었지만, Supabase는 명확하게 효과가 있었다. 일정 사용량까지는 무료이고, 외부 API 키만 연동하면 쉽게 호출할 수 있으며, GUI로 DB를 손쉽게 관리할 수 있다는 점에서 초기 개발에 매우 유리했다. 비슷한 기능을 AWS에서 구성하려면 비용도 훨씬 많이 들고, 세팅도 복잡하다. 초기 실험과 MVP 구조를 구성하는 단계에서 Supabase를 선택하지 않을 이유가 없었다.
물론, 이후에 서비스가 확장되면서 다른 DB로 이전할 가능성은 있다. 하지만 처음부터 DB를 하나의 드라이버 혹은 인터페이스 레이어를 통해 추상화해두면, 추후 전환 시에도 큰 문제가 없다. Supabase를 "초기용 DB"로 두고, 확장을 고려한 구조로 설계해두는 것이 오히려 더 합리적인 접근이었다.

새로운 전략: Claude Code + Cursor로 CSS 개발

결론은 의외로 단순했다. AI 코딩 툴을 적극적으로 활용하자.
Claude Code를 활용해 초벌 CSS 코드를 생성하고, Cursor에서 바꾸고 싶은 일부분만 수정하는 방식이 훨씬 더 효율적이었다. 로직과 UI를 분리한 구조로 설계할 수 있어 유지보수가 쉬웠고, 반복적으로 재사용 가능한 컴포넌트 개발도 가능했다. 무엇보다 직접 통제 가능한 코드 기반이라 디버깅이 훨씬 수월했다.
특히 예상보다 훨씬 인상적이었던 것은 Claude Code의 코드 생성 능력이었다. 처음에는 GPT-4 수준의 자동 완성을 기대했지만, 실제로는 전체 코드 구조를 파악하고, 파일 단위의 흐름을 일관성 있게 유지하며 구현해주는 모습이 눈에 띄었다. 함수와 컴포넌트 간의 연결, context의 흐름, 로직에 필요한 세부 변수 구성까지도 매우 정교하게 계획하고 작성하는 능력은 기대 이상이었다.
TDD(Test-Driven Development) 방식과 결합하면 그 진가가 더욱 빛난다. 테스트 케이스가 명확히 정의되어 있기 때문에, 이후 UI를 수정하더라도 기존 로직이 깨지지 않았는지 빠르게 확인할 수 있다. 이 말은 곧 비개발자도 안정적인 구조 안에서 실험에 참여할 수 있다는 뜻이다. 예를 들어, 디자이너나 기획자가 Cursor의 미리보기 환경에서 버튼 위치를 바꾸거나 색상, 구성 요소를 수정해도, 기능 자체가 깨질 가능성은 낮다. 테스트가 모든 주요 흐름을 보장하고 있기 때문이다.
실제로는 Claude가 만든 초안을 기반으로 내가 전체 구조를 정리하고, 다시 Claude에게 일부를 개선시키는 흐름이 가장 자연스럽고 생산적이었다. 빠르게 만들고, 쉽게 고치고, 안심하고 실험할 수 있는 개발 흐름이 만들어졌다.
Chainlit은 빠른 실험용으로는 여전히 훌륭한 도구다. 하지만 실제 서비스를 운영하고 발전시키기 위해선 결국 내가 직접 다룰 수 있는 코드가 필요하다. Claude Code + Cursor + CSS 조합은 이 두 가지 니즈를 동시에 만족시켜주며, 우리가 원하는 수준의 유연성과 안정성을 갖춘 최적의 개발 환경이 되어주었다.

빠르게 만든다고 끝이 아니었다

이번 실험을 통해 우리는 하나 분명히 알게 됐다. 빠르게 만들 수 있는 구조와, 실제로 운영 가능한 구조는 다르다.
Chainlit은 실험의 출발점으로 좋았고, Supabase는 여전히 든든한 기반이 되어줬고, Claude + Cursor는 우리가 직접 컨트롤할 수 있는 개발 환경의 핵심이 되었다.
다음 실험은 이 구조 위에 실제 사용자를 올려놓는 일이다. 우리가 만든 앱이 진짜 사용되고 있는지, 어디서 끊기고 어디서 반응이 오는지를 직접 확인해보려 한다.
제품이 아니라 사용자 흐름을 실험하는 단계, 그 이야기를 이어서 해보겠다.
Subscribe to 'Monthly Lab'
Subscribe to my site to be the first to receive notifications and emails about the latest updates, including new posts.
Join Slashpage and subscribe to 'Monthly Lab'!
Subscribe
👍