1. はじめに
「npm run serve の裏では何が動いているのか?」
フロントエンドやバックエンドの開発をしていると、当たり前のように npm run serve や npm run dev といったコマンドを実行します。
エラーが出なければブラウザが立ち上がり、開発サーバーが動き出すので、特に深く考えずに使っている人も多いのではないでしょうか。
ですが、よく考えてみると「このコマンドの裏側で実際にコードを実行している仕組みは何なのか?」という疑問が出てきます。
npm がスクリプトを呼び出しているのは分かるけれど、実際に JavaScript を解釈して動かしている基盤 については、意識されないことが多いのです。
実は、この「本当に動かしている存在」こそが JavaScriptランタイム と呼ばれるものです。
この記事では、まず「ランタイム」とは何かを明確にし、Node.js だけでなく Deno や Bun といった新しいランタイムがどのような位置づけにあるのかを整理します。
さらに、日常で使っている npm run の裏側にランタイムがどのように関わっているのかを知ることで、開発環境をより深く理解できるようになるはずです。
2. JavaScriptランタイムとは?
ランタイムの定義
「ランタイム」とは、JavaScript(やTypeScript)を実際に解釈・実行する環境 のことを指します。
ソースコードを理解し、メモリを管理し、I/Oを扱い、結果を返すためには「実行基盤」が必要です。この実行基盤こそがランタイムです。
言い換えると、ランタイムは 「JavaScriptを動かすエンジン + 標準的なAPI群」 の組み合わせであり、アプリケーションが動作するための土台となります。
ブラウザ内ランタイム vs ブラウザ外ランタイム
JavaScriptランタイムには大きく分けて2つの種類があります。
-
ブラウザ内ランタイム
例:Chrome(V8)、Firefox(SpiderMonkey)、Safari(JavaScriptCore)
ブラウザには JavaScript エンジンが組み込まれており、DOM やfetch、localStorageなどのブラウザAPIとセットで実行されます。Webページのインタラクションや描画処理は、すべてこの「ブラウザ内ランタイム」で動いています -
ブラウザ外ランタイム
例:Node.js、Deno、Bun
ブラウザを介さずに OS 上で直接 JavaScript を動かすための環境です。ファイル操作やサーバー通信、CLIツールの構築など、Webページ以外の用途に利用できます
このブラウザ外ランタイムにより、JavaScript は「フロントエンド専用の言語」から「サーバーサイドや開発ツールにも使える汎用言語」へと大きく進化しました。
Node.js / Deno / Bun の共通点と違い
ここで代表的な 3 つのブラウザ外ランタイムを整理します。
| 項目 | Node.js | Deno | Bun |
|---|---|---|---|
| リリース年 | 2009 | 2020 | 2022 |
| エンジン | V8 | V8 | JavaScriptCore (Safariと同じ) |
| 言語対応 | JS, (TSはトランスパイル) | JS/TS標準対応 | JS/TS標準対応 |
| パッケージ管理 | npm (別途) | URL import, 独自モジュール管理 | npm互換 + 内蔵 |
| 主要特徴 | 豊富なエコシステム(npm) | 安全設計(権限制御)、TS標準 | 高速起動、バンドラ/テスト/パッケージマネージャ内蔵 |
| ユースケース | サーバーアプリ、CLI、Webサービス全般 | セキュアなサーバーやスクリプト | 高速実行、統合開発環境的利用 |
これらに共通しているのは「JavaScript/TypeScript をブラウザ外で動かす」という目的です。
一方で、それぞれが抱えていた課題や狙いが異なるため、設計思想や周辺ツールの位置づけには大きな違いがあります。
3. ランタイムの使い方
基本実行方法
JavaScriptランタイムは「ソースコードを渡して実行する」ことが基本です。
代表的な3つのランタイムでは以下のように書きます。
# Node.js
node file.js
# Deno(TypeScriptもそのまま実行可能)
deno run file.ts
# Bun
bun run file.ts
ここで重要なのは、どのランタイムを使うかによってコマンドが異なるという点です。
裏側ではそれぞれのランタイムがコードを解釈し、OSのAPIにアクセスして処理を進めています。
用途例
ランタイムは「JS/TSの実行環境」というシンプルな存在ですが、使い方によって性格が大きく変わります。代表的な3つのパターンを見てみましょう。
1. サーバーアプリ
HTTPサーバーを立ち上げ、リクエストを受けてレスポンスを返すプログラム。
Node.js の express、Deno の標準WebサーバーAPI、Bun の高速HTTPサーバーなどが代表例です。
Webサービスのバックエンドを構築する際に使われます。
2. CLIツール(コマンド化)
「画像を変換する」「設定ファイルを生成する」などの処理をコマンドとして配布・実行するケース。
例えば eslint や prettier も Node.js 上で動くCLIツールです。
DenoやBunでも同様にCLIを作ることができ、TypeScript対応や高速起動が魅力になります。
3. スクリプト実行(単発処理)
一度きりの処理や軽い自動化に使う方法です。
例:ログを整形する、ファイルを一括リネームする、APIを叩いてデータを取得する、など。
シェルスクリプトやPythonの代わりに、手慣れたJavaScript/TypeScriptで書けるのが利点です。
CLIツールとスクリプトの違い
ちなみに上記で出てきた両者の違いを整理すると次のようになります。
| 項目 | スクリプト | CLIツール |
|---|---|---|
| 主な目的 | 一時的・個人用の処理 | 再利用・配布を前提とした処理 |
| 実行方法 |
node myscript.js のように直接叩く |
mytool convert file.txt のように独自コマンド化 |
| 利用範囲 | プロジェクト内や個人PCに限定 | 他プロジェクトや他ユーザーにも利用可能 |
| 例 | ファイル名リネーム、API取得 | eslint, prettier, create-react-app |
つまり、小さく始めたスクリプトを整理・公開するとCLIツールになる と捉えると分かりやすいでしょう。
4. 「npm run serve」とランタイムの関係
実際には Node.js が動いている
npm run serve や npm run dev といったコマンドを実行すると、多くの人は「npm を動かしている」と思いがちです。
しかし実際には、裏で Node.js が JavaScript を実行しているのです。
npm はあくまで「Node.js でコードを実行するための補助ツール」に過ぎません。
npm の役割
npm は Node.js に付属している パッケージマネージャ です。
- 外部ライブラリ(パッケージ)の取得・更新
- 依存関係の解決
-
package.jsonに記述したスクリプトの実行補助
これらを担うことで、プロジェクトの管理や自動化を便利にしています。
npm run の仕組み(おまけ枠)
npm run serve を例にすると、実際の処理はシンプルです。
-
npm が
package.json内の"scripts"セクションを確認する{ "scripts": { "serve": "node server.js" } } -
serveという名前に対応するコマンド(ここではnode server.js)を探す -
そのコマンドを Node.js に渡して実行する
つまり、npm が自動で Node.js を呼び出してくれているだけ なのです。
npm は「Node.js の便利ボタン」
まとめると、npm run は
- Node.js を直接叩く代わりに
- プロジェクトごとに用意されたスクリプトを呼び出し
- 開発者が共通のコマンドで実行できるようにしてくれる
という存在です。
npm がいることで、開発者は毎回 node ./tools/dev-server.js --config ./configs/dev.json のような長いコマンドを打たずに済みます。
5. Node.js 以外のランタイム(Deno / Bun)
なぜ新しいランタイムが生まれたのか(背景)
Node.js は 2009 年に登場して以来、巨大なエコシステムを築き、いまやサーバーサイド JavaScript のデファクトスタンダードとなっています。
しかし長年の利用で以下の課題も浮かび上がってきました。
- セキュリティモデルの弱さ:Node.js のコードは基本的に OS のファイルやネットワークにフルアクセス可能。安全性の制御が難しい。
-
複雑なモジュール管理:npm の膨大な依存関係(
node_modulesフォルダ)が扱いづらい。 - 起動速度やパフォーマンスの限界:とくに軽量スクリプト実行時には「重い」と感じられる。
こうした課題を背景に、「よりモダンで、安全で、速いランタイムを作ろう」として誕生したのが Deno と Bun です。
Deno の特徴
Node.js の生みの親 Ryan Dahl が再設計したランタイムが Deno です(2018年発表、2020年正式リリース)。
名前は Node のアナグラム。まさに「Node の反省から生まれた」存在です。
-
セキュリティ重視
ファイルアクセスやネットワーク通信はデフォルト禁止。--allow-netなど明示的に権限を付与しないと実行できない。 -
TypeScript 標準対応
トランスパイラを別途用意せず、TSをそのまま実行可能。 -
URL import
npm ではなく、URL経由でライブラリを読み込む仕組み。依存管理の仕組みがシンプル。 -
標準ライブラリの充実
よく使う機能は公式が提供し、外部依存を減らす方向性。
Bun の特徴
Bun は比較的新しいランタイムで、2022年に公開されました。目玉は 「速さ」と「統合」 です。
-
超高速
JavaScriptCore(Safari と同じエンジン)を採用し、起動・実行が Node.js より圧倒的に速い。 -
ツール統合
- バンドラ(ESBuildのような機能)
- テストランナー
- パッケージマネージャ(npm互換)
これらを最初から内蔵。外部ツールを組み合わせなくても、Bun ひとつで開発が回せる。
-
npm互換
既存の npm パッケージをそのまま利用可能。
「速い・軽い・全部入り」が Bun の特徴です。
Node.jsとの使い分け例
| シーン | 選択例 |
|---|---|
| 既存プロジェクト、豊富なライブラリを活用したい | Node.js |
| 新規開発でセキュリティやTSを重視 | Deno |
| 起動の速さや統合ツールで開発効率を上げたい | Bun |
| 安定した運用基盤が最優先 | Node.js |
| 個人開発や小規模ツールで新機能を試したい | Deno / Bun |
つまり、Deno と Bun は「Node.js を置き換える存在」というより、
「Node.js の課題を補う選択肢」 として登場したと捉えるのが自然です。
6. まとめ
この記事では、普段なんとなく使っている npm run serve を入り口に、JavaScript ランタイムについて整理しました。
-
ランタイムとは?
→ JavaScript / TypeScript を実行する「基盤(環境)」のこと。ブラウザ内ランタイムとブラウザ外ランタイムがあり、Node.js / Deno / Bun は後者にあたります。 -
Node.js / Deno / Bun の違い
→ Node.js は実績とエコシステム、Deno はセキュリティと標準TS、Bun は高速性とツール統合。
それぞれの強みを理解すれば、プロジェクトの目的や環境に応じて最適なランタイムを選べます。
「ランタイム=コードを動かす土台」 を理解しておくことが、開発環境を正しく使いこなす第一歩です。
「裏で動いている仕組み」を意識できるようになると、開発効率やトラブル対応のスピードも一段と上がるはずです。
ここまで読んでいただきありがとうございました。