💻 프로그래밍

Elysia

Bun을 위한 TypeScript 웹 프레임워크

📖 상세 설명

Elysia는 Bun 런타임에 최적화된 TypeScript 웹 프레임워크로, 타입 안전성과 극한의 성능을 동시에 추구합니다. 2023년에 등장하여 빠르게 성장하고 있으며, Express.js 대비 최대 18배 빠른 처리 속도를 자랑합니다.

Elysia의 가장 큰 특징은 End-to-End Type Safety입니다. 서버에서 정의한 API 스키마가 클라이언트까지 자동으로 타입이 추론되어, 프론트엔드와 백엔드 간의 타입 불일치 문제를 원천적으로 방지합니다. tRPC와 유사하지만 REST API 형태로 제공됩니다.

플러그인 시스템을 통해 기능을 모듈화하고 재사용할 수 있습니다. 공식 플러그인으로 Swagger 문서 자동 생성, JWT 인증, CORS 처리, GraphQL 통합 등이 제공되며, 커스텀 플러그인을 만들어 프로젝트 전반에 걸쳐 공통 로직을 쉽게 공유할 수 있습니다.

실무에서 Elysia는 고성능 API 서버, 마이크로서비스, 실시간 애플리케이션에 적합합니다. Bun의 네이티브 SQLite, 파일 I/O, 번들링 기능과 결합하면 별도의 도구 없이도 풀스택 애플리케이션을 빠르게 구축할 수 있습니다.

💻 코드 예제

// 1. 기본 Elysia 서버 설정
import { Elysia, t } from 'elysia';
import { swagger } from '@elysiajs/swagger';
import { jwt } from '@elysiajs/jwt';

// 사용자 타입 정의
interface User {
    id: number;
    name: string;
    email: string;
}

const users: User[] = [];

const app = new Elysia()
    // Swagger 문서 자동 생성
    .use(swagger({
        documentation: {
            info: { title: 'Elysia API', version: '1.0.0' }
        }
    }))
    // JWT 인증 플러그인
    .use(jwt({
        name: 'jwt',
        secret: process.env.JWT_SECRET || 'super-secret-key'
    }))
    // 전역 에러 핸들러
    .onError(({ code, error }) => {
        console.error(`[${code}] ${error.message}`);
        return { error: error.message };
    });

// 2. CRUD API 라우트 정의 (타입 안전)
app.group('/api/users', (app) =>
    app
        // 사용자 목록 조회
        .get('/', () => users, {
            detail: { summary: '모든 사용자 조회' }
        })
        // 사용자 생성 (입력 검증 포함)
        .post('/', ({ body }) => {
            const newUser: User = {
                id: users.length + 1,
                ...body
            };
            users.push(newUser);
            return newUser;
        }, {
            body: t.Object({
                name: t.String({ minLength: 2 }),
                email: t.String({ format: 'email' })
            }),
            detail: { summary: '새 사용자 생성' }
        })
        // 특정 사용자 조회
        .get('/:id', ({ params: { id }, error }) => {
            const user = users.find(u => u.id === Number(id));
            if (!user) return error(404, '사용자를 찾을 수 없습니다');
            return user;
        })
);

// 3. 서버 시작
app.listen(3000, () => {
    console.log('🦊 Elysia 서버가 http://localhost:3000 에서 실행 중');
    console.log('📖 Swagger 문서: http://localhost:3000/swagger');
});

🗣️ 실무에서 이렇게 말하세요

💬 회의에서
"이번 마이크로서비스는 Elysia로 구축하는 게 좋겠습니다. Bun 런타임의 성능과 End-to-End 타입 안전성 덕분에 프론트엔드 팀과의 API 스펙 싱크 문제를 줄일 수 있어요. Swagger 문서도 자동 생성됩니다."
💬 면접에서
"Elysia는 Express.js나 Fastify와 달리 Bun에 최적화되어 있고, TypeBox 기반의 런타임 스키마 검증과 컴파일 타임 타입 추론을 동시에 지원합니다. 플러그인 시스템으로 인증, 로깅 같은 공통 기능을 깔끔하게 분리할 수 있어요."
💬 코드 리뷰에서
"body 스키마에 t.Object를 사용한 건 좋은데, 여기 선택적 필드는 t.Optional()로 감싸주세요. 그리고 에러 응답도 일관된 형식으로 통일하면 프론트엔드에서 핸들링하기 편해질 거예요."

⚠️ 흔한 실수 & 주의사항

Node.js에서 실행하려는 시도

Elysia는 Bun 전용 프레임워크입니다. Node.js에서는 실행되지 않으므로, 반드시 `bun run` 또는 `bun dev`로 실행하세요. 기존 Node.js 프로젝트 마이그레이션 시 의존성 호환성을 먼저 확인해야 합니다.

스키마 없이 body 접근

body 스키마를 정의하지 않고 요청 본문에 접근하면 타입 안전성을 잃습니다. 항상 t.Object()로 스키마를 정의하고, 필수/선택 필드를 명확히 구분하세요.

플러그인으로 공통 로직 분리

.use()와 .derive()를 활용해 인증, 로깅, 에러 핸들링 같은 공통 로직을 플러그인으로 분리하세요. 코드 재사용성이 높아지고 테스트가 쉬워집니다.

🔗 관련 용어

📚 더 배우기