
출처: https://dev.to/wasp/a-structured-workflow-for-vibe-coding-full-stack-apps-352l
최근 "바이브 코딩"이 핫하게 떠오르고 있습니다. 아마 여러분은 AI 인플루언서들이 몇 가지 도구와 프롬프트만으로 15분 만에 SaaS 앱을 만들 수 있다고 이야기하는 모습을 종종 보셨을겁니다.
하지만, 짐작하셨던 것처럼, 이러한 예제 워크플로우는 꽤 허술합니다.
사실, 랜딩 페이지를 복사하거나 기본적인 CRUD 앱을 만드는 건 가능하지만, 복잡한 SaaS 앱이나 내부 툴을 만드는 데에는 한계가 분명합니다.
그렇다고 해서, 개발 워크플로우를 실제로 향상시킬 수 있는 워크플로우가 없다는 뜻은 아닙니다. 다양한 AI 도구를 다뤄보셨다면, 그 도구들이 정말 효과적일 수 있다는 것을 알고 계실 겁니다.
그래서 저는 몇 주간 효과적인 기술과 워크플로우 팁을 연구한 후, 이를 실제로 테스트하면서 기능이 완전한 풀스택 앱을 만들어 보았습니다.
이 글에서는 제가 사용한 도구인 Cursor와 Google의 Gemini 2.5 Pro, 그리고 견고한 UI 템플릿을 바탕으로 효과적인 워크플로우와 제 경험을 공유하려 합니다.
이 워크플로우는 제 개인적인 금융 관리 앱을 개발하면서 점차 개선한 과정을 통해 완성되었습니다. 처음엔 조금씩 개선하면서 앱을 만들었고, 최적화된 템플릿과 워크플로우를 찾은 후에는 앱을 다시 한 번 재구성했습니다. 그 과정은 3시간 분량의 유튜브 영상으로 기록되어 있습니다.

이 글은 이 워크플로우를 구현하는 데 있어 핵심적인 접근법을 요약한 내용입니다.
현대의 풀스택 웹 앱은 많은 부분들이 얽혀 있습니다. LLM을 사용해서 모든 것을 하나로 이어 붙이려고 해도 잘되지 않습니다.
AI 도구를 효과적으로 사용하려면 기본적인 구조나 틀을 잘 마련해 두고, 그 기반 위에서 AI가 잘 작동하도록 우리가 제공할 수 있는 도구나 리소스를 제공하는 것이 중요합니다.
실무적인 측면에서 살펴보자면, 다음과 같은 것들을 사용한다는 의미입니다.
컴포넌트 라이브러리와 템플릿은 LLM에게 잘 정의된 틀이나 규칙을 제공할 수 있는 유용한 방법입니다. 또한, 스타일링과 관련된 고민을 줄여주고 앱이 커져도 일관된 스타일을 유지하는 데 도움을 줍니다.
기본 기능이 내장된 풀스택 프레임워크, 예를 들어 자바스크립트용 프레임워크인 Wasp (혹은 React, Node.js, Prisma)나 PHP용 프레임워크 Laravel을 사용하면 여러 가지 기술 스택을 연결하는 복잡함을 없앨 수 있습니다. 이런 프레임워크들은 개발 방향이 정해져 있기 때문에 잘 작동하는 도구들을 조합해 놓았고, 따라서 많은 작업이 자동으로 처리됩니다. 결국, AI는 앱의 비즈니스 로직에만 집중할 수 있습니다.
예를 들어 Wasp의 메인 설정 파일을 보면(아래 코드 참조), 개발자나 LLM이 해야 할 일은 백엔드 작업을 정의하는 것뿐이고 나머지 서버 설정과 구성은 프레임워크가 자동으로 처리합니다. 또한 이 설정 파일은 앱의 구조와 정의를 명확하게 알려주는 "기준점"이 되어, LLM이 새로운 기능을 추가할 때 참고할 수 있게 해 줍니다.
app vibeCodeWasp {
wasp: { version: "^0.16.3" },
title: "Vibe Code Workflow",
auth: {
userEntity: User,
methods: {
email: {},
google: {},
github: {},
},
},
client: {
rootComponent: import Main from "@src/main",
setupFn: import QuerySetup from "@src/config/querySetup",
},
}
route LoginRoute { path: "/login", to: Login }
page Login {
component: import { Login } from "@src/features/auth/login"
}
route EnvelopesRoute { path: "/envelopes", to: EnvelopesPage }
page EnvelopesPage {
authRequired: true,
component: import { EnvelopesPage } from "@src/features/envelopes/EnvelopesPage.tsx"
}
query getEnvelopes {
fn: import { getEnvelopes } from "@src/features/envelopes/operations.ts",
entities: [Envelope, BudgetProfile, UserBudgetProfile] // Need BudgetProfile to check ownership
}
action createEnvelope {
fn: import { createEnvelope } from "@src/features/envelopes/operations.ts",
entities: [Envelope, BudgetProfile, UserBudgetProfile] // Need BudgetProfile to link
}
작업할 기반이 마련된 후에는 편집기와 LLM이 따를 수 있는 종합적인 규칙을 만들어야 합니다.
단단한 규칙을 만들기 위해서는 다음과 같이 해야 합니다.
다양한 IDE와 코딩 도구들이 규칙을 정의할 때 사용하는 네이밍 룰은 제각각이지만, 대부분 비슷한 방식으로 작동합니다(저는 이 프로젝트에서 Cursor를 사용했으므로, 여기서는 Cursor의 네이밍 룰을 참조하겠습니다).
Cursor는 더 이상 .cursorrules 설정 파일을 사용하지 않고, .cursor/rules/ 디렉토리에 여러 파일로 규칙을 나누어 사용합니다. 이 규칙 세트에는 자신의 코딩 스타일에 맞는 일반적인 규칙과 프로젝트에 특화된 규칙(예: 관례, 작업, 인증)을 정의할 수 있습니다.
핵심은 LLM에게 명확하고 구조화된 컨텍스트를 제공해서, LLM이 더 넓은 지식에 의존하지 않고 정확한 맥락에서 작업할 수 있게 한다는 것입니다.

