제품을 진화시키는 방법

당신의 스타트업을 시작했다면 — 이제 어떻게 훌륭한 제품을 ASAP로 찾을 수 있을까요? Granola에서는 자연 선택의 원칙을 사용하여 제품을 빠르게 발전시켰습니다! 우리는 반복적인 코드를 사용하여 하나의 블롭에 모든 코드를 모으고, 테스트 없이 소프트웨어를 돌연변이에 친화적으로 만들었습니다. 최고의 변형을 선택하기 위해 프로그램을 타겟 사용자에게 수동으로 보냈습니다. 또한 변형이 멸종에 친화적이도록 하기 위해 모든 출시, 랜딩 페이지 및 문서를 피했습니다. 주의하세요: 대기업의 "최고 관행"은 초기 단계의 스타트업에는 적합하지 않습니다!

역사상 최고의 스타트업 이야기

Pikaia

이 친구는 피카이아(Pikaia)입니다. 그는 약 5억 년 전쯤 살았으며, 길이는 약 4cm 정도까지 자랐고 아마도 장어처럼 헤엄쳤을 것입니다. 그 후 얼마 지나지 않아, 대부분의 다른 종들과 함께 사라졌습니다.

그럼에도 불구하고 피카이아는 여전히 살아 있습니다: 그의 후손들은 바로 당신과 저, 이 행성의 지배자들로, 심지어 태양계 너머까지 영향을 미치며, 그들의 이미지가 파이어니어 우주선에 영원히 새겨져 있습니다!

Pioneer plaque

저는 캄브리아기 대폭발이 역사상 최고의 스타트업 이야기라고 믿습니다. 빠른 프로토타이핑과 잊혀진 피벗으로 가득 찬 이야기죠! 우리의 초기 스타트업처럼, 자연 선택도 변화하는 환경에서 새로운, 더 나은 디자인을 찾는 탐색 과정입니다.

Pigeons

일부 사람들은 진화가 느려야 한다고 믿지만, 이는 잘못된 생각입니다. 다윈의 이론은 비둘기 사육사들에게 영향을 받았는데, 그들은 놀랍도록 짧은 시간 내에 새로운 비둘기 디자인을 찾아낼 수 있었습니다. 저는 좋은 스타트업을 이러한 사육사들과 같다고 생각합니다: 돌연변이와 선택을 세련되게 사용하여 놀라운 새로운 제품을 찾는 것이죠.

저의 주장: 스타트업을 설계할 때, 우리는 자연 선택이 작동하는 방식에서 놀랍도록 구체적인 교훈을 얻을 수 있습니다! 첫 번째 예로: 자연이 복사-붙여넣기에 대해 어떤 태도를 취하는지 살펴봅시다.

추상적인 개념을 피하고, 복사-붙여넣기-편집을 사용하세요!

Williston's law

여러분의 팔과 다리는 어떻게 생겨났을까요? 피카이아와의 차이점을 주목해보세요: 피카이아는 많은 반복된 부분을 가지고 있지만, 여러분의 몸은 소수의 특수화된 부분만 가지고 있습니다.

Hox gene evolutionary tree

이것은 진화에서 매우 자주 발생하는 현상으로, 이를 윌리스톤의 법칙이라고 부릅니다. 간단히 말해, 자연은 복사-붙여넣기와 편집을 좋아합니다. 자연은 다리나 이와 같은 다재다능한 신체 부위를 여러 번 복제하고, 각각이 특수화할 기회를 주고, 남는 부분을 제거합니다.

Hox gene evolutionary tree

자연의 복사-붙여넣기에 대한 사랑은 유전적으로도 볼 수 있습니다. 여러분이 아직 배아였을 때, 여러분의 몸 구조는 39개의 서로 다른 "Hox" 유전자에 의해 그려졌습니다. 각 Hox 유전자는 몸의 한 부분에 해당합니다. 그러나 초기 조상들은 단 하나의 Hox 유전자만 가지고 있었습니다! 자연은 이를 여러 번 복사-붙여넣기하고 편집하여 이제 우리는 39개의 서로 다른 기능을 가진 Hox 유전자를 가지게 되었습니다.

컴퓨터 과학 강의에서는 명확하고 고정된 요구사항을 주었고, 우리는 이를 "깨끗한 코드"로 구현해야 했습니다. 하지만 특정하고 고정된 요구사항을 위한 프로그램은 불확실성과 변화를 위해 설계된 프로그램과 매우 다릅니다!

