Vite 8로 React 프로젝트를 시작하려면 지원되는 Node.js 버전을 먼저 확인하고 npm create vite@latest를 실행합니다. React 또는 React+TypeScript 템플릿을 선택한 뒤 개발 서버, 프로덕션 빌드, 미리보기 순서로 검증합니다.- Vite는 React에서 무엇을 해주는 도구인가
- React Vite 프로젝트 만들기 전 준비 사항
- Vite 8 Node.js 요구 버전
- Vite로 React 프로젝트 생성하기
- React TypeScript 템플릿
- 개발 서버 실행과 화면 확인
- 생성된 프로젝트 구조 이해하기
- React Vite 프로젝트 빌드하기
- 초반에 자주 쓰는 Vite 설정
- 처음 사용할 때 자주 헷갈리는 점
- 정리: Vite는 React 개발 시작점을 단순하게 만든다
- 공식 문서
Vite는 React에서 무엇을 해주는 도구인가

Vite는 React 코드를 브라우저에서 확인하고, 배포 가능한 결과물로 묶어 주는 개발 도구입니다. React 자체는 화면을 컴포넌트로 구성하는 라이브러리이고, Vite는 그 코드를 개발 중에 실행하거나 실제 서비스용 파일로 빌드하는 역할을 맡습니다.
예전에는 React 프로젝트를 시작할 때 Create React App을 많이 사용했습니다. 하지만 프로젝트가 커질수록 개발 서버 시작이나 코드 수정 반영이 느리게 느껴지는 경우가 있었습니다. Vite는 개발 중에는 브라우저가 필요한 모듈만 빠르게 가져가도록 처리하고, 빌드할 때는 최적화된 정적 파일을 만들어 줍니다.
중요한 점은 Vite가 React를 대체하는 도구가 아니라 React 개발 환경을 구성해 주는 도구라는 것입니다. 따라서 useState, useEffect, 컴포넌트 작성 방식은 그대로 사용하면서 프로젝트 생성과 실행 경험만 더 단순하게 가져갈 수 있습니다.
React Vite 프로젝트 만들기 전 준비 사항
Vite로 React 프로젝트를 만들려면 먼저 Node.js와 npm이 설치되어 있어야 합니다. Node.js는 개발 도구를 실행하는 런타임이고, npm은 필요한 패키지를 설치하고 스크립트를 실행하는 패키지 매니저입니다.
node -v
npm -v
위 명령어를 실행했을 때 버전 번호가 출력되면 설치 여부를 확인한 것입니다. 아래 Vite의 Node.js 요구 범위까지 만족하는지 확인하세요. 만약 명령어를 찾을 수 없다는 메시지가 나온다면 Node.js를 먼저 설치해야 합니다. 실무에서는 팀마다 npm, pnpm, yarn 중 하나를 정해 쓰기도 하지만, 처음 학습한다면 npm만으로 충분합니다.
npm: 기본으로 설치되어 접근성이 좋습니다.pnpm: 저장 공간과 설치 속도 측면에서 장점이 있습니다.yarn: 기존 프로젝트에서 여전히 자주 만날 수 있습니다.
이 글에서는 가장 범용적인 npm 기준으로 진행합니다. 다른 패키지 매니저를 사용해도 전체 흐름은 거의 같습니다.
Vite 8 Node.js 요구 버전
Vite 8은 Node.js 20.19+ 또는 22.12+를 요구합니다. 생성 명령에서 엔진 오류가 나오면 Vite를 낮추기보다 node --version으로 런타임을 확인하고 지원되는 LTS 버전으로 올리는 것이 좋습니다.
node --version
npm create vite@latest my-react-app -- --template react
Vite로 React 프로젝트 생성하기
새 React 프로젝트는 npm create vite@latest 명령어로 만들 수 있습니다. 터미널에서 프로젝트를 만들 위치로 이동한 뒤 아래 명령어를 실행합니다.
npm create vite@latest my-react-app
my-react-app은 생성할 프로젝트 폴더 이름입니다. 원하는 이름으로 바꿔도 됩니다. 명령어를 실행하면 사용할 프레임워크와 템플릿을 선택하라는 안내가 나옵니다. 여기서는 프레임워크로 React를 선택하고, 템플릿은 일반 JavaScript 기반이라면 JavaScript, 타입 안정성을 함께 가져가고 싶다면 TypeScript를 선택합니다.
처음 React를 익히는 단계라면 JavaScript 템플릿으로 시작해도 좋습니다. 이미 TypeScript를 알고 있거나 실무 프로젝트를 염두에 둔다면 TypeScript 템플릿을 고르는 편이 자연스럽습니다.
cd my-react-app
npm install
npm install은 package.json에 적힌 의존성을 실제로 설치합니다. 이 과정을 거치면 node_modules 폴더가 생기고, 프로젝트에서 필요한 React와 개발 도구가 준비됩니다.
React TypeScript 템플릿
npm create vite@latest my-react-app -- --template react-ts
cd my-react-app
npm install
npm run dev
npm run build
npm run preview
npm run dev는 개발 서버, npm run build는 배포 결과 생성, npm run preview는 빌드 결과의 로컬 확인에 사용합니다.
개발 서버 실행과 화면 확인
의존성 설치가 끝나면 개발 서버를 실행할 수 있습니다. Vite 프로젝트에서는 기본적으로 npm run dev를 사용합니다.
npm run dev
터미널에 로컬 접속 주소가 표시됩니다. 보통 http://localhost:5173 형태입니다. 브라우저에서 이 주소를 열면 React 기본 화면을 확인할 수 있습니다.
개발 서버가 실행된 상태에서 src/App.jsx를 수정하면 브라우저 화면이 거의 즉시 갱신됩니다. 이 기능은 빠른 피드백을 주기 때문에 컴포넌트 UI를 만들거나 스타일을 조정할 때 체감 차이가 큽니다.
function App() {
return (
<main>
<h1>React Vite 시작하기</h1>
<p>첫 번째 Vite 프로젝트입니다.</p>
</main>
)
}
export default App
위처럼 App 컴포넌트를 수정한 뒤 저장하면 새로고침을 직접 누르지 않아도 변경 사항이 반영됩니다. 이 흐름이 Vite를 사용하는 가장 기본적인 개발 경험입니다.
생성된 프로젝트 구조 이해하기

