Denoの環境構築でつまずくのは、どのインストーラを選ぶか、どの版に固定するか、実行時にどの権限を許可するかという判断です。この記事では2026年8月時点の最新安定版v2.9.5を前提に、OS別のインストールコマンドからLTSの選び方、権限フラグの設計、Node.js資産の持ち込み範囲、Fresh 2でのプロジェクト作成までを公式ドキュメントとインストーラの実体に沿って組み立てます。Freshというフレームワーク自体の設計思想はDeno Freshとは|Preactとアイランドアーキテクチャの軽量Webフレームワーク【Fresh 2対応・2026年版】で扱っているため、ここでは手を動かす部分だけを追います。
まとめ:インストーラは公式スクリプト、版はLTS、Freshは初期化コマンド1行
結論を先に置きます。DenoはmacOSとLinuxならcurl -fsSL https://deno.land/install.sh | sh、WindowsならPowerShellでirm https://deno.land/install.ps1 | iexで入ります。npm経由も動きますが公式が起動時間の理由で推奨しておらず、Ubuntu・Debianに至ってはaptの公式リポジトリどころか標準リポジトリにdenoパッケージ自体がありません。
業務で使うなら版はチャネルで決めます。2026年8月時点のLTSは2.9系(v2.9.3以降)で、維持期限は2027年1月31日と公式に明示されています。Freshのプロジェクトはdeno run -Ar jsr:@fresh/initのウィザードで生成でき、Fresh 2からはViteプラグインとして動く構成に変わりました。以下、それぞれの手順と根拠を順に見ていきます。
Denoの基本:TypeScriptを直接実行する単一バイナリのランタイム
Denoは外部依存を持たない単一の実行ファイルとして配布され、macOS・Linux・Windowsのx64とarm64で動きます。Node.jsの作者であるRyan Dahl氏が設計し直したランタイムで、綴りのdenoはnodeのアナグラムです。
環境構築の観点で効いてくる違いは2つあります。ひとつはTypeScriptをそのまま実行できることで、tsconfig.jsonもトランスパイル手順も用意せずにdeno run app.tsが通ります。もうひとつが権限モデルです。フラグで許可しない限り、実行されたコードはファイルにもネットワークにも触れません。実行エンジンはNode.jsと同じV8で、この共通部分の仕組みはV8 Isolateとは?仕組み・Contextとの違い・サーバーレスでの活用を徹底解説にまとめています。
Denoのインストール:OS別コマンドと事前に要るもの
公式が第一に案内しているのはインストールスクリプトです。macOSとLinuxはシェル、WindowsはPowerShellで実行します。
# macOS / Linux
curl -fsSL https://deno.land/install.sh | sh
# Windows (PowerShell)
irm https://deno.land/install.ps1 | iex
# 導入後の確認
deno --version
シェル版のインストーラには前提が1つあります。スクリプトは配布物のzipを展開するため、冒頭でunzipと7zの有無を確認し、どちらも無ければ「either unzip or 7z is required to install Deno」と表示してその場で終了します。最小構成のUbuntuや多くのDockerベースイメージ、CIランナーはこれに該当するので、先にsudo apt-get install -y unzipを通してください。PATHへの追加はインストーラが既定で行います(無効化する--no-modify-pathが用意されている=既定は追加する側)。
パッケージマネージャからも入ります。macOSはHomebrewとMacPorts、WindowsはScoop・Chocolatey・winget、Linuxを含むクロスプラットフォームではNix、asdf、vfoxが公式ドキュメントに載っており、Rust環境があればcargo install deno --lockedでも導入できます。npm install -g denoも動きますが、公式は「npm経由で入れるとdenoコマンドの起動時間に影響が出る」と明記し、シェルまたはPowerShellのインストーラを推奨しています。Windowsは IsWow64Process2 に依存するため、Windows 10 バージョン1709またはWindows Server 2016 バージョン1709以降が必要です。
Ubuntu・Debianでaptが使えない理由と、ディストリ別の実情
Denoは公式のaptリポジトリを提供していません。それどころか、Ubuntuのprimary archiveを照会するとdenoの公開ソースパッケージは0件で、Debianのソースパッケージも存在しません。つまり素のUbuntuやDebianでapt install denoを叩いても、古い版が入るのではなく「パッケージが見つからない」で終わります。ここは選択の余地がなく、上のシェルインストーラを使います。
一方でディストリを一括りに「遅れている」と決めつけるのも正確ではありません。Archのextraリポジトリは2026年8月13日時点で2.9.5を配っており、最新安定版に追随しています。公式ドキュメントが「ディストリ同梱版はコミュニティ管理で最新リリースに遅れがち」と注意するのは事実ですが、実際の遅れ幅はディストリごとに違います。判断基準はシンプルで、そのディストリのパッケージ版がプロジェクトの要求する版に届いているかをdeno --versionで確認し、届いていなければ公式インストーラに切り替えれば済みます。
4つのリリースチャネルとLTSの維持期間
Denoはstable、lts、rc、canaryの4チャネルで配布され、メジャー版のプレリリース期間中はalphaとbetaが加わります。押さえるべきは、チャネルがバイナリ自体に焼き込まれている点です。同じ2.9.3という版番号が、stable版とLTS版という2つの異なるビルドとして存在します。deno upgradeが何を「最新」と見なすかは、いま動いているバイナリのチャネルで決まります。
| LTS版 | 維持開始 | 維持終了 |
|---|---|---|
| v2.1 | 2025-02-01 | 2025-04-30 |
| v2.2 | 2025-05-01 | 2025-10-31 |
| v2.5 | 2025-11-01 | 2026-04-30 |
| v2.9 | 2026-07-01 | 2027-01-31 |
LTSにバックポートされるのはセキュリティ修正と、クラッシュや計算誤りといった重大バグの修正だけです。API変更と新機能は入りません。表のとおり1系列の維持期間は3〜7か月で、1系列あたり約30か月のNode.jsとは前提が違います。年1〜2回はLTS系列を乗り換える作業が発生すると考えてください。その工数を確保できない案件では、LTSを選ぶより最新安定版のv2.9.5を追い続けるほうが結果的に運用は単純になります。
特定版へのピン留めと、LTSから滑り落ちる操作
CIやDockerイメージで版を固定したい場合、インストーラは第1位置引数をバージョンとして受け取ります。
# 特定版を入れる
curl -fsSL https://deno.land/install.sh | sh -s v2.9.5
# LTSチャネルへ切り替える
deno upgrade lts
ここに落とし穴があります。deno upgradeにバージョン番号を渡すと、常にstableビルドが選ばれます。LTSを使っている環境でdeno upgrade 2.9.3と打つと、同じ版番号のstableビルドがダウンロードされ、そのマシンはLTSチャネルから外れてstableへ移ります。しかも公式ドキュメントが明記しているとおり、古いLTSパッチ版にピン留めするdeno upgradeの形は存在しません。LTS運用では版番号を打たずdeno upgrade ltsだけを使う、と決めておくのが安全です。
権限フラグの設計:許可を書かないと何も触れない実行環境
公式ドキュメントはDenoを「既定で安全(secure by default)」と定義し、ファイルシステム、ネットワーク、環境変数、サブプロセス生成のいずれにも初期状態で触れないと明記しています。依存パッケージが自動的にすべてのI/O権限を得るNode.jsとは前提が逆です。必要な権限だけを実行時に渡します。
# ネットワークだけ許可
deno run --allow-net main.ts
# 読み取り先を限定し、その中の一部を除外
deno run --allow-net --allow-read=./data --deny-read=./data/secrets main.ts
ここで-A(全許可)を癖で付けると、この設計は何も守りません。--allow-readや--allow-netは値を渡してパスやホスト単位に絞れ、--deny-*で広い許可から一部を切り抜けます。フラグを毎回書くのが面倒ならdeno.jsonのpermissionsフィールドに宣言できますし、起動後にコードからDeno.permissions.revoke()で権限を降ろすこともできます。依存パッケージの既知脆弱性は権限とは別問題なので、CIのゲートにはdeno auditを挟みます。
過信を避けるための例外も押さえておきます。公式は「同一スレッド上のコードはすべて同じ権限レベルを共有する」と明記しており、依存モジュール1つだけを隔離することはできません。さらに、初期の静的モジュールグラフの読み込みは権限チェックの対象外です。静的なimport文と文字列リテラルのimport()で解決されるモジュールは、ローカルファイルでも--allow-readなしに、リモートURLでも--allow-netなしに読み込まれます。この免除が効くのは読み込みまでで、実行が始まったあとの動作は通常どおり権限に従います。
サンドボックスを素通りする–allow-runと–allow-ffi
すべての許可フラグが同じ重さではありません。公式が「サンドボックスできないものへのアクセスを与える=実質的に全権付与」と名指ししているのが2つあります。
--allow-runはサブプロセスの起動を許します。子プロセスは親から制限を引き継がない別プログラムとして走るため、そこで起きることはサンドボックスの外側です。とりわけ--allow-run=denoが危険だと公式が指摘しています。新しいdenoプロセスを--allow-all付きで起動できてしまい、制限を丸ごと脱出できるからです。渡すなら--allow-run=gitのように信頼できる実行ファイルを名指しし、denoやシェルを起動させないこと。--allow-ffiも同様で、ネイティブライブラリは同一プロセス内の機械語として動き、どの--allow-*を渡したかに関係なくシステムコールを直接発行できます。
組織で許可範囲を統制する権限ブローカー
フラグの管理を個々の開発者やCIジョブに任せると、結局-Aが横行します。Denoはこれを組織側で封じる仕組みを持っています。環境変数DENO_PERMISSION_BROKER_PATHにUnixドメインソケット(Windowsは名前付きパイプ)のパスを指定すると、すべての権限判断が外部のブローカープロセスへ委譲されます。
挙動は明確です。ブローカーが有効な間は--allow-*と--deny-*がすべて無視され、対話プロンプトも表示されません。権限チェックは1件ずつブローカーへ送られ、接続失敗・メッセージ破損・ID不一致など異常があればDenoはその場でプロセスを終了します。要求と応答の形式はJSON Schemaでバージョン管理されています。
ただし公式が「上級者向け」と警告しているとおり、ブローカーが落ちればアプリも道連れで止まります。単一のWebサービスを動かすだけなら導入する必要はありません。検討する価値があるのは、複数チームの実行環境で許可範囲を監査ログとして残す義務がある場合に限られます。
Node.js資産の持ち込みで詰まる3か所
既存のNode.jsプロジェクトを持ち込む場合、Deno 2系ではほとんどが修正なしで動きます。公式は「Deno 2.8時点でNode自身のテストスイートの75%超が通過し、ほぼすべてのnode:モジュールをカバーする」と計測値を出しています。npmパッケージはnpm:指定子またはpackage.json経由、require()を含むCommonJSもサポート対象です。package.jsonのdependencies・scripts・typeフィールドはそのまま読まれ、scriptsはdeno taskから実行できます。node_modulesは任意で、isolatedとhoistedの2レイアウトを選べます。
公式が「正直に言えば」と前置きして挙げる難所は3つです。一部のAPIが部分実装であること、Node-APIを使うネイティブアドオンにはローカルのnode_modulesと--allow-ffiが要ること、そして一部のツールがnpmのディスク配置そのものを前提にしていることです。裏を返せば、純粋なJavaScriptのパッケージだけで構成されたプロジェクトなら移行の障害はほぼありません。モジュール解決の考え方でつまずく場合はNative ESMの基本仕組みとCommonJSとの根本的な違いの整理を先に読むと切り分けが早くなります。
Freshプロジェクトの作成:初期化コマンドと生成されるファイル
DenoにはWebフレームワークが同梱されていないため、Webアプリを作るならFreshを載せます。Fresh 2.0.0は2025年9月9日に正式リリースされ、最新版は2.3.3(2026年4月28日)です。配布先はJSRの@fresh/coreに移っています。新規プロジェクトは次の1行で作成します。
deno run -Ar jsr:@fresh/init
ウィザードがプロジェクト名、tailwindcssを使うか、VS Codeを使うかを順に尋ね、回答に応じたひな形を生成します。出来上がるのはroutes/、islands/、components/、static/の各ディレクトリと、サーバーのエントリであるmain.ts、クライアント側エントリのclient.ts、deno.json、そしてvite.config.tsです。deno.jsonには@/のパスエイリアスが最初から設定されているので、相対パスの階層を数えずにimport { Button } from "@/components/Button.tsx"と書けます。開発サーバーはdeno task devで起動します。
CSSファイルの読み込み先だけ間違えやすいので補足します。Viteはモジュールグラフに含まれるものしかホットリロードしないため、スタイルシートはclient.tsからインポートします。ルーティングの書き方やアイランドの考え方はDeno Freshとは|Preactとアイランドアーキテクチャの軽量Webフレームワーク【Fresh 2対応・2026年版】を参照してください。
Fresh 1.xプロジェクトを2系へ移行する手順
1.x向けの構成は自動では移りません。まず更新スクリプトをプロジェクトディレクトリで実行します。$fresh/server.tsからfreshへのインポート書き換えなど、API変更の大半はこれで片付きます。続けて、Viteの依存をdeno.jsonのimportsへ追加します。
deno run -Ar jsr:@fresh/update
deno install npm:vite jsr:@fresh/plugin-vite
残るのは手作業です。Fresh 2は専用の設定ファイルを持たなくなったため、fresh.config.tsとマニフェストのfresh.gen.ts、そしてdev.tsを削除します。代わりにvite.config.tsを作って@fresh/plugin-viteのfresh()プラグインを登録し、CSS読み込み用のclient.tsを追加します。deno.jsonのtasksも書き換えが必要で、devはvite、buildはvite build、本番起動はdeno serve -A _fresh/server.jsになります。エントリファイルをFreshが生成する形に変わったためです。最後に、テンプレートの_404.tsxと_500.tsxは_error.tsx1本へ統合されているので、これも自分で寄せます。なおVite構成ではjsr:@fresh/plugin-tailwindcssは不要になり、npm:@tailwindcss/viteに置き換わります。
この移行の見返りは、開発時だけ必要なコードが本番から切り離されることです。公式はこれによってデプロイのサイズが小さくなり、アップロードと本番の起動が速くなると説明しています。
業務採用の判断材料となる更新の継続性
環境を整えたあと、社内で採否を問われたときに出す材料は開発の継続性です。最新安定版v2.9.5が2026年8月6日にリリースされ、LTSの維持期限も2027年1月31日まで公式に切られています。放置されたプロジェクトではありません。実務上の論点はむしろ前述のLTS周期で、乗り換え作業を年間計画に織り込めるかどうかが採否ラインになります。
同じくNode.js互換をうたう高速ランタイムと比較検討する場合は、Bunとは?インストール(brew・curl)から使い方・コマンドまで解説|Node.jsに挑む高速JSランタイムに導入手順と設計思想をまとめています。
JavaScript商標をめぐる係争の現在地
採用可否とは別に、質問されやすいのがJavaScript商標の話です。Deno Land社は2024年11月22日、USPTOにOracleが保有する「JavaScript」商標の取消を申し立てました。TTABは2025年6月18日に3つの主張のうち詐欺の主張を却下しましたが、中心である一般名称化(genericness)と放棄(abandonment)の主張は取り下げられておらず、審理が続いています。2026年8月時点で結論は出ていません。この係争はDenoの製品仕様にも配布条件にも影響しないため、技術選定の判断材料には使えません。
よくある質問
Denoの読み方と名前の由来は?
公式ドキュメントは発音を /ˈdiːnoʊ/、読みを dee-no と記載しています。日本語では「ディーノ」に当たります。綴りのdenoはnodeのアナグラムで、Node.jsの作者であるRyan Dahl氏が設計上の反省点を踏まえて作り直したランタイムであることが名前に表れています。
Windowsに入れるにはどのコマンドを使いますか?
PowerShellでirm https://deno.land/install.ps1 | iexを実行するのが公式の第一候補です。Scoop、Chocolatey、wingetからも導入できます。npm install -g denoでも入りますが、公式ドキュメントはnpm経由だとdenoコマンドの起動時間に影響が出ると注意しています。前提としてWindows 10 バージョン1709またはWindows Server 2016 バージョン1709以降が必要です。
UbuntuでAPTからインストールできますか?
できません。Denoは公式のaptリポジトリを提供しておらず、Ubuntuのprimary archiveにもDebianのソースパッケージにもdenoは存在しないため、apt install denoはパッケージが見つからずに失敗します。curl -fsSL https://deno.land/install.sh | shを使ってください。実行前にunzip(または7z)を入れておく必要があります。
TypeScriptを動かすのにtsconfig.jsonやビルド設定は必要ですか?
不要です。Denoは.tsファイルを受け取ってそのまま実行するため、deno run app.tsだけで動きます。トランスパイル用の依存パッケージもビルドスクリプトも用意しません。設定を書くとすればdeno.jsonにインポートマップやタスク、権限を定義する場面ですが、単一ファイルを動かすだけなら設定ファイル自体が要りません。
Freshで作ったアプリをSSRで動かすには追加設定が要りますか?
要りません。Freshは全ページをサーバー側でHTMLに描画してからブラウザへ返す設計で、これが既定の動作です。追加でJavaScriptを配信するのはislands/に置いたコンポーネントだけになります。deno run -Ar jsr:@fresh/initで生成した時点でこの構成なので、SSRのために書く設定はありません。レンダリング方式そのものの違いはCSRとSSRの違いと使い分け|レンダリング方式を比較して実装で選ぶで整理しています。