Skip to content
Published on

Rust 생태계 투어: 멋진 크레이트와 프로젝트들

Authors

들어가며 — 언어보다 생태계

Rust를 이야기할 때 우리는 흔히 소유권, 빌림 검사기, 메모리 안전성 같은 언어의 특징을 먼저 떠올립니다. 하지만 어떤 언어가 실무에서 쓸 만한지를 결정하는 것은 언어 문법만이 아닙니다. 필요한 일을 이미 잘 해내는 라이브러리가 있는가, 그것을 얼마나 쉽게 가져다 쓰는가, 곧 생태계의 성숙도가 핵심입니다.

Rust는 이 점에서 지난 몇 년간 극적으로 성장했습니다. 2015년 1.0 출시 이후 crates.io에는 수십만 개의 크레이트가 쌓였고, 그 가운데 몇몇은 각 분야의 사실상 표준이 되었습니다. 이 글은 그 대표 크레이트와 유명 프로젝트들을 한 바퀴 도는 지도입니다. 각 크레이트가 "무엇을 위한 것인지"에 초점을 맞추므로, Rust로 무언가를 시작할 때 어디를 봐야 할지 감을 잡는 데 도움이 될 것입니다.

cargo와 crates.io — 생태계의 토대

크레이트 이야기를 하기 전에, 그것을 가능하게 하는 토대부터 짚어야 합니다. Rust의 생태계가 빠르게 성숙한 데에는 처음부터 잘 만들어진 도구 체계가 큰 몫을 했습니다.

cargo는 Rust의 공식 빌드 도구이자 패키지 매니저입니다. 프로젝트 생성(cargo new), 빌드(cargo build), 테스트(cargo test), 실행(cargo run), 의존성 관리를 하나의 일관된 명령으로 처리합니다. 다른 언어에서 빌드 도구와 패키지 매니저, 포매터, 테스트 러너가 제각각인 상황과 대비하면, 하나로 통합된 경험은 진입 장벽을 크게 낮춥니다.

crates.io는 공개 크레이트 레지스트리입니다. Cargo.toml에 크레이트 이름과 버전만 적으면 cargo가 알아서 내려받아 빌드합니다. 여기에 시맨틱 버저닝과 잠금 파일(Cargo.lock)이 결합되어, 재현 가능한 빌드가 기본으로 보장됩니다.

[dependencies]
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }

이 단순한 선언 하나로 라이브러리와 그 하위 의존성 전체가 딸려 옵니다. 아래에서 소개할 모든 크레이트는 결국 이 두 도구 위에 얹혀 있습니다.

기초 크레이트 — serde와 tokio

Rust 프로젝트를 열어 보면 거의 항상 등장하는 두 크레이트가 있습니다. 생태계의 바닥을 떠받치는 기둥이라 할 만합니다.

serde는 직렬화/역직렬화 프레임워크입니다. 구조체에 파생 매크로를 붙이는 것만으로 JSON, YAML, TOML, MessagePack 등 수많은 포맷과 상호 변환됩니다. 핵심 설계는 "데이터 모델"과 "포맷"을 분리한 것으로, 같은 타입을 여러 포맷으로 다룰 수 있게 해 줍니다.

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Config {
    name: String,
    port: u16,
}