새로운 종류의 "큰 버튼" 컴포넌트를 추가하고 싶다고 가정해 봅시다. 추상적인 "버튼" 개념을 도입하는 대신, 기존 버튼 컴포넌트를 복제하여 자신의 경로를 따라 발전하게 해보세요. 현재 요구사항 아래에서 "버튼" 추상이 맞더라도, 새로운 요구사항을 구현하는 데 방해가 될 수 있습니다! 게다가 반복적인 복사-붙여넣기 코드는 AI가 지원하는 변화에도 친숙합니다.

쪼개지 마세요. 하나의 큰 블롭을 사용하세요!

Peacock

왜 공작새는 그 거대한 꼬리를 포기하지 않을까요? 수컷 공작새는 암컷이 그것을 선택하기 때문에 포기할 수 없습니다. 암컷 공작새 역시 선택을 포기할 수 없습니다. 꼬리가 작은 아들은 선택받지 못할 테니까요!

Peacock sequence diagram

프로토콜은 변화를 방해합니다. 공작새는 큰 꼬리를 "건강"과 동일시하는 잘못된 프로토콜을 가지고 있습니다. 무성생식 공작새라면 꼬리를 포기할 수 있었을 것입니다. 그러나 두 성이 있는 경우, 전 세계적으로 협력하지 않으면 변화할 방법이 없습니다.

자연이 우리에게 주는 교훈은 명확합니다: 분할을 피하라는 것입니다. 특히 분산 시스템을 만드는 분할을 피하세요! 여러 작은 것들이 서로 소통하는 것보다 하나의 큰 것을 바꾸는 것이 더 쉽습니다. 이제 교수님이 여러분을 벌주지 않습니다. 모든 것을 하나의 파일에 담아도 괜찮습니다!

Client, database, and API

심지어 초기 프로토타입도 종종 이렇게 보입니다: 클라이언트, 데이터베이스, 그리고 그 사이의 API. 하지만 이 설계로는 이미 두 개의 분할을 도입한 것입니다!

Initial version of Granola

반면, Granola의 첫 번째 프로토타입은 독립된 데스크톱 앱이었습니다. 필요한 것들과 소통하지만, 기본적으로는 하나의 큰 덩어리였습니다.

Granola using Supabase

결국 서버 측의 것이 필요해졌습니다. 일반적으로 이는 API 계층을 구축하는 것을 의미합니다. 하지만 우리는 Supabase를 사용하여 이를 피했습니다. Supabase를 사용하면 클라이언트가 중앙 데이터베이스와 직접 상호작용할 수 있습니다. 두 개의 인터페이스가 속도를 늦추는 대신, 우리는 하나만 가지고 있었습니다.

자동 업데이트를 피하고 직접 배포하세요!

Cambrian species

다음은 우리 조상 피카이아와 함께 살았던 기이한 생명체들입니다. 생명은 항상 여러 변종을 동시에 탐구합니다! 이것이 거대한 가능성의 공간을 빠르게 탐구할 수 있는 유일한 방법입니다.

그러나 대부분의 소프트웨어 배포는 순차적입니다. v1, v2, v3, 그리고 계속해서 이어집니다. 웹 앱은 사용자가 탐구할 수 있는 단일 "프로덕션" 버전에 제한됩니다. 모바일 앱은 앱 스토어에 게시된 단일 버전에 제한됩니다. 이는 탐구에 좋지 않습니다.

Direct software distribution via .dmg file

대신, Granola는 .dmg 파일을 통해 직접 배포됩니다. 이는 급진적인 코드 변경을 하고, 새로운 빌드를 만들어 단일 사용자에게 보낼 수 있음을 의미합니다. 이는 제품을 진화시키는 데 매우 좋습니다. 왜냐하면 우리는 동시에 여러 버전을 평가하고 있기 때문입니다.

(여러분은 "하지만 우리는 기능 플래그를 가지고 있어요"라고 생각할 수 있습니다. 좋습니다. 하지만 단일 프로덕션 버전이 모든 가능한 소프트웨어 변경의 중첩으로 작동해야 하기 때문에, 급진적인 변화를 기능 플래그로 만들 수는 없습니다.)
초기 단계에서는, 선형적인 자동 업데이트를 피하고 대신 직접 배포를 사용하세요.

소프트웨어 버전을 제거하세요

Opabinia

