바이브코딩 웹 구조, HTML CSS JS 와 서버가 각각 하는 일

2026.10.17 · 밥

AI 한테 웹게임 하나 만들어 달라고 하면 파일이 우르르 나온다. index.html, style.css, main.js, 가끔은 server.py 나 package.json 까지. 돌아가긴 하는데, 어디를 고쳐야 버튼 색이 바뀌고 어디를 고쳐야 점수가 저장되는지 모르면 다음 요청부터 막힌다. 바이브코딩을 시작하면 파이썬부터 배워야 하나 싶기도 하다. 그 전에 웹이 어떻게 굴러가는지 큰 그림부터 잡는 게 낫다.

바이브코딩 웹 구조를 한 문단으로 줄이면 이렇다. 브라우저가 서버에 파일을 달라고 요청하고, 서버가 응답으로 돌려준다. HTML 은 뼈대, CSS 는 모양, JS 는 움직임이고, 웹페이지를 볼 때 셋 다 내 브라우저가 해석하고 실행한다. 서버 쪽 코드는 여러 사람이 같은 데이터를 나눠 쓰거나 사람마다 다른 내용을 줘야 할 때 필요해진다. 아래는 2026년 10월 17일에 연 MDN 문서 기준이고, 요청과 응답은 이 블로그 주소로 직접 찍어 봤다.

주소를 치면 일어나는 일, 웹 구조의 출발점

MDN 의 웹은 어떻게 동작하나 문서는 이걸 네 단계로 설명한다. 먼저 브라우저가 DNS 서버에서 사이트가 있는 서버의 실제 주소를 찾는다. 문서는 DNS 를 웹사이트 주소록에 빗댄다. 그다음 서버에 HTTP 요청을 보내고, 서버가 받아 주면 200 OK 와 함께 파일을 패킷이라는 작은 조각으로 나눠 보낸다. 브라우저는 그 조각을 모아 페이지로 조립한다.

여기서 기억할 건 대화의 방향이다. HTTP 개요 문서를 보면 요청은 늘 클라이언트 쪽이 시작한다. 웹페이지를 볼 때는 브라우저가 그 역할이고, 아래에서 응답을 찍을 때는 curl 이 요청을 보냈다. 서버는 기다렸다가 답할 뿐. 그리고 HTTP 는 상태가 없다. 같은 연결로 연달아 보낸 요청 둘 사이에도 연결고리가 없다는 뜻이다. 로그인이나 장바구니처럼 앞의 일을 기억해야 하면 쿠키 같은 장치를 따로 쓴다.

웹 구조를 실제 요청과 응답으로 보기

말로만 들으면 감이 잘 안 온다. 그래서 이 블로그 주소로 직접 물어봤다. 윈도우 PowerShell 에서 curl.exe -sI 주소 를 치면 본문은 빼고 응답 머리만 보여 준다.

주소마다 상태 코드와 파일 종류가 따로 온다
주소마다 상태 코드와 파일 종류가 따로 온다

휴대폰에선 그림 글자가 작을 수 있어서 같은 출력을 그대로 옮겨 둔다.

> curl.exe -sI https://textverse.kr/
HTTP/1.1 200 OK
Content-Type: text/html

> curl.exe -sI https://textverse.kr/style.css
HTTP/1.1 200 OK
Content-Type: text/css

> curl.exe -sI https://textverse.kr/no-such-page-xyz/
HTTP/1.1 404 Not Found
Content-Type: text/html

첫 화면 주소는 200 OK 에 text/html, 스타일 파일은 200 OK 에 text/css 가 왔다. 없는 주소를 넣으니 404 Not Found. 실제 응답엔 캐시 관련 줄이 더 붙어 있었는데 그림에선 줄였다. Content-Type 은 이게 무슨 종류의 파일인지 브라우저한테 알려 주는 칸이다.

첫 화면 HTML 을 통째로 받아서 안에서 뭘 부르는지도 세어 봤다. 스타일 파일 1개, 스크립트 1개, 글 썸네일 그림 12개. HTTP 개요 문서 설명 그대로였다. 브라우저는 HTML 을 먼저 받고, 그걸 읽어 가면서 CSS 랑 스크립트, 그림을 따로 또 요청해서 합친다. 화면 하나가 요청 하나로 끝나는 게 아니라는 거다.

HTML CSS JS, 바이브코딩 결과물에서 어디를 고치나

MDN 의 자바스크립트란 문서는 셋을 케이크 층에 빗댄다. HTML 은 내용에 구조와 의미를 주는 마크업이다. 제목, 문단, 표, 그림 자리 같은 것. CSS 는 그 위에 스타일을 입히는 규칙이다. 배경색, 글꼴, 여러 단 배치. JS 는 세 번째 층으로, 내용을 그때그때 바꾸거나 그림을 움직이는 동작을 맡는다. 문서 예로는 버튼 하나를 HTML 로 만들고, CSS 로 꾸미고, JS 로 누르면 반응하게 한다.