// 이제 이 타입은 JSON, YAML, TOML 등과 자유롭게 오간다
let cfg: Config = serde_json::from_str(r#"{"name":"web","port":8080}"#)?;

tokio는 Rust의 비동기 런타임입니다. Rust는 async/await 문법을 언어에 두되, 실제로 그 태스크를 스케줄링하고 실행하는 런타임은 라이브러리에 맡깁니다. tokio는 그 런타임의 사실상 표준으로, 비동기 태스크 스케줄러, 논블로킹 I/O, 타이머, 채널 등을 제공합니다. 아래에서 볼 네트워크·웹·DB 크레이트 상당수가 tokio 위에서 돕니다.

#[tokio::main]
async fn main() {
    let handle = tokio::spawn(async {
        // 동시에 실행되는 비동기 태스크
        "done"
    });
    println!("{}", handle.await.unwrap());
}

병렬성과 데이터 — rayon과 polars

Rust의 강점 중 하나는 "겁 없는 동시성(fearless concurrency)"입니다. 타입 시스템이 데이터 레이스를 컴파일 타임에 막아 주므로, 병렬 코드를 훨씬 안심하고 쓸 수 있습니다. 이 강점을 가장 잘 보여 주는 크레이트가 rayon입니다.

rayon은 데이터 병렬성(data parallelism) 라이브러리입니다. 놀라운 점은 사용법의 단순함입니다. 순차 반복자(iter)를 병렬 반복자(par_iter)로 바꾸는 것만으로, 컬렉션 처리가 여러 코어에 자동 분산됩니다.

use rayon::prelude::*;

// iter() -> par_iter() 한 글자 차이로 병렬 처리
let sum: u64 = (0..1_000_000)
    .into_par_iter()
    .filter(|n| n % 3 == 0)
    .map(|n| n as u64)
    .sum();

내부적으로는 작업 훔치기(work-stealing) 스케줄러가 부하를 코어에 고르게 나눕니다. 병렬화의 정확성은 Rust의 타입 시스템이 보장하므로, 데이터 레이스 걱정 없이 성능만 챙기면 됩니다.

polars는 고성능 데이터프레임 라이브러리입니다. 파이썬의 pandas에 대응하는 위치인데, Apache Arrow 기반의 컬럼 지향 저장과 지연 실행(lazy evaluation), 쿼리 최적화를 결합해 대용량 데이터에서 매우 빠릅니다. Rust에서 직접 쓸 수도 있고, 파이썬 바인딩으로도 널리 쓰여 데이터 분석 진영에서 점점 존재감을 키우고 있습니다.

네트워크와 웹 — reqwest, hyper, axum

웹은 어느 언어에서나 큰 영역이고, Rust에는 이 계층이 잘 정돈되어 있습니다.

hyper는 저수준 HTTP 라이브러리입니다. HTTP/1과 HTTP/2를 정확하고 빠르게 구현한 토대로, 클라이언트와 서버 양쪽을 모두 지원합니다. 직접 쓰기에는 저수준이지만, 아래의 상위 크레이트들이 hyper 위에 얹혀 있습니다.

reqwest는 hyper를 감싼 사용하기 편한 HTTP 클라이언트입니다. JSON 요청/응답, 쿠키, 리다이렉트, TLS를 간결한 API로 다룹니다. "다른 서비스의 API를 호출한다"는 일상적 작업에 가장 먼저 손이 가는 크레이트입니다.

let body: serde_json::Value = reqwest::get("https://api.example.com/status")
    .await?
    .json()
    .await?;

axum은 tokio 팀이 만든 웹 프레임워크입니다. hyper와 tower(미들웨어 추상화) 위에 세워졌고, 라우팅과 요청 파싱을 타입 안전한 "추출자(extractor)" 방식으로 표현합니다. 매크로에 의존하지 않고 평범한 함수와 타입으로 핸들러를 짜는 설계가 특징입니다.

use axum::{routing::get, Router};

async fn hello() -> &'static str {
    "Hello, world!"
}

let app = Router::new().route("/", get(hello));

데이터베이스와 CLI — sqlx, diesel, clap

애플리케이션이라면 대개 데이터베이스와 명령줄 인터페이스가 필요합니다. Rust에는 이 둘을 위한 성숙한 선택지가 있습니다.

데이터베이스 접근에는 대표적으로 두 갈래가 있습니다. sqlx는 비동기 SQL 툴킷으로, 흥미롭게도 컴파일 타임에 SQL 쿼리를 실제 데이터베이스 스키마와 대조해 검사합니다. 즉 잘못된 컬럼명이나 타입 불일치를 빌드 단계에서 잡습니다. 반면 diesel은 완전한 ORM이자 쿼리 빌더로, Rust 코드로 타입 안전하게 쿼리를 조립합니다. sqlx는 SQL을 직접 쓰되 검증을 원할 때, diesel은 ORM 스타일의 추상화를 원할 때 어울립니다.

clap(Command Line Argument Parser)은 명령줄 인자 파싱의 사실상 표준입니다. 구조체에 파생 매크로를 붙이면, 인자 정의로부터 파서와 도움말, 하위 명령까지 자동으로 만들어 줍니다.

use clap::Parser;

#[derive(Parser)]
struct Cli {
    /// 처리할 입력 파일
    path: String,
    /// 상세 출력 여부
    #[arg(short, long)]
    verbose: bool,
}

let cli = Cli::parse(); // --help도 자동 생성된다

그래픽스와 앱 — Bevy, wgpu, Tauri

Rust는 시스템 언어답게 그래픽스와 응용 프로그램 영역에서도 흥미로운 프로젝트들을 낳았습니다.

wgpu는 크로스 플랫폼 그래픽스 API입니다. 브라우저 표준인 WebGPU를 기반으로, 그 뒤에서 Vulkan, Metal, DirectX 12 같은 각 플랫폼의 네이티브 그래픽스 백엔드로 이어집니다. 하나의 코드로 여러 플랫폼의 GPU를 다룰 수 있게 해 주는 이식성이 강점입니다.

