워로디스

Tauri 시작하기 (Typescript + Vite + React) 본문

정리/Tauri

Tauri 시작하기 (Typescript + Vite + React)

워로디스 2026. 2. 24. 22:21

Vite + TypeScript + React + Tauri 조합은 현재 데스크톱 애플리케이션(특히 런처)을 개발할 때 가장 트렌디하고 강력한 정석적인 스택입니다. 프론트엔드의 빠른 개발 경험(Vite/React)과 백엔드의 압도적인 성능(Rust/Tauri)을 모두 챙길 수 있습니다.

 

Tauri v2를 기준으로 가장 심플하게 프로젝트를 생성하고, React에서 Rust로 데이터를 주고받는(IPC) 기본 구조를 완성하여 실행하는 단계는 다음과 같습니다.

 

0단계: 사전 준비 (Prerequisites)

 

이 과정이 매끄럽게 진행되려면 PC에 다음 두 가지가 설치되어 있어야 합니다.

  • Node.js: 프론트엔드 패키지 관리 (npm 사용)
  • Rust: 백엔드 컴파일 (rustup.rs를 통해 설치)
  • (Windows의 경우) Visual Studio C++ 빌드 도구 (Rust 컴파일용)

 

1단계: 프로젝트 스캐폴딩

 

Tauri는 공식 CLI 도구를 제공하므로, 빈 폴더에서 터미널을 열고 아래 명령어를 입력하면 Vite + React + TS 환경이 완벽하게 세팅된 보일러플레이트가 생성됩니다.

# 1. Tauri 앱 자동 생성 (이름: tauri-launcher, 템플릿: react-ts)
npm create tauri-app@latest tauri-launcher -- --manager npm --template react-ts

# 2. 생성된 폴더로 이동하여 패키지 설치
cd tauri-launcher
npm install

# 3. Tauri v2 API 패키지 설치 (프론트엔드에서 Rust를 호출하기 위함)
npm install @tauri-apps/api@latest

 

2단계: 핵심 소스 코드 이해 및 작성

 

프로젝트가 생성되면 프론트엔드(React)와 백엔드(Rust)가 나뉘어 있습니다. 런처의 핵심인 "React에서 입력을 받아 Rust로 전달하고 결과를 받는 과정"을 구성해 보겠습니다.

가. 백엔드 (Rust) 설정

경로: src-tauri/src/lib.rs

프론트엔드에서 호출할 수 있는 greet 함수를 만들고, Tauri 빌더에 등록합니다. (v2부터는 메인 로직을 lib.rs에 작성하는 것이 표준입니다.)

// React에서 호출할 수 있도록 #[tauri::command] 매크로를 붙여줍니다.
#[tauri::command]
fn greet(name: &str) -> String {
    format!("안녕하세요, {}님! Rust 백엔드에서 응답합니다.", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_shell::init())
        // 생성한 greet 함수를 핸들러에 등록합니다.
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("Tauri 애플리케이션 실행 중 오류가 발생했습니다.");
}

나. 프론트엔드 (React) 설정

경로: src/App.tsx

React 컴포넌트에서 @tauri-apps/api/core의 invoke 함수를 사용해 방금 만든 Rust의 greet 함수를 호출합니다.

import { useState } from "react";
import { invoke } from "@tauri-apps/api/core";
// 기본 생성된 App.css가 있다면 그대로 사용하셔도 됩니다.
import "./App.css";

function App() {
  const [name, setName] = useState("");
  const [greetMsg, setGreetMsg] = useState("");

  // Rust 함수를 호출하는 비동기 함수
  async function handleGreet() {
    try {
      // Rust의 "greet" 커맨드를 호출하고, 인자로 name을 전달합니다.
      const response = await invoke<string>("greet", { name });
      setGreetMsg(response);
    } catch (error) {
      console.error("Rust 호출 중 에러 발생:", error);
    }
  }

  return (
    <div style={{ textAlign: "center", padding: "50px", fontFamily: "sans-serif" }}>
      <h1>Tauri v2 런처 기본 앱</h1>
      <div style={{ marginTop: "20px" }}>
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.currentTarget.value)}
          placeholder="이름을 입력하세요..."
          style={{ padding: "10px", fontSize: "16px" }}
        />
        <button 
          onClick={handleGreet} 
          style={{ padding: "10px 20px", marginLeft: "10px", fontSize: "16px", cursor: "pointer" }}
        >
          Rust로 전송
        </button>
      </div>
      {greetMsg && (
        <p style={{ marginTop: "20px", fontSize: "18px", color: "blue" }}>
          {greetMsg}
        </p>
      )}
    </div>
  );
}

export default App;

 

3단계: 앱 실행 및 테스트

 

모든 코드가 준비되었습니다. 터미널에서 아래 명령어를 실행하면, 백엔드(Rust)가 컴파일된 후 네이티브 데스크톱 창에서 React UI가 렌더링됩니다.

npm run tauri dev
  • 참고: 최초 실행 시에는 Rust 패키지(Crate)들을 다운로드하고 컴파일하느라 시간이 조금 걸릴 수 있습니다. 두 번째 실행부터는 Vite의 HMR(Hot Module Replacement)이 적용되어 코드를 수정하자마자 앱에 즉각 반영됩니다.