구체적으로 말하자면, LLM에게 현재 작업할 프로젝트와 사용할 템플릿에 대해 설명하고, 어떤 규칙(관례)을 따라야 하는지, 그리고 자주 발생하는 문제들을 어떻게 처리해야 하는지 정의하는 것입니다(예: 위의 예시는 튜토리얼 비디오에 첨부된 레포지토리에서 가져왔습니다).
또한, 규칙 파일에 일반적인 전략을 추가해서 채팅 창에서 필요할 때마다 수동으로 참조할 수 있게 만들 수 있습니다. 예를 들어, 저는 LLM에게 "세 가지 다른 전략/접근 방식을 생각하고, 가장 좋은 것을 선택한 후 왜 그것을 선택했는지 설명해 달라"라고 자주 요청하는데, 이를 위해 7-possible-solutions-thinking.mdc라는 규칙을 만들었습니다. 이 규칙을 사용하고 싶을 때마다 그냥 전달하면 되기 때문에, 같은 말을 반복해서 타이핑할 필요가 없습니다.
이 외에도, 저는 규칙 세트를 필요에 따라 계속 수정하고 개선하고 있습니다. 앱을 개발하면서 규칙 세트를 시작으로 작업을 시작했고, 그 후 LLM이 원하는 결과를 도출할 수 있도록 그 규칙들을 계속해서 수정해 나갔습니다. LLM이 자주 발생시키는 오류를 처리하기 위한 규칙을 추가하거나, 프로젝트에 특화된 문제를 해결하기 위한 규칙을 새롭게 추가했습니다.
이 규칙들을 수정하면서, 저는 LLM을 피드백의 원천으로 활용하고, 현재 워크플로우를 비판적으로 검토해서 개선할 방법을 찾도록 요청했습니다.
규칙 파일뿐만 아니라 계획서나 README 파일 등과 같은 다른 문서들도 LLM에게 전달해서 개선할 수 있는 부분을 찾아보도록 하고, 이전 대화 내용을 참고해 피드백을 받을 수 있도록 했습니다.
대부분은 아래와 같은 요청이었습니다.
이 문서의 내용을 폭넓고 명확하게 검토해 보고, 필요하다면 개선할 수 있는 방법을 몇 가지 생각해 봐. 이 문서는 AI 보조 코딩 워크플로우에서 사용될 것이라는 점을 명심해.
이 단계에서 가장 중요한 것은 제품 요구 사항 문서(PRD)를 생성하고, 이를 바탕으로 실행 가능한 단계별 계획을 수립할 때 사용할 초기 프롬프트입니다.
PRD는 기본적으로 앱이 어떻게 보여야 하고 어떻게 작동해야 하는지를 설명한 상세 가이드라인이며, 구현 방식에 대한 지침도 일부 포함되어 있습니다.
PRD를 생성한 후에는, LLM에게 이를 바탕으로 단계별 실행 계획을 생성하도록 요청합니다. 이때는 LLM 기반 개발에 적합한 방식으로 변형된 수직 분할 방식(vertical slice method)을 사용합니다.
수직 분할 방식이 중요한 이유는, LLM에게 데이터베이스(DB)부터 사용자 인터페이스(UI)까지 전체 스택을 아우르는 "조각" 단위로 앱을 개발하도록 지시하기 때문입니다. 이 방식에서는 초기 단계에서 전체 스택 기능의 아주 간단한 버전을 만들고, 이후 단계에서 점차 복잡도를 추가하는 식으로 진행됩니다.
이 작업 흐름의 핵심은, 처음에는 단순하고 튼튼한 기본 구조를 만들고, 이후에는 복잡한 기능을 작게 나눠서 단계적으로 추가해 나간다는 것입니다.
각 문서가 처음 생성된 후에는, 종종 LLM에게 자기 작업을 스스로 검토하게 하고, 프로젝트 구조와 LLM 보조 개발이라는 점을 고려하여 개선할 수 있는 부분이 있는지 살펴보게 합니다. 때로는 흥미로운 개선점을 제안하기도 하고, 불필요한 중복을 제거해 주기도 합니다.
아래는 단계별 계획을 생성할 때 사용할 수 있는 예시 프롬프트입니다 (모든 예시 프롬프트는 동영상과 함께 제공되는 저장소에서 확인할 수 있습니다).
이 PRD를 바탕으로, LLM 기반 코딩에 적합한 방식으로 수정된 수직 분할 방식을 사용하여 실행 가능한 단계별 계획을 작성하세요. 계획을 세우기 전에 이 프로젝트와 구현 방식에 적합한 여러 계획 스타일을 고려한 후, 그중 가장 적합한 스타일을 선택하고 그 이유를 설명하세요. 이 계획은 이후 지속적으로 참조하며 개발을 진행할 것이므로, 구조가 명확하고 간결하며 실행 가능해야 하며, 동시에 LLM이 이해할 수 있을 정도로 충분한 정보를 담고 있어야 합니다.
앞서 말했듯이, 수직 분할 방식은 풀스택 프레임워크와 함께 사용하기에 매우 적합합니다. 왜냐하면 이런 프레임워크들이 여러분과 LLM(언어 모델)이 해야 할 복잡한 작업을 많이 대신해 주기 때문이죠.
처음부터 모든 데이터베이스 모델을 다 정의하려고 하기보다는, 가장 단순한 형태의 전체 기능을 하나씩 개발하고, 이후 단계에서 그 위에 필요한 기능을 점차 추가하는 방식입니다.
예를 들어, 초기 단계에서는 인증에 필요한 데이터베이스 모델만 정의하고, 관련 서버 사이드 로직과 로그인 폼이나 로그인 페이지 같은 UI만 만드는 것이죠.