오파비니아(Opabinia)는 우리 조상과 함께 살았습니다. 그는 다섯 개의 눈과 하나의 중앙 발톱을 가지고 있었습니다. 하지만 오파비니아의 후손은 오늘날 살아 있지 않습니다. 어쩌면 그가 어리석은 디자인이었기 때문일 것입니다. 대부분의 캄브리아기 형태는 진화의 막다른 길이었습니다.

죽음이 없으면 자연 선택은 작동하지 않습니다! 그럼에도 불구하고 많은 기존의 조언은 우리가 나쁜 소프트웨어 버전을 제거하기 어렵게 만듭니다.

References to software versions
(왼쪽부터) 살아있는 그래놀라, 죽은 그래놀라.

"죽은" 소프트웨어 버전이란 더 이상 참조가 없는 버전을 의미합니다. 가비지 컬렉션을 생각해보세요. 따라서 소프트웨어를 죽이려면 불필요한 참조를 피하세요. 피할 수 있는 일반적인 참조를 살펴봅시다.

자동 테스트를 피하고 수동으로 테스트하세요!

Tests

소프트웨어 변경을 했는데 테스트가 깨졌다고요? 기분 나빠하지 마세요: 그것은 여러분의 잘못이 아니라 테스트의 잘못입니다!

테스트는 프로그램이 자유롭게 실행되는 것을 막는 사슬입니다. 테스트는 "나쁜 코드! 변경을 멈춰! 이전 프로그램으로 돌아가!"라고 말합니다.

따라서 테스트를 작성하지 마세요. 변경될 가능성이 적은 것들만 테스트하세요. 나머지는 모두 수동으로 테스트하세요.

(참고: 타입 체킹은 다릅니다. 타입 체킹은 어떤 프로그램에도 적용되는 올바름 속성을 테스트합니다. 좋은 타입 체커는 많은 것을 깨뜨리지 않고 빠르게 움직일 수 있게 해줍니다.)

불필요한 사용자를 피하고 자신을 위해 빌드하세요!

Users

여러분도 이런 경험을 했을 것입니다: 제품에서 무언가를 제거하고 싶지만, 일부 애매한 사용자가 크게 불평하여 결국 포기하게 되는 경우 말이죠.
기존의 조언은 가능한 한 빨리 출시하라고 합니다. 하지만 소프트웨어를 사용하는 사람들은 그것을 유지하고, 따라서 변경을 늦출 수 있습니다.
대신 모든 불필요한 사용자를 피하세요. 소수의 타겟 사용자(그 타겟은 여러분 자신일 수도 있습니다)를 위해 빌드하세요!

랜딩 페이지를 피하고 수동으로 온보딩하세요!

User-facing resources

기존의 조언은 퍼널의 상단 경험에 집중하라고 합니다. 제품을 판매하기 위해 랜딩 페이지를 만들고, 문서를 작성하고, 앱 내에서 매끄러운 온보딩을 구축하라고 합니다.

하지만 이 모든 사용자 대면 리소스는 특정 버전의 제품을 참조합니다! 따라서 해당 버전을 제거하기 어렵게 만듭니다.

Granola에서는 고의로 출시 전까지 오랜 시간을 보냈습니다. 우리는 작은 틈새 시장을 타겟으로 하고, 모든 사람을 수동으로 온보딩했습니다. 이는 혼란을 줄이고, 불필요한 것들을 버리기 쉽게 하며, 결국 랜딩 페이지와 온보딩을 구축할 때 연습이 되었습니다.

출시 전 소프트웨어를 위한 모범 사례는 매우 다릅니다

Midwit meme

기존의 조언은 좋은 코드는 높은 테스트 커버리지를 가진 "깨끗한 코드"이며, 팀은 초기 출시, 지속적 배포, 퍼널의 상단 경험을 우선시해야 한다고 합니다. 그러나 초기 스타트업에서는 제품을 찾는 것이 유일한 초점이며, 이러한 "모범 사례"는 이 탐색을 느리게 할 수 있습니다. 낮은 추상화를 사용하여 복사-붙여넣기하고, 모든 것을 한 곳에 모으고, 테스트를 작성하지 마세요. 앱을 수동으로 배포하고, 사람들을 수동으로 온보딩하세요. 우리가 그렇게 했습니다. 12개월 후, 우리는 이제 제품을 찾았다고 생각하며 접근 방식을 재평가할 때가 되었습니다. 우리 여정에 함께하고 싶다면 연락 주세요!


(출처: Granola blog)