コンテンツにスキップ

GoがバックエンドでNodeを侵食している理由:標準ライブラリの強さ

概要

Go が Node.js を凌ぐ理由は「ベンチマーク」より「バックエンド開発の体験」にある。標準ライブラリの充実度が決定的な差を生んでいる。

詳細

Node.js の問題:最初の選択の嵐

Node.js プロジェクト開始時の意思決定:
  □ フレームワーク: Express? Fastify? NestJS? Hono?
  □ ロガー: Winston? Pino? Bunyan?
  □ バリデーション: Zod? Joi? class-validator?
  □ テストフレームワーク: Jest? Vitest? Mocha?
  □ ORM: Prisma? TypeORM? Drizzle?

→ 選択疲れ + ライブラリの組み合わせ問題 + メンテナンス負担

Go の強さ:標準ライブラリで大半が完結する

// HTTP サーバー → net/http だけで十分
package main

import (
    "encoding/json"  // JSON シリアライズ
    "log/slog"       // 構造化ログ(Go 1.21+)
    "net/http"       // HTTP サーバー
    "testing"        // テスト
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("GET /users/{id}", handleGetUser)
    http.ListenAndServe(":8080", mux)
}

Go 1.22 以降、net/httpGET /path/{param} パターンマッチングをサポートし、軽量ルーター不要になった。

標準ライブラリの対応範囲

機能 Go (stdlib) Node.js (要追加パッケージ)
HTTP サーバー net/http Express, Fastify 等
JSON encoding/json 組み込み JSON
テスト testing Jest, Vitest 等
構造化ログ log/slog (1.21+) winston, pino 等
並行処理 goroutine, channel Promise, async/await
HTTP クライアント net/http axios, fetch
環境変数 os.Getenv dotenv 等

ベンチマーク以外の実質的なメリット

1. コンパイル = 型チェック → ランタイムエラーが大幅に減る
2. バイナリが単一ファイル → Docker イメージが小さい(scratch ベースで数MB)
3. goroutine → 10万接続を数百MBのメモリで捌ける
4. 標準ライブラリの後方互換性保証 → ライブラリが突然壊れない

なぜ重要か / いつ使うか

  • 「Go と Node どちらを使うべきか」の技術選定判断
  • 高並行・低メモリのバックエンド API が必要なとき
  • マイクロサービスのコンテナサイズを小さく保ちたいとき