Blazor vs React: .NET 개발자의 솔직한 비교

발행: (2025년 12월 7일 오후 12:40 GMT+9)
11 min read
원문: Dev.to

Source: Dev.to

Blazor란 무엇인가?

Blazor는 JavaScript 대신 C#를 사용해 인터랙티브 웹 UI를 구축할 수 있게 해 주는 Microsoft의 프레임워크입니다. 이름은 BrowserRazor( .NET 템플릿 구문)의 합성어이며, 2020년부터 프로덕션 수준으로 사용 가능합니다.

핵심 아이디어는 C# 코드를 다음 중 하나로 실행한다는 것입니다:

  • 서버에서 실행 (Blazor Server) – C#이 서버에서 실행되고 UI 업데이트가 SignalR WebSocket 연결을 통해 실시간으로 브라우저에 전달됩니다.
  • 브라우저에서 실행 (Blazor WebAssembly) – .NET 런타임 자체가 WebAssembly를 통해 브라우저에서 실행됩니다. 실제로 컴파일된 .NET 코드가 브라우저 안에서 동작합니다.
  • 둘 다 (Blazor United/.NET 8+) – 컴포넌트별로 렌더링 모드를 선택합니다. 초기 로드 속도는 서버‑사이드, 오프라인 기능은 WebAssembly. 두 세계의 장점을 모두 누릴 수 있습니다.
// A Blazor component. Yes, that's C# in your UI.
@page "/counter"

<h2>Counter</h2>

<p>Current count: @currentCount</p>

<button @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

그게 전부입니다. webpack도, Babel도, 수십 개의 설정 파일도 없습니다. 그냥 컴파일되고 실행되는 C#만 있으면 됩니다.

React에 대한 비판

React는 괜찮습니다. 컴포넌트 기반 UI를 혁신했고, Virtual DOM은 정말 영리했습니다. Facebook이 사용하고 있고, 그들 역시 괜찮아 보입니다.

하지만 수년간 프로덕션 React 애플리케이션을 구축하면서, 제 선택을 의심하게 만드는 패턴들을 발견했습니다:

  • 끊임없이 변하는 생태계 – 매년 새로운 “올바른 방법”이 등장합니다.
연도최신 상태 관리
2016Redux (당연히)
2018MobX (Redux가 너무 장황!)
2020Context API (라이브러리 필요 없나요?)
2021Zustand (Context는 확장 안 돼!)
2022Jotai, Recoil, Valtio…
2024Server Components (상태가 거짓인가?)
  • 도구 과부하 – 새로운 React 프로젝트를 시작하면 번들러, 상태 관리 라이브러리, 스타일링 솔루션, 데이터 패칭 도구, 폼 라이브러리, 메타‑프레임워크 등 수십 가지를 선택해야 비즈니스 로직을 작성할 수 있습니다.

  • TypeScript 한계 – TypeScript는 동적 타입 언어 위에 얹은 임시방편에 불과합니다. 타입은 컴파일 타임 제안일 뿐이며, 런타임 검증은 여전히 수동입니다.

// TypeScript: Types are suggestions, really
const user: User = JSON.parse(response); // No runtime validation!
// Meanwhile, in C#:
var user = JsonSerializer.Deserialize(response); // Actual deserialization with type checking
  • node_modules 보안 위험 – 거대한 의존성 트리와 자원봉사 유지보수자 모델 때문에 npm 생태계는 공급망 공격에 취약합니다.

npm 재난 사건 베스트

사건연도영향
left‑pad2016한 개발자가 11줄짜리 패키지를 삭제했습니다. Babel, React, 수천 개 프로젝트가 즉시 깨졌습니다.
event‑stream2018“도움을 주는” 새 유지보수자가 악성 코드를 삽입했습니다. 2.5개월간 탐지되지 않았으며, 비트코인 지갑을 표적으로 삼았습니다.
ua‑parser‑js2021주당 800만 다운로드. 암호화 채굴기와 비밀번호 탈취기를 설치하도록 손상되었습니다.
everything2024모든 npm 패키지를 의존하도록 만든 “농담” 패키지. 설치하는 사람을 DOS 공격했습니다.
Shai‑Hulud2025주당 26억+ 다운로드에 영향을 미쳤습니다. AI‑보조 공격 및 데이터 파괴 페이로드가 포함되었습니다.

왜 계속 발생할까

  • 방대한 의존성 트리 – 일반적인 React 앱은 수백 개의 전이 의존성을 가지고 있으며, 각각이 공격 표면이 됩니다.
  • 자원봉사 유지보수자 – 핵심 인프라가 무보수 개인에 의해 관리되다 보니 피싱이나 사회공학에 노출됩니다.
  • 빌드‑타임 검증 부재 – npm은 package.json에 적힌 대로 설치할 뿐, 컴파일 타임 안전 검사를 하지 않습니다.
  • 사소한 패키지 – 생태계가 is‑odd?, is‑even? 같은 작은 유틸리티에 의존하는 것을 정상화하면서 전체 공격 표면이 커집니다.