Bevy는 Rust로 쓰인 게임 엔진입니다. ECS(Entity Component System) 아키텍처를 전면에 내세운 것이 특징으로, 데이터 지향 설계와 Rust의 병렬성이 잘 맞물립니다. 오픈 소스이고 활발히 개발되며, 게임뿐 아니라 시뮬레이션이나 인터랙티브 애플리케이션에도 쓰입니다.

Tauri는 데스크톱(및 모바일) 앱을 만드는 프레임워크입니다. Electron과 목적은 비슷하지만 접근이 다릅니다. Electron이 크롬 브라우저 전체를 앱마다 번들하는 반면, Tauri는 운영체제가 제공하는 시스템 웹뷰를 쓰고 백엔드를 Rust로 둡니다. 그 결과 바이너리 크기와 메모리 사용이 훨씬 작습니다. 프론트엔드는 익숙한 웹 기술로 짜고, 무거운 로직과 시스템 접근은 Rust가 맡는 구조입니다.

유명 프로젝트들 — Rust가 세상에 남긴 것

크레이트가 부품이라면, 그 부품으로 만들어진 완성품도 Rust의 위상을 잘 보여 줍니다. 몇 가지 널리 알려진 프로젝트를 봅시다.

  • ripgrep(rg): Rust로 쓰인 초고속 코드 검색 도구입니다. 정규식 엔진과 병렬 순회, .gitignore 인식을 결합해 대규모 코드베이스에서 놀라운 속도를 냅니다. 많은 개발자가 grep을 대체해 일상적으로 쓰며, VS Code의 검색 기능도 내부적으로 ripgrep을 씁니다.
  • Deno: Node.js의 창시자가 만든 자바스크립트/타입스크립트 런타임입니다. 코어는 Rust로 작성되었고 V8 엔진을 품습니다. 기본 보안(권한 모델), 타입스크립트 기본 지원 등을 내세웁니다.
  • Firecracker: AWS가 만든 경량 가상화 기술(microVM)입니다. Rust로 쓰였고, 서버리스(AWS Lambda)와 컨테이너 서비스의 격리 기반으로 쓰입니다. 수십 밀리초 만에 뜨는 가벼운 VM으로, 보안 격리와 빠른 기동을 동시에 노립니다.
  • 리눅스 커널의 Rust 지원: 2022년 리눅스 6.1부터 커널에 Rust를 쓸 수 있는 기반이 병합되었습니다. 수십 년간 C가 지배해 온 영역에 Rust가 들어간 상징적 사건으로, 주로 새 드라이버 등에서 메모리 안전성을 얻으려는 시도입니다.

이 밖에도 Firefox의 여러 구성 요소, 패키지 도구, 웹 서버, 블록체인, 임베디드 등 수많은 분야에서 Rust가 쓰입니다. 공통점은 "성능과 안전성이 동시에 중요한 곳"에서 특히 강하다는 것입니다.

직접 다뤄 보기

여기까지 훑어본 크레이트와 프로젝트는 결국 Rust라는 언어의 토대 위에 서 있습니다. 소유권, 트레이트, 열거형 같은 개념을 손에 익히면 이 생태계가 왜 이런 모양인지가 더 잘 보입니다. Rust의 핵심 개념을 직접 코드로 실험해 보고 싶다면 이 사이트의 Rust 학습 랩에서 다뤄 볼 수 있습니다. 또 Rust는 WebAssembly 진영의 주력 언어이기도 한데, wgpu가 WebGPU를 기반으로 삼는 것처럼 웹은 Rust의 중요한 무대입니다. WebAssembly가 어떻게 동작하는지 궁금하다면 WebAssembly 원리에서 그 구조를 살펴볼 수 있습니다.

마치며

Rust의 힘은 언어 하나에 그치지 않습니다. cargo와 crates.io라는 잘 만들어진 토대 위에, serde와 tokio 같은 기초 크레이트, rayon과 polars 같은 데이터·병렬 도구, reqwest·hyper·axum으로 이어지는 웹 계층, sqlx·diesel·clap 같은 애플리케이션 부품, 그리고 Bevy·wgpu·Tauri 같은 그래픽스와 앱 프레임워크가 층층이 쌓여 있습니다.

그리고 그 부품들로 ripgrep, Deno, Firecracker 같은 실제 도구가 만들어졌고, 마침내 리눅스 커널에까지 Rust가 발을 들였습니다. 이 모든 것을 관통하는 공통점은, Rust가 "빠르면서도 안전한" 코드를 원하는 자리에서 특히 빛난다는 사실입니다.

새로 무언가를 시작할 때, 이 지도가 어디를 먼저 봐야 할지 알려 주는 이정표가 되길 바랍니다. 필요한 크레이트는 대체로 이미 존재하고, cargo 한 줄이면 손에 들어옵니다.

참고 자료