Vite로 프로젝트를 만들면 처음에는 파일이 많아 보일 수 있지만, 핵심은 몇 개뿐입니다. 가장 자주 보는 위치는 src 폴더와 루트의 index.html, vite.config.js, package.json입니다.
my-react-app/
index.html
package.json
vite.config.js
src/
App.jsx
main.jsx
assets/
src/main.jsx는 React 앱의 진입점입니다. 여기에서 createRoot를 사용해 App 컴포넌트를 실제 DOM에 연결합니다. src/App.jsx는 기본 화면을 구성하는 컴포넌트 파일이며, 학습 단계에서는 가장 먼저 수정하게 되는 파일입니다.
index.html은 브라우저가 처음 읽는 HTML 파일입니다. 일반 React 코드와 달리 이 파일 안에는 div 같은 실제 루트 요소가 있고, src/main.jsx가 연결됩니다. Vite에서는 index.html도 중요한 진입점으로 취급됩니다.
vite.config.js는 Vite 설정 파일입니다. 공식 React 템플릿의 React 플러그인, 개발 서버 옵션, 경로 별칭 같은 설정을 이 파일에서 다룹니다. 처음에는 거의 수정하지 않아도 되지만, 프로젝트가 커지면 자연스럽게 보게 됩니다.
React Vite 프로젝트 빌드하기
개발 중에는 npm run dev를 사용하지만, 실제 배포를 위해서는 빌드가 필요합니다. 빌드는 개발용 코드를 브라우저가 효율적으로 받을 수 있는 정적 파일로 만드는 과정입니다.
npm run build
명령어가 성공하면 dist 폴더가 생성됩니다. 이 폴더 안에는 압축되고 최적화된 HTML, JavaScript, CSS 파일이 들어갑니다. 실제 배포 플랫폼에는 보통 dist 폴더의 결과물이 올라갑니다.
빌드 결과를 로컬에서 확인하고 싶다면 npm run preview를 사용할 수 있습니다.
npm run preview
npm run preview는 개발 서버가 아니라 빌드된 결과물을 미리 보는 서버입니다. 개발 중 화면과 배포용 결과가 다르게 보이는 문제를 확인할 때 유용합니다. 배포 전에는 최소 한 번 npm run build와 npm run preview를 실행해 보는 습관이 좋습니다.
초반에 자주 쓰는 Vite 설정
처음에는 기본 설정만으로 충분하지만, 프로젝트를 진행하다 보면 포트 변경, 자동 브라우저 열기, 경로 별칭 같은 설정이 필요해질 수 있습니다. 이런 설정은 vite.config.js에서 관리합니다.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
open: true
}
})
위 설정에서 server.port는 개발 서버 포트를 3000으로 바꿉니다. server.open을 true로 두면 npm run dev 실행 시 브라우저가 자동으로 열립니다.
컴포넌트가 많아지면 상대 경로가 길어질 수 있습니다. 이때는 경로 별칭을 설정해 src 폴더를 짧게 참조할 수 있습니다.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
이 설정을 적용하면 src/components/Button.jsx를 @/components/Button.jsx처럼 가져올 수 있습니다. 다만 작은 프로젝트에서는 반드시 필요한 설정은 아닙니다. 팀에서 정한 규칙이 없다면 처음에는 기본 상대 경로로 시작하고, 파일 구조가 복잡해질 때 적용해도 늦지 않습니다.
환경 변수는 .env 파일에 작성할 수 있습니다. Vite에서 클라이언트 코드에 노출할 값은 이름이 VITE_로 시작해야 합니다.
VITE_API_BASE_URL=https://api.example.com
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL
import.meta.env는 Vite가 제공하는 환경 변수 접근 방식입니다. 비밀번호나 서버 전용 비밀 키처럼 노출되면 안 되는 값은 프론트엔드 환경 변수에 넣으면 안 됩니다.
처음 사용할 때 자주 헷갈리는 점
첫 번째로 자주 하는 실수는 npm install을 건너뛰는 것입니다. 프로젝트 폴더를 만든 직후 바로 npm run dev를 실행하면 의존성이 없어서 오류가 납니다. 반드시 프로젝트 폴더로 이동한 뒤 npm install을 먼저 실행해야 합니다.
cd my-react-app을 실행하지 않아 다른 위치에서 명령어를 실행하는 경우npm install없이npm run dev를 실행하는 경우localhost주소를 잘못 입력하는 경우.env값을 바꾼 뒤 개발 서버를 재시작하지 않는 경우dist폴더를 직접 수정하려고 하는 경우
dist 폴더는 빌드 결과물이므로 직접 수정하는 대상이 아닙니다. 화면을 바꾸려면 src 안의 React 코드나 스타일 파일을 수정하고 다시 빌드해야 합니다.
또 하나 헷갈리는 부분은 npm run dev와 npm run build의 차이입니다. npm run dev는 개발 중 빠른 확인을 위한 명령어이고, npm run build는 배포 가능한 결과물을 만드는 명령어입니다. 두 명령어는 목적이 다르므로 배포 전에 개발 서버 화면만 보고 끝내지 않는 것이 좋습니다.
정리: Vite는 React 개발 시작점을 단순하게 만든다
Vite를 사용하면 React 프로젝트를 빠르게 만들고, 개발 서버를 실행하고, 수정 결과를 즉시 확인하는 흐름이 단순해집니다. 기본 작업은 npm create vite@latest, npm install, npm run dev, npm run build 네 단계로 이해하면 됩니다.
처음에는 src/App.jsx, src/main.jsx, index.html, vite.config.js의 역할만 알아도 충분합니다. 이후 프로젝트가 커지면 환경 변수, 경로 별칭, 배포 설정을 하나씩 추가하면 됩니다.
Vite의 핵심 가치는 복잡한 설정을 먼저 공부하게 만드는 것이 아니라 React 코드를 빠르게 작성하고 확인할 수 있게 해 주는 데 있습니다. 이 기본 흐름에 익숙해지면 React Router 적용, 상태 관리 도입, API 연동, 배포 같은 다음 단계로 자연스럽게 넘어갈 수 있습니다.
공식 문서
공식 템플릿과 고정 실습의 차이
npm create vite@latest는 실행 시점의 생성기를 사용하므로 앞으로 선택지나 패키지 버전이 달라질 수 있습니다. 이 글의 ZIP은 React 19.3.0·Vite 8.3.0을 직접 고정한 작은 JSX 프로젝트입니다. 템플릿을 새로 생성하지 않고 ZIP의 starter 또는 complete 폴더에서 npm install로 시작합니다.
위 설정 예시는 공식 React 템플릿에 포함된 @vitejs/plugin-react가 있다는 전제입니다. ZIP은 그 플러그인을 사용하지 않으므로 JSX 파일에 import React from "react"를 유지합니다. Vite 기본 JSX 변환만 사용하며 React Fast Refresh의 상태 보존을 제공한다고 가정하지 않습니다.
npm run dev와 npm run preview는 계속 실행되는 서버입니다. Ctrl+C로 종료하거나 다른 터미널에서 다음 명령을 실행하세요. preview는 먼저 build해야 하며 운영 서비스용 서버가 아닙니다. TypeScript 템플릿은 타입 검사 스크립트를 함께 제공할 수 있지만 Vite의 변환 자체는 타입 검사가 아닙니다.
진입점 파일을 직접 연결하기
index.html → src/main.jsx → src/App.jsx 순서로 연결됩니다. CSS는 main.jsx에서 별도로 가져옵니다. 아래 파일은 ZIP 완성본과 같습니다.
index.html
실습 파일
파일 경로를 확인하고 같은 프로젝트 안에 저장하세요. 이미지 등 소스 목록에 없는 파일과 실행 안내는 실습 ZIP에 포함되어 있습니다.
Vite 진입점이 불러오는 React 컴포넌트를 수정하고 화면과 빌드를 확인합니다. 수정 전은 시작 상태, 수정 후는 비교할 완성 상태입니다.
수정 전
index.html
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React 실습</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
package.json
{
"name": "blogflow-react-7690",
"version": "1.0.0",
"private": true,
"type": "module",
"engines": {
"node": ">=22.12.0"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest run"
},
"dependencies": {
"react": "19.3.0",
"react-dom": "19.3.0"
},
"devDependencies": {
"vite": "8.3.0",
"vitest": "4.1.11",
"jsdom": "30.0.1",
"@testing-library/react": "16.3.3",
"@testing-library/user-event": "14.6.7"
}
}
src/App.jsx
import React from 'react';
export default function App() {
return (
<main>
<h1>제목을 바꿔 보세요</h1>
<p>HTML 진입점에서 React 컴포넌트까지 연결했습니다.</p>
<p className="build-note">CSS도 별도 파일에서 가져옵니다.</p>
</main>
);
}
src/main.jsx
import React, { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
import './style.css';
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
);
src/style.css
* {
box-sizing: border-box;
}
body {
margin: 0;
color: #222;
background: #fff;
font-family: sans-serif;
line-height: 1.6;
}
main {
width: min(100% - 32px, 760px);
margin: 32px auto;
}
section,
article {
padding: 16px;
border: 1px solid #aaa;
margin: 16px 0;
}
button,
input,
select {
font: inherit;
color: inherit;
background: #fff;
border: 1px solid #777;
padding: 8px 12px;
min-height: 44px;
}
button {
margin: 4px;
}
button:disabled {
color: #666;
background: #eee;
}
input,
select {
display: block;
width: 100%;
margin: 4px 0 16px;
}
:focus-visible {
outline: 2px solid #222;
outline-offset: 3px;
}
li {
margin: 8px 0;
}
test/App.test.jsx
import React from 'react';
import { test, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import App from '../src/App.jsx';
test('mounts the entry screen', () => {
render(<App />);
expect(screen.getByRole('heading', { name: 'React Vite 시작하기' })).toBeTruthy();
});
test/setup.js
import { afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
afterEach(cleanup);
vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
test: { environment: 'jsdom', setupFiles: './test/setup.js' },
});
수정 방법
index.html
이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.
package.json
이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.
src/App.jsx
src/App.jsx에서 아래 차이가 있는 위치를 수정하세요. -는 삭제할 줄, +는 추가할 줄이며 표시는 실제 코드에 넣지 않습니다.
Vite 진입점이 불러오는 React 컴포넌트를 수정하고 화면과 빌드를 확인합니다.
--- 수정 전/src/App.jsx
+++ 수정 후/src/App.jsx
@@ -3,7 +3,7 @@
export default function App() {
return (
<main>
- <h1>제목을 바꿔 보세요</h1>
+ <h1>React Vite 시작하기</h1>
<p>HTML 진입점에서 React 컴포넌트까지 연결했습니다.</p>
<p className="build-note">CSS도 별도 파일에서 가져옵니다.</p>
</main>
수정 후 탭의 전체 파일과 비교한 뒤 본문의 확인 절차를 실행하세요.
src/main.jsx
이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.
src/style.css
이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.
test/App.test.jsx
이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.
test/setup.js
이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.
vite.config.js
이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.
수정 후
index.html
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React 실습</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
package.json
{
"name": "blogflow-react-7690",
"version": "1.0.0",
"private": true,
"type": "module",
"engines": {
"node": ">=22.12.0"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest run"
},
"dependencies": {
"react": "19.3.0",
"react-dom": "19.3.0"
},
"devDependencies": {
"vite": "8.3.0",
"vitest": "4.1.11",
"jsdom": "30.0.1",
"@testing-library/react": "16.3.3",
"@testing-library/user-event": "14.6.7"
}
}
src/App.jsx
import React from 'react';
export default function App() {
return (
<main>
<h1>React Vite 시작하기</h1>
<p>HTML 진입점에서 React 컴포넌트까지 연결했습니다.</p>
<p className="build-note">CSS도 별도 파일에서 가져옵니다.</p>
</main>
);
}
src/main.jsx
import React, { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
import './style.css';
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
);
src/style.css
* {
box-sizing: border-box;
}
body {
margin: 0;
color: #222;
background: #fff;
font-family: sans-serif;
line-height: 1.6;
}
main {
width: min(100% - 32px, 760px);
margin: 32px auto;
}
section,
article {
padding: 16px;
border: 1px solid #aaa;
margin: 16px 0;
}
button,
input,
select {
font: inherit;
color: inherit;
background: #fff;
border: 1px solid #777;
padding: 8px 12px;
min-height: 44px;
}
button {
margin: 4px;
}
button:disabled {
color: #666;
background: #eee;
}
input,
select {
display: block;
width: 100%;
margin: 4px 0 16px;
}
:focus-visible {
outline: 2px solid #222;
outline-offset: 3px;
}
li {
margin: 8px 0;
}
test/App.test.jsx
import React from 'react';
import { test, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import App from '../src/App.jsx';
test('mounts the entry screen', () => {
render(<App />);
expect(screen.getByRole('heading', { name: 'React Vite 시작하기' })).toBeTruthy();
});
test/setup.js
import { afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
afterEach(cleanup);
vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
test: { environment: 'jsdom', setupFiles: './test/setup.js' },
});
src/main.jsx
src/style.css
직접 실행할 실습
src/App.jsx의 제목을 “React Vite 시작하기”로 바꾸고 src/style.css의 main 폭을 760px로 지정하세요. npm run build 후 dist/index.html이 src/main.jsx 대신 assets 파일을 참조하는지 확인하세요.
아래는 완성본의 src/App.jsx입니다. ZIP에는 별도 HTML·CSS, 진입점, 필요한 자식 컴포넌트, 고정 패키지 버전과 테스트가 함께 들어 있습니다. starter는 미완성 동작을 수정하는 시작본이고 complete는 비교용 완성본입니다.
기대 결과: 제목 “React Vite 시작하기”, 설명 두 문단이 표시됩니다. 빌드에 HTML·JS·CSS가 포함됩니다. preview는 이미 생성한 dist를 확인합니다.
압축을 풀고 complete에서 npm install 후 npm run dev를 실행합니다. 빌드·검증은 별도 터미널에서 npm test, npm run build로 실행합니다. 자세한 시작본 과제와 파일 설명은 README에 있습니다.
실습의 공식 참고 문서
이 글이 도움이 되었나요?
React 학습 순서
필수 19개 · 전체 23개
읽음 기록 관리
전체 과정 목차 (23개)
- 필수 길잡이 · React 학습 순서: 컴포넌트·props·state부터 상태관리까지
- 필수 학습 · React Vite 사용법: Vite 8 프로젝트 생성·실행·빌드 현재 글
- 필수 학습 · React 컴포넌트 개념 정리: UI 재사용 구조 잡기
- 필수 학습 · React JSX 문법 사용법: 조건부 렌더링과 리스트 처리
- 필수 학습 · React props 사용법: 부모에서 자식으로 데이터 전달하는 구조
- 필수 학습 · React useState 사용법: state와 객체 배열 업데이트 기준
- 선택 참고 · React state 업데이트 안됨 문제 해결
- 필수 선수 · React 리스트 key 경고 해결 기준: index key를 피해야 하는 이유
- 필수 학습 · React 제어 컴포넌트 폼과 상태 끌어올리기 첫 실습 가이드
- 필수 학습 · React useRef 실습: 입력 포커스와 state의 역할 나누기
- 필수 선수 · React useEffect 두 번 실행되는 이유: StrictMode·API 중복 해결
- 선택 참고 · React Maximum update depth exceeded 오류 해결: 무한 렌더링 원인 찾기
- 선택 참고 · React Cannot update 오류 해결: 렌더링 중 setState 원인
- 필수 학습 · React useReducer와 Context 실습: 작업 목록 상태를 여러 컴포넌트에서 공유하기
- 필수 학습 · React 컴포넌트 props 타입 지정하기: 부모와 자식 사이의 값 구조 잡기
- 선택 참고 · React Hook Form 에러 메시지 표시 문제 해결: validation이 안 보일 때 체크리스트
- 필수 길잡이 · React 라이브러리 조합 가이드: Zustand·TanStack Query·shadcn/ui 선택 기준
- 필수 학습 · Next.js 커스텀 훅 설계: 프론트엔드 상태 관리 구조 잡기
- 필수 학습 · React Compiler 기준: useMemo useCallback 언제 줄일까
- 필수 학습 · React·TypeScript 검색 필터 만들기: 상태와 결과 목록 연결
- 필수 학습 · React Router v7 실습: BrowserRouter부터 Layout·Outlet·상세 경로까지
- 필수 학습 · shadcn/ui 시작 실습: Vite 설정·components.json·입력 폼·Sonner
- 필수 학습 · shadcn/ui 복합 컴포넌트 실습: Dialog·Popover·Carousel과 접근성
새 글 받아보기
RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.