“단순한” React 프로젝트에서 실제 npm 감사를 실행한 결과:

found 47 vulnerabilities (12 moderate, 28 high, 7 critical)

코드 비교: React vs Blazor

React (hooks 사용)

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h2>Counter</h2>
      <p>Current count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

Blazor

@page "/counter"

<h2>Counter</h2>

<p>Current count: @count</p>

<button @onclick="() => count++">Click me</button>

@code {
    private int count = 0;
}

두 예제는 라인 수가 비슷하지만, Blazor 버전은 import도, useState 훅도, 별도의 setter 함수도 없습니다. 단순히 변수와 증감만 있죠.

Blazor가 나에게 맞는 이유

  • npm audit 악몽 제로dotnet list package --vulnerable는 보통 결과가 없습니다.
  • 서명된 패키지 – NuGet 패키지는 암호학적으로 서명될 수 있습니다.
  • 선별된 생태계 – 전체 패키지는 적지만 평균 품질은 높습니다.
  • Microsoft 지원 – 핵심 라이브러리는 수조 달러 규모 기업이 유지합니다.
  • 컴파일‑타임 안전성 – C# 컴파일러가 런타임 이전에 많은 문제를 잡아줍니다.
  • 작은 의존성 그래프 – .NET의 포괄적인 표준 라이브러리 덕분에 외부 패키지 필요성이 줄어듭니다.

Blazor의 진화: .NET 8, 9, 10

  • .NET 8Blazor United를 도입해 컴포넌트별 렌더링 모드 선택을 가능하게 했습니다 (Server vs WebAssembly).
  • .NET 9 – 더 빠른 UI 반복을 위한 Hot Reload가 개선되었습니다.
  • .NET 10 (프리뷰) – MAUI와의 tighter integration 및 WebAssembly의 네이티브 수준 성능을 약속합니다.

React가 아직도 의미가 있는 경우

  • 방대한 기존 JavaScript 생태계나 아직 Blazor로 포팅되지 않은 서드‑파티 React 컴포넌트가 필요한 프로젝트.
  • JavaScript 전문성이 깊고 C# 경험이 부족한 팀.
  • 클라이언트‑사이드 전용 렌더링이 필수이며, 브라우저에 .NET 런타임을 올리는 오버헤드를 감당할 수 없는 상황.

Blazor 시작하기

  1. .NET SDK 설치 (≥ 8.0).

  2. 새 프로젝트 생성:

    dotnet new blazorwasm -o MyBlazorApp
  3. 앱 실행:

    cd MyBlazorApp
    dotnet run
  4. 브라우저에서 https://localhost:5001을 열고 기본 템플릿을 살펴보세요.

  5. .razor 파일(예: Counter.razor)을 만들어 앞서 본 컴포넌트 패턴을 따라 새 페이지를 추가합니다.

FAQ: 흔히 묻는 질문들

Q: Razor 구문을 배워야 하나요?
A: 네, 하지만 HTML에 C# 코드 블록을 추가한 자연스러운 확장이라 C#에 익숙하다면 학습 곡선이 얕습니다.

Q: 성능은 어떻게 비교되나요?
A: Blazor WebAssembly 시작은 순수 JS 번들보다 약간 느리지만, 로드된 뒤 런타임 성능은 비슷합니다. Blazor Server는 최소한의 클라이언트 페이로드로 거의 즉시 UI 업데이트를 제공합니다.

Q: 기존 JavaScript 라이브러리를 사용할 수 있나요?
A: 물론입니다. Blazor는 IJSRuntime을 통한 JavaScript interop을 제공해 필요할 때 언제든 JS 라이브러리를 호출할 수 있습니다.

Q: SEO는 어떻게 되나요?
A: 서버‑사이드 렌더링(Blazor Server 또는 사전 렌더링된 WebAssembly)으로 크롤러에 완전한 HTML을 전달해 SEO가 향상됩니다.

마무리 생각

React에서 Blazor로 전환하면서 단일 언어 스택을 갖게 되었고, 의존성 관련 보안 문제를 크게 줄였으며, 개발 워크플로우가 간소화되었습니다. React는 여전히 강력한 도구이며, 특히 JavaScript 중심 생태계에 묶여 있을 때 유용합니다. 하지만 .NET 개발자가 tighter integration, 컴파일‑타임 안전성, 더 예측 가능한 의존성 그래프를 원한다면 Blazor는 매력적인 대안이 됩니다.

Back to Blog

관련 글

더 보기 »