AI 가 만든 파일에 그대로 대 보면 고칠 곳이 보인다. 글자나 칸이 빠졌으면 HTML, 색이나 간격이 이상하면 CSS, 눌러도 아무 일이 없으면 JS 쪽부터 보면 된다. 요청할 때도 버튼 색을 바꿔 달라고 하는 것보다 style.css 에서 시작 버튼 색만 바꿔 달라고 파일을 짚어 주면 범위가 좁아진다.

하나 걸리는 게 있다. 웹페이지에 들어간 이 셋은 다 내 브라우저에서 돈다는 것. 문서는 이렇게 브라우저가 내려받아 실행하는 걸 클라이언트 쪽 코드라고 부른다. JS 라는 언어 자체는 Node.js 처럼 서버에서 돌릴 수도 있으니, 언어 이름 말고 어디서 도느냐로 나누는 거다. 받은 사람 컴퓨터에 파일이 그대로 와 있는 셈이니 브라우저로 보내는 HTML 이나 JS 안에 넣은 건 남도 열어 볼 수 있다고 봐야 한다. API 키 같은 비밀값을 JS 에 넣으면 안 되는 이유다.

서버가 필요한 순간, 정적 사이트와 동적 사이트

서버 쪽 입문 문서는 사이트를 둘로 나눈다. 정적 사이트는 같은 주소를 요청하면 늘 미리 만들어 둔 같은 내용을 돌려준다. 서버는 자기 파일 중에서 맞는 걸 찾아 200 OK 로 보내고, 못 찾으면 오류를 보낸다. 위에서 찍은 404 가 그런 오류 응답의 예. 동적 사이트는 응답 일부를 필요할 때 만든다. 대표적인 방식이 데이터베이스에서 꺼낸 값을 HTML 틀에 끼우는 거라, 같은 주소라도 사람마다 다른 화면이 나올 수 있다. 다만 이건 입문용 나눔이다. 문서도 동적 사이트가 CSS 나 그림 같은 파일은 정적 사이트처럼 보낸다고 적어 뒀고, 실제 서비스는 둘을 섞어 쓰기도 한다.

같은 문서에 이런 차이도 있다. 브라우저 쪽 코드는 운영체제에 거의 손을 못 대고 파일 접근도 제한된다. 반대로 서버 쪽 코드는 서버 운영체제에 다 접근할 수 있다. 그래서 여러 사람의 데이터를 한곳에 모아 두고 지키는 일은 서버 몫. 문서가 서버가 필요한 경우로 드는 건 정보 저장, 사람마다 다른 화면, 허락한 사람만 보게 하는 접근 제한, 로그인이나 게임 상태 기억, 메일 같은 알림, 데이터 분석이다.

내 경우엔 이 나눔이 잘 맞았다. 이 블로그는 정적 사이트다. 글을 미리 HTML 로 만들어 정적 호스팅에 올려 두고, 따로 운영하는 웹 앱이나 데이터베이스는 없다. 만든 구조는 Node 정적 블로그 글에 따로 적었다. 반면 혼자 만드는 웹게임 TEXT WAR 는 계정이랑 게임 진행을 저장해야 해서 Python 웹 앱 하나와 PostgreSQL 데이터베이스를 서버에 따로 돌린다. 서버 비용 얘기는 웹게임 서버 비용 글 쪽에.

바이브코딩 웹 구조, 만들기 전에 정할 것

그래서 AI 한테 뭘 만들어 달라고 하기 전에 하나만 먼저 정하면 된다. 데이터가 내 브라우저 안에만 있으면 되는지, 여러 사람이나 여러 기기가 같이 보고 한곳에서 확인해야 하는지. 계산기나 포트폴리오, 혼자 하는 퍼즐처럼 내 화면 안에서만 돌면 되는 거라면 HTML, CSS, JS 만으로 된다. 혼자 쓰는 진행 기록 정도는 브라우저 저장소인 localStorage에 넣어 둘 수도 있다. 파일만 올리면 되니 올릴 곳 고르기도 쉽고. 계정별 기록이나 같이 보는 점수판처럼 한곳에서 관리해야 하는 기능이 들어가면, 서버 쪽 기능과 데이터를 어디에 어떻게 저장할지부터 정해야 한다. 그 순간부터 올릴 곳, 비용, 백업, 보안까지 따라온다.

하나 더. JS 파일이 든 HTML 을 더블클릭해서 file:// 로 열면 모듈 스크립트가 막힐 수 있다. 자바스크립트 문서도 그래서 로컬 시험 서버로 열어 보라고 권한다. AI 가 로컬 서버부터 띄우라고 하는 게 이 얘기. 이건 이번에 직접 해 보진 않았다. 문서에 적힌 내용이다.

다음엔 ChatGPT 구독이랑 API 결제가 왜 따로인지, 처음 키 만들 때 볼 것을 정리하려고 한다.