💻 프로그래밍

Deno

Deno

Node.js 창시자가 만든 JS/TS 런타임. 보안과 TypeScript 기본 지원.

📖 상세 설명

Deno는 2018년 Ryan Dahl이 JSConf EU에서 "Node.js에 대해 후회하는 10가지"라는 발표와 함께 공개한 JavaScript/TypeScript 런타임입니다. Node.js의 설계 결함을 해결하고자 Rust로 처음부터 다시 만들었으며, V8 엔진을 사용하여 JavaScript를 실행합니다.

Deno의 가장 큰 특징은 보안 기본 적용(Secure by Default)입니다. 파일 시스템, 네트워크, 환경 변수 접근에 명시적인 권한 플래그(--allow-read, --allow-net 등)가 필요하며, 이는 악성 패키지로부터 시스템을 보호합니다.

TypeScript를 별도 설정 없이 네이티브로 지원하며, URL 기반 모듈 임포트로 package.json과 node_modules 없이 의존성을 관리합니다. 내장된 포매터(deno fmt), 린터(deno lint), 테스트 러너(deno test)로 개발 환경 설정이 간소화됩니다.

Deno Deploy는 전 세계 35개 이상의 엣지 로케이션에서 Deno 애플리케이션을 실행하는 서버리스 플랫폼입니다. Fresh 프레임워크와 함께 사용하면 제로 JS 번들로 빠른 웹 애플리케이션을 구축할 수 있으며, 2024년부터는 npm 패키지 호환성도 크게 개선되었습니다.

💻 코드 예제

// 1. HTTP 서버 (Deno.serve - 권장 방식)
Deno.serve({ port: 8000 }, (req: Request) => {
    const url = new URL(req.url);

    if (url.pathname === "/api/hello") {
        return Response.json({ message: "안녕하세요, Deno!" });
    }

    return new Response("Welcome to Deno", {
        headers: { "content-type": "text/plain" },
    });
});
// 실행: deno run --allow-net server.ts

// 2. 파일 읽기/쓰기 (권한 필요)
async function processFile() {
    // 파일 읽기 (--allow-read 필요)
    const content = await Deno.readTextFile("./data.json");
    const data = JSON.parse(content);

    // 데이터 처리
    data.updatedAt = new Date().toISOString();

    // 파일 쓰기 (--allow-write 필요)
    await Deno.writeTextFile(
        "./output.json",
        JSON.stringify(data, null, 2)
    );
    console.log("파일 처리 완료!");
}

// 3. URL 기반 모듈 임포트
import { serve } from "https://deno.land/std@0.220.0/http/server.ts";
import { assertEquals } from "https://deno.land/std@0.220.0/assert/mod.ts";

// npm 패키지도 사용 가능 (Deno 1.28+)
import express from "npm:express@4";
import chalk from "npm:chalk@5";

// 4. Deno KV (내장 키-값 저장소)
const kv = await Deno.openKv();

// 데이터 저장
await kv.set(["users", "user123"], {
    name: "홍길동",
    email: "hong@example.com"
});

// 데이터 조회
const result = await kv.get(["users", "user123"]);
console.log(result.value); // { name: "홍길동", ... }

// 5. 테스트 (deno test로 실행)
Deno.test("덧셈 테스트", () => {
    assertEquals(1 + 2, 3);
});

Deno.test("비동기 테스트", async () => {
    const response = await fetch("https://api.example.com/health");
    assertEquals(response.status, 200);
});

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

💬 회의에서
"이번 마이크로서비스는 Deno로 구축하면 좋겠습니다. TypeScript 설정 없이 바로 쓸 수 있고, 보안 권한 시스템으로 서드파티 패키지의 무단 파일/네트워크 접근을 차단할 수 있어요. Deno Deploy로 배포하면 콜드 스타트도 50ms 이하입니다."
💬 면접에서
"Deno는 Node.js와 달리 보안이 기본으로 활성화되어 있습니다. 네트워크 접근은 --allow-net, 파일 읽기는 --allow-read처럼 명시적으로 권한을 부여해야 합니다. 또한 URL 기반 모듈 시스템으로 node_modules 없이 의존성을 관리하며, deno.lock으로 버전을 고정합니다."
💬 코드 리뷰에서
"이 스크립트 실행할 때 --allow-all 대신 필요한 권한만 명시해주세요. --allow-read=./data --allow-net=api.example.com 이렇게 경로와 호스트를 지정하면 더 안전합니다. 그리고 deno.json에 import map 설정하면 URL 임포트를 깔끔하게 관리할 수 있어요."

⚠️ 흔한 실수 & 주의사항

--allow-all 남용하지 않기

개발 편의상 --allow-all을 쓰기 쉽지만, Deno의 보안 이점이 사라집니다. 프로덕션에서는 반드시 --allow-read, --allow-net 등 필요한 권한만 최소한으로 부여하세요.

URL 임포트 버전 고정하기

https://deno.land/x/module/mod.ts처럼 버전 없이 임포트하면 예기치 않은 업데이트가 발생합니다. 항상 @0.1.0 같이 버전을 명시하고, deno.lock 파일을 커밋하세요.

npm 호환성 활용하기

Deno 1.28부터 npm:패키지명으로 npm 패키지를 직접 사용할 수 있습니다. Express, Prisma 등 기존 Node.js 생태계를 Deno에서도 활용하세요. package.json도 지원됩니다.

🔗 관련 용어

📚 더 배우기