제가 만든 Wasp 프로젝트에서는 각 기능이나 단계별 구현 흐름이 대략 다음과 같았습니다.
schema.prisma에 정의main.wasp 파일에 해당 기능의 동작(Operation) 정의main.wasp에 페이지/라우트 정의src/features 또는 src/components에서 UI 구현react-router-dom, recharts, tanstack-table)으로 기능 연결이 방식 덕분에, 저도 LLM도 복잡성에 묻히지 않고 점진적으로 앱을 개발할 수 있었습니다.
기본적인 기능이 잘 작동하기 시작하면, 그 위에 더 복잡한 로직이나 세부 기능은 문제없이 자연스럽게 추가할 수 있었습니다.
또 하나의 장점은, 계획에 없던 기능이 나중에 필요해졌을 때도 유연하게 대응할 수 있었다는 것입니다. 예를 들어 어떤 기능을 나중에 추가하고 싶어 졌을 때, LLM에게 현재 계획을 검토해 보라고 요청하면, 그 기능을 어느 단계에서 구현하는 게 가장 좋을지 알려주었습니다. 지금 당장 넣는 게 좋을 때도 있었고, 나중에 넣는 게 더 나을 때도 있었죠. 그런 경우엔 계획을 유연하게 업데이트하면서 개발을 이어갔습니다.
문서화는 종종 우선순위에서 밀리곤 합니다. 하지만 AI와 함께하는 개발 워크플로우에서는, 왜 특정 방식으로 구현했는지, 현재 구조가 어떻게 작동하는지를 기록하는 것이 훨씬 더 중요해집니다.
AI는 기본적으로 예전 단계의 맥락을 "기억"하지 못하기 때문에, 우리가 직접 그 맥락을 다시 제공해 줘야 합니다. 이 작업 또한 LLM에게 맡겼습니다. :)
저는 하나의 중요한 기능이나 계획에서 정의된 개발을 마칠 때마다, AI에게 우리가 방금 만든 기능을 문서화하게 하는 걸 습관처럼 진행했습니다. 이 작업을 쉽게 하기 위해 문서화 작업 전용 규칙 파일도 따로 만들었습니다.
문서화 과정은 대략 아래와 같이 진행되었습니다.
특히 핵심 로직이 무엇인지, 각 계층(DB → 서버 → 클라이언트)이 어떻게 연결되는지, 그리고 어떤 주요 결정 사항이 있었는지에 집중하는 것이 중요합니다. 또한 그 내용이 실제로 구현된 파일 위치도 함께 명시하여야 합니다.
이 과정을 통해 AI는 ai/docs/ 디렉토리에 마크다운 형식의 문서 파일을 새로 만들거나 기존 파일을 업데이트합니다. 이게 유용한 이유는 두 가지가 있습니다.
이렇게 "한 사이클을 마무리하는(closing the loop)" 방식으로 문서화를 하면, 귀찮은 일이 아니라 워크플로우를 계속해서 효과적으로 유지하는 깔끔한 방법이 됩니다.
그럼, 정말로 "바이브 코딩(vibe coding)”해서 몇 시간 만에 복잡한 SaaS 앱을 만들 수 있을까요?
음…. 가능하긴 하지만, 아마 굉장히 단순하고 재미없는 앱일 겁니다.
하지만 AI를 활용해서 개발 과정을 크게 향상해 더 빠르게 만들고 복잡한 로직도 효과적으로 다루며 전체 구조도 훨씬 더 깔끔하게 유지하는 것은 가능합니다.
제가 여러 주 동안 실험하면서 정리한 "바이브 코딩 워크플로우"의 핵심 원칙은 다음과 같습니다.
.cursor/rules/ 같은 규칙 파일을 만들어, 프로젝트 규칙, 사용하는 기술 스택, 자주 발생하는 실수들에 대해 구체적으로 알려주세요. AI의 일반적인 지식에만 의존하지 마세요.이렇게 구조화된 접근 방식을 따르니까 기능을 정말 빠르게 구현할 수 있었고, 복잡한 앱도 이전보다 20~50배는 빨리 만들 수 있었습니다.
또한, 지식이 풍부한 AI 파트너가 옆에서 아이디어를 다듬고 가설을 검증해 주는 느낌도 정말 놀라웠습니다.
물론, 코드 한 줄 안 써도 많은 걸 할 수 있지만, 여전히 개발자인 여러분이 코드를 이해하고, 방향을 제시하며, 리뷰하는 역할은 꼭 필요합니다.
그렇지만 이건 정말 현실적이고 효과적인 방법이고, 단순한 프롬프트를 넘어서 Cursor의 Gemini 2.5 Pro와 같은 AI와 함께 진짜 앱을 만들어가는 새로운 방식입니다.
전체 워크플로우를 처음부터 끝까지 보고 싶다면, 유튜브에 올라온 약 3시간짜리 워크스루 영상과 템플릿 저장소를 참고해 보세요.
혹시 제가 놓친 팁이 있다면 댓글로 알려주세요! :)
I appreciate this thoughtful post and the useful points you made. On a related note, I discovered a website, https://deerflow.net, that can easily generate in-depth research reports, saving a significant amount of time.https://seededit.app is a free image-editing tool. https://masteragent.app is a smart AI agent.