서류 검토할 때 포트폴리오를 30초 본다. 그 30초 안에 뭘 보는지 이야기해보려 한다. 지난 1년간 우리 팀 채용에 참여하면서 프론트엔드 신입 지원자 이력서를 60개 넘게 봤는데, 그중 포트폴리오 링크를 눌러서 1분 이상 머문 건 10개도 안 됐다.
왜 30초냐면, 현실적으로 그 이상 볼 시간이 없다. 서류 검토는 보통 업무 사이사이에 한다. 스프린트 플래닝 끝나고 점심 전 40분, 배포 대기하는 동안 20분. 그 시간에 이력서 5~6개를 훑어야 하니까, 포트폴리오 하나에 할애할 수 있는 시간은 진짜 30초에서 길어야 1분이다. 그래서 첫인상이 전부다.
README가 없으면 그냥 닫는다
GitHub 링크를 눌렀을 때 제일 먼저 보이는 게 README다. 그런데 놀랍게도 지원자 절반 이상이 README를 안 쓴다. Create React App이 자동 생성한 기본 README가 그대로 있거나, 아예 빈 파일인 경우가 많다.
이건 식당으로 치면 간판 없이 문만 열어놓은 거랑 비슷하다. 안에 음식이 아무리 맛있어도, 뭐 파는 집인지 모르면 들어가기 꺼려진다. README도 마찬가지다. 이 프로젝트가 뭔지 30초 안에 파악이 안 되면, 코드를 뜯어볼 이유가 없다.
README에 뭘 써야 하냐고 물으면, 세 가지만 있으면 된다.
프로젝트 한 줄 설명. "쇼핑몰 클론"이 아니라 "실시간 재고 반영이 되는 의류 쇼핑몰"처럼 이 프로젝트의 핵심이 뭔지 한 문장으로. 한 줄이면 된다. 길게 쓸 필요 없다.
기술 선택 이유. React를 썼으면 왜 React인지. "많이 써서"는 이유가 아니다. "컴포넌트 단위로 UI를 조합하고 싶었고, 상품 목록처럼 반복되는 패턴이 많아서 재사용성이 중요했다" 정도면 충분하다. 상태 관리 라이브러리를 선택한 이유, CSS 방법론을 고른 이유 같은 것도 마찬가지다. 이걸 쓸 수 있다는 건 기술을 의식적으로 선택했다는 뜻이고, 그건 면접관 입장에서 꽤 큰 신호다.
본인 기여도. 팀 프로젝트라면 이게 특히 중요하다. "프론트엔드 전체 담당"이라고만 쓰면 뭘 했는지 알 수가 없다. "상품 검색 페이지 구현 (debounce 적용, 검색어 하이라이팅), 장바구니 상태 관리 (Zustand), 반응형 레이아웃" 이런 식으로 구체적으로 적혀 있으면 바로 해당 코드를 찾아서 볼 수 있다.
작년에 본 지원자 중에 README를 거의 기술 블로그 수준으로 쓴 사람이 있었다. 프로젝트 설명, 기술 스택 선정 이유, 아키텍처 다이어그램, 트러블슈팅 과정까지 정리돼 있었다. 그 README만 읽고도 이 사람이 어떤 사고방식으로 개발하는지 감이 왔다. 코드를 뜯어보기도 전에 이미 면접 보고 싶다는 생각이 들었다.
클론 코딩이 나쁜 건 아닌데
이건 좀 민감한 주제다. 신입 지원자 포트폴리오의 70~80%가 클론 코딩이다. 넷플릭스 클론, 인스타그램 클론, 당근마켓 클론. 클론 자체가 나쁜 건 아니다. 실제로 잘 만들어진 서비스를 따라 만들면서 배우는 게 분명히 있다.
문제는 "따라 만들기"에서 끝나는 경우다.
유튜브 강의를 보면서 똑같이 따라 치고, 강의 코드를 그대로 가져다 쓰고, 거기에 자기만의 생각이 하나도 안 들어가 있으면 — 그건 면접관 입장에서 볼 게 없다. 왜냐하면 코드를 짠 건 그 사람이 아니라 강의를 만든 사람이니까.
클론이라도 차별화되는 순간이 있다. 넷플릭스 클론을 만들면서 "무한 스크롤 구현할 때 Intersection Observer를 써봤는데, 이미지가 많아서 성능이 안 나왔다. 그래서 가상 스크롤을 직접 구현해봤다"라는 과정이 README에 적혀 있으면 이건 클론이 아니라 학습 프로젝트가 된다. "왜 이 기술을 썼는지", "어떤 문제를 만났고 어떻게 해결했는지"가 있냐 없냐의 차이다.
반면에 실제 문제를 해결한 프로젝트는 그 자체로 눈에 띈다. 규모가 작아도 상관없다. 내가 기억나는 건 대학교 동아리 출석 관리 앱을 만든 지원자였다. 기능 자체는 단순했다. QR 코드 출석 체크, 출석률 통계, 관리자 페이지 정도. 근데 README에 이렇게 적혀 있었다.
"기존에 구글 설문지로 출석을 받았는데 대리 출석이 가능하고, 통계를 수동으로 집계해야 했습니다. QR 코드에 위치 정보를 포함시켜 반경 100m 이내에서만 체크인이 되도록 했고, 주차별 출석률이 자동 집계되도록 만들었습니다."
이 한 단락에 문제 정의, 해결 방법, 구체적 구현이 다 들어가 있다. 이런 게 좋은 포트폴리오다. 대단한 기술을 쓸 필요가 없다. 실제 문제를 발견하고, 그걸 코드로 해결한 경험 자체가 가치 있다.
GitHub 잔디는 안 본다
솔직한 얘기를 하면, 잔디를 보는 면접관도 물론 있을 거다. 근데 나는 잔디를 거의 안 본다. 왜냐하면 잔디는 조작이 너무 쉽다. 매일 빈 커밋 하나씩 찍어도 잔디는 초록색으로 채워진다.
대신 커밋 메시지를 본다.
커밋 히스토리를 3~4개만 훑어봐도 이 사람의 개발 습관이 보인다. "fix", "update", "asdf", "ㅋㅋ" 같은 커밋 메시지가 줄줄이 있으면 솔직히 인상이 좋지 않다. 반대로 "feat: 상품 검색 debounce 적용 (300ms)", "fix: 장바구니 수량 변경 시 총 금액 미반영 버그 수정", "refactor: useCart 훅에서 계산 로직 분리" 같은 메시지가 있으면 이 사람이 작업 단위를 어떻게 나누고, 변경 사항을 어떻게 설명하는지가 바로 느껴진다.
커밋 메시지가 깔끔한 사람은 실무에서 PR 설명도 잘 쓰고, 이슈 트래킹도 잘 한다. 그게 경험상 꽤 정확한 상관관계다. 개발 실력이랑 직접적인 관계가 있다고까지는 안 하겠지만, 협업 역량의 지표로는 꽤 신뢰할 만하다.
배포 안 된 프로젝트
이것도 많이 보이는 패턴이다. GitHub 링크만 있고, 배포 링크가 없는 경우.
코드만 보면 되는 거 아니냐고 생각할 수 있는데, 면접관 입장에서는 배포된 프로젝트를 더 신뢰한다. 이유가 몇 가지 있다. 첫째, 배포까지 해봤다는 건 빌드 에러, 환경 변수 설정, CORS 같은 실전 이슈를 한 번이라도 겪었다는 뜻이다. 둘째, 돌아가는 화면을 직접 클릭해볼 수 있으면 코드를 읽기 전에 전체적인 맥락을 빠르게 파악할 수 있다. 그 30초 안에 "아 이런 서비스구나"를 이해하는 데 도움이 된다.
Vercel이나 Netlify를 쓰면 Next.js나 React 프로젝트 배포하는 데 10분이면 된다. GitHub repo 연결하고 몇 번 클릭하면 끝이다. 이 10분을 투자 안 한 건 아쉽다.
한 가지 주의할 게 있다. 배포해놓고 서버가 죽어있거나, API 키가 만료돼서 빈 화면만 뜨는 경우. 이건 안 한 것보다 인상이 더 나쁘다. 배포 링크를 넣을 거면, 주기적으로 한 번씩 접속해서 살아있는지 확인하자.
1개의 완성 > 5개의 미완성
포트폴리오에 프로젝트를 5~6개 넣어놓은 지원자가 있다. 하나씩 눌러보면 README가 없거나, 커밋이 3개뿐이거나, 기능이 반만 구현돼 있다. 이러면 오히려 역효과다.
"많이 해봤다"를 보여주고 싶은 마음은 이해한다. 근데 면접관이 보는 건 양이 아니라 깊이다. 하나의 프로젝트를 제대로 끝냈는지. 에러 처리는 했는지. 반응형은 잡았는지. edge case는 고려했는지. 그런 게 보고 싶다.
내가 실제로 높게 평가했던 지원자는 포트폴리오 프로젝트가 딱 2개였다. 하나는 팀 프로젝트, 하나는 개인 프로젝트. 둘 다 README가 탄탄했고, 배포가 돼 있었고, 커밋 히스토리가 깔끔했다. 개인 프로젝트는 할 일 관리 앱이었는데 — 네, 투두리스트다. 근데 이게 범상치 않았다. 드래그 앤 드롭으로 순서 변경, 카테고리별 필터링, 로컬 스토리지 동기화, 그리고 키보드만으로 모든 기능을 사용할 수 있는 접근성 처리까지 돼 있었다. README에는 "기존 투두 앱들을 써보면서 불편했던 점들을 개선하는 방향으로 만들었다"고 적혀 있었고, 각 기능별로 왜 그렇게 구현했는지 설명이 있었다.
투두리스트를 이렇게까지 깊이 만들 수 있다는 걸 보여준 거다. 주제가 뻔해도 상관없다. 깊이가 보이면 된다.
이력서의 기술 스택 나열
이건 포트폴리오가 아니라 이력서 얘기인데, 같이 보는 거니까 짚고 넘어간다.
"React, TypeScript, Next.js, Redux, Styled-components, Jest, Storybook, GraphQL, Docker..."
이렇게 기술 스택을 쭉 나열해놓은 이력서가 정말 많다. 이걸 보면 드는 생각은 "이 기술들을 진짜 다 쓸 줄 아나?"다. 신입인데 이 목록이 전부 가능하다? 현실적으로 어렵다. 그래서 스택 나열 자체가 오히려 신뢰를 떨어뜨리는 경우가 있다.
차라리 이렇게 쓰는 게 낫다.
"상품 검색 페이지에서 입력할 때마다 API를 호출하던 구조를 debounce로 개선해서 API 호출 횟수를 80% 줄였습니다."
"이미지 lazy loading과 WebP 변환을 적용해서 상품 목록 페이지 LCP를 3.2초에서 1.1초로 줄였습니다."
기술 이름이 아니라, 그 기술로 뭘 했는지를 쓰는 거다. 숫자가 들어가면 더 좋다. 면접관은 "React를 할 줄 안다"보다 "React로 이런 문제를 이렇게 해결했다"에 훨씬 더 관심이 있다. 면접에서도 이런 성과 중심으로 이력서를 쓴 사람한테는 자연스럽게 "그거 어떻게 측정했어요?" "다른 방법은 고려 안 했어요?" 같은 깊이 있는 질문을 하게 된다. 대화가 풍성해진다.
기술 스택을 아예 안 쓰라는 건 아니다. 스택은 간단하게 정리하되, 각 프로젝트 설명에서 "이 기술로 이런 걸 했다"를 보여주는 구조가 이상적이다.
눈에 띄었던 포트폴리오
지금까지 봤던 것 중에 특히 기억에 남는 케이스 두 개를 익명으로 공유한다.
A 지원자. 이 사람은 포트폴리오 사이트 자체가 인상적이었다. Next.js로 만든 개인 사이트였는데, 프로젝트 소개가 단순 나열이 아니라 각 프로젝트마다 "문제 → 시도 → 결과" 흐름으로 정리돼 있었다. 그리고 프로젝트 페이지 하단에 "아쉬운 점과 다음에 개선할 것"이 적혀 있었다. "상태 관리를 Context API로 했는데 리렌더링 이슈가 있어서 다음에는 Zustand를 써볼 예정"이라는 식으로. 이게 좋았던 건, 이 사람이 자기 코드를 객관적으로 볼 줄 안다는 걸 보여줬기 때문이다. 신입한테 완벽한 코드를 기대하는 사람은 없다. 대신 뭐가 부족한지 아는 사람을 원한다.
B 지원자. 프로젝트가 하나였다. 동네 소규모 카페의 주문 관리 시스템. README 첫 줄이 "부모님이 운영하는 카페에서 종이로 주문을 받는 게 비효율적이라 만들었습니다"였다. 기술적으로 대단한 건 아니었다. 근데 이 사람은 실제 사용자(부모님과 카페 직원)의 피드백을 반영한 커밋 히스토리가 있었다. "사장님이 글씨가 작다고 해서 폰트 사이즈 조정", "주문 취소 기능 요청으로 추가 구현" 같은. 실제 사용자가 있는 프로젝트는 그 자체가 강력한 차별점이다. 사용자의 요구사항을 듣고 반영하는 경험은 실무에서 매일 하는 일이니까.
30초를 넘기는 법
길게 썼지만 핵심은 단순하다. 면접관은 "이 사람이 우리 팀에 들어오면 같이 일할 수 있겠다"를 판단하려는 거다. 코드를 잘 짜는지도 보지만, 그보다 자기가 뭘 했는지 설명할 수 있는 사람인지, 문제를 인식하고 해결하려고 시도한 사람인지를 본다.
README를 쓰자. 커밋 메시지를 신경 쓰자. 하나라도 제대로 배포하자. 기술 나열 대신 성과를 쓰자.
포트폴리오에 들이는 시간 중 절반은 코드를 짜는 데, 나머지 절반은 그 코드를 설명하는 데 쓰는 게 맞다. 아무리 좋은 코드를 짜도, 그걸 전달하지 못하면 30초 안에 탭이 닫힌다.
