---
title: "Three.jsとは？r187の導入手順とglTF表示・バンドルサイズ実測まで解説"
url: "https://www.issoh.co.jp/tech/details/3051/"
published: 2024-07-12
updated: 2026-11-01
categories: ["シミュレーション"]
publisher: "株式会社一創"
---

# Three.jsとは？r187の導入手順とglTF表示・バンドルサイズ実測まで解説

Three.jsは、ブラウザの3D描画APIであるWebGLを扱いやすくまとめたJavaScriptライブラリです。最新版はr187で、2026年10月30日にnpmへ`0.187.0`が公開されました。ライセンスはMITです。古い入門記事には、現在は削除された配布ファイルやAPIを使う例があり、そのままr187へ置き換えると動かない場合があります。r125、r148、r161などで配布ファイルとAPIが段階的に削除されてきたためです。さらに2026年9月のr186では、minify済みのビルドと日本語版の公式マニュアルが削除されています。

この記事では、r187で実際に動く導入手順とglTFモデルの表示までを実装コードで示し、古い記事のコードが動かない原因と書き換え先、検索されることの多いバンドルサイズを実測値で示します。

## まとめ

r187時点でのThree.jsの要点は次のとおりです。

- 導入は`import map`でCDNを読むか、npmとViteを使うかの2択。script要素で`three.min.js`を読む方法はr161で配布そのものが無くなった
- r186でnpmの配布物から`three.module.min.js`などminify済みのビルドが消え、`require('three')`は非推奨になった。日本語版の公式マニュアルも同じr186で削除された
- `OrbitControls`や`GLTFLoader`は`three/addons/`から読み込む。`THREE.GLTFLoader`のような名前空間経由の参照は成立しない
- `THREE.Clock`はr183から非推奨で、r187でも警告付きで残っている。新しいコードは`Timer`で書く
- 本記事の最小シーンはr187でgzip後135,144バイト。名前付きで必要な機能だけ取り出しても、全量参照と比べた削減は約30%にとどまった
- 3D Gaussian Splattingはr186でaddonsに入ったが、描画できるのは`WebGPURenderer`だけ

以降で、それぞれの根拠と実装コードを順に説明します。

## Three.jsの守備範囲とWebGLとの役割分担

### WebGLを直接書く場合との実装量の差

WebGLはブラウザに標準搭載された低レベルの描画APIで、三角形を1枚出すだけでも頂点シェーダとフラグメントシェーダをGLSLで書き、バッファを確保し、行列を自分で計算する必要があります。Three.jsはこの層を包み、シーン、カメラ、描画器という3つのオブジェクトの組み立てに置き換えます。立方体を1つ置いてライトを当てるまでが20行程度で済むのは、シェーダと行列演算をライブラリ側が持っているからです。

裏返すと、WebGLの概念そのものが消えるわけではありません。座標系、カメラの視錐台、マテリアルとライトの関係は理解が必要です。WebGL側の仕組みと対応ブラウザについては[WebGLとは？仕組み・対応ブラウザの確認・動くコードとUnity WebGLビルドの手順【2026年】](/tech/details/4884/)で解説しています。扱う対象が2Dのスプライトやグラフであれば、Three.jsは過剰です。2D描画に特化した[PixiJSとは？WebGL/WebGPUで動く2D描画エンジンの使い方をv8.22対応で解説](/tech/details/9180/)は、2Dスプライトを中心とする実装の比較候補になります。転送量は使用機能を揃えたビルドで比較してください。

### シーンを構成する主要クラスの役割

次の表は、本記事のシーン構築とモデル表示で使う主要クラスをまとめたものです。時間管理のTimerやアニメーション再生のAnimationMixerなどは、後の章で説明します。

| クラス                               | 役割            | 入手先    |
| --------------------------------- | ------------- | ------ |
| `Scene`                           | 描画対象をまとめる入れ物  | 本体     |
| `PerspectiveCamera`               | 遠近法で写す視点      | 本体     |
| `WebGLRenderer`                   | シーンをcanvasに描く | 本体     |
| `Mesh`                            | 形状と材質を組にした物体  | 本体     |
| `BoxGeometry`・`BufferGeometry`    | 頂点の集まり（形状）    | 本体     |
| `MeshStandardMaterial`            | 光に反応する材質      | 本体     |
| `DirectionalLight`・`AmbientLight` | 平行光と環境光       | 本体     |
| `GLTFLoader`                      | glTFモデルの読み込み  | addons |
| `OrbitControls`                   | マウスでの視点操作     | addons |

見落としやすいのは右端の列です。モデルの読み込みと視点操作は本体に入っておらず、`three/addons/`から別途importします。古いコードで読み込みエラーが出る場合は、このimport先を確認してください。

### Three.jsで作られる代表的な用途

実際の採用先は、3Dであること自体が機能になっている画面に集中しています。用途ごとに中心となるクラスが決まっているので、作りたいものから逆引きできます。

- 製品やCADデータの3Dビューア：`GLTFLoader`で読み込み、`OrbitControls`で回転させる。後述のglTFの章がそのまま雛形になる
- 色や部品を切り替える製品コンフィギュレータ：読み込んだモデルのマテリアルの`color`を差し替えて再描画する
- 大量の点や棒を並べるデータ可視化：`InstancedMesh`で同じ形状を1回の描画命令でまとめて描く
- ヘッドセットで見るVR・AR：`renderer.xr`でWebXRのセッションに接続する
- 実写をスキャンした3D Gaussian Splattingの表示：r186で入った`GaussianSplat`を`WebGPURenderer`で描く

逆に、ページの背景を少し立体的に見せたいだけの用途には向きません。理由は後述のバンドルサイズの章で数字を示します。

### 開発体制とライセンス・リリース間隔の実測

Three.jsは2010年にRicardo Cabello氏（Mr.doob）が公開し、現在もGitHubの`mrdoob/three.js`で開発が続いています。r187の[LICENSEファイル](https://github.com/mrdoob/three.js/blob/r187/LICENSE)はMITライセンスで、著作権表記は「2010-2026 three.js authors」です。商用利用時に必要なのは著作権表示とライセンス文の保持だけで、利用料や公開義務はありません。

リリース間隔は、npmレジストリの公開日時を並べると実態が見えます。2025年はr178が6月30日、r179が8月1日、r180が9月3日、r181が10月31日、r182が12月10日。2026年はr183が2月18日、r184が4月16日、r185が6月25日、r186が9月8日、r187が10月30日です。この9区間は最短31日、最長75日、平均で約54日です。破壊的変更はこの節目のリビジョン更新で入ります。npmの`^0.187.0`は0.x系の規則により0.187系のパッチ更新だけを許し、r188へは自動で上がりません。それでも0.186.0から0.186.1のような修正版は入り込むため、ビルドの再現性を保つなら`"three": "0.187.0"`と完全固定し、上げるときにMigration Guideを確認する運用が確実です。

### 最新版r187とバージョン番号の読み方

npm上のバージョンは`0.187.0`、公式ドキュメントやコミュニティでの呼称は`r187`です。マイナー番号がリビジョン番号にあたり、`0.161.0`ならr161です。`0.186.1`のように末尾が付くのは、同じリビジョンの修正版です。

先頭が`0.`のまま止まっている点には意味があります。セマンティックバージョニングの慣習で`0.x`系は互換性を保証しない段階を指し、Three.jsは実際にマイナー更新でAPIを削除してきました。r187の[リリースノート](https://github.com/mrdoob/three.js/releases/tag/r187)の先頭も「Remove code deprecated in r177」です。[公式のMigration Guide](https://github.com/mrdoob/three.js/wiki/Migration-Guide)は非推奨の警告を10リリース残す運用を明記しており、古いプロジェクトは10リリースずつ段階的に上げるよう勧めています。

## import mapとnpm+Viteによる導入手順の選び分け

### import mapでCDNから読み込む手順

ビルドツールを使わない場合、[公式マニュアルのInstallation](https://threejs.org/manual/#installation)が案内する方法は`import map`です。HTMLの`head`内に`three`と`three/addons/`の解決先を書き、本体はES Modulesとして読み込みます。

```
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Three.js r187</title>
    <style>body { margin: 0; }</style>
    <script type="importmap">
    {
      "imports": {
        "three": "https://cdn.jsdelivr.net/npm/three@0.187.0/build/three.module.js",
        "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.187.0/examples/jsm/"
      }
    }
    </script>
  </head>
  <body>
    <script type="module" src="./main.js"></script>
  </body>
</html>
```

バージョンを`0.187.0`のように具体的に書く点が要点です。指定を省いた`three@latest`は、次のリリースが来た瞬間にAPI削除を巻き込みます。`three/addons/`の末尾スラッシュも必須で、これが無いと`three/addons/controls/OrbitControls.js`の解決に失敗します。

CDNのURLでminify版を指定したい場合は注意が要ります。r186でnpmの配布物から`three.module.min.js`が削除されました（[#33893](https://github.com/mrdoob/three.js/pull/33893)）。jsDelivrは配布物に無い`.min.js`も自動生成して200を返しますが、unpkgで`three@0.187.0/build/three.module.min.js`を指定すると404になります。CDNによって結果が変わるので、import mapには`three.module.js`を書いてください。

ローカルで開く際は`file://`ではなく簡易サーバを立ててください。`npx serve .`で十分です。ES Modulesとテクスチャ読み込みはどちらもオリジンを要求するため、HTMLファイルをダブルクリックで開くと動きません。

### npmとViteで開発環境を作る手順

公式マニュアルが大半の利用者に推奨する方法です。作業フォルダにindex.htmlと後述のmain.jsを用意してください。前節のHTMLを使う場合はimport mapを削除し、依存関係の解決をViteに任せます。

```
npm install --save-exact three@0.187.0
npm install --save-dev vite
npx vite
```

`npx vite`を実行すると開発サーバが起動します。通常はブラウザで`http://localhost:5173`へアクセスすると、`import * as THREE from 'three'`がそのまま解決されます。公開用のファイルは`npx vite build`で`dist/`に出力されます。minifyはこの段階でViteが行うため、配布物にminify版が無くても困りません。TypeScriptで書く場合、型定義は本体に同梱されないので`npm install --save-dev @types/three`を別途入れます。r187に対応する`0.187.0`は本体と同じ10月30日に公開されています。

Node.jsのスクリプトから`require('three')`で読み込んでいる場合は、r186以降で移行が必要です。r187で実行すると「`require("three")` is deprecated and will be removed.」という警告が出ます。`import * as THREE from 'three'`へ書き換えてください。

### import mapとnpm＋Viteの採用条件

本番運用のプロダクトでCDNのimport mapを使うのは避けてください。外部CDNの応答が初回描画の直列依存になるうえ、ツリーシェイキングが効かず`build/three.module.js`と、そこから読まれる`build/three.core.js`を丸ごと転送することになります。

import mapが向くのは、検証用のスケッチ、社内向けの単発デモ、ビルド環境を用意できない既存CMSへの埋め込みです。それ以外はnpmとViteを選んでください。

## r128世代のコードが動かない原因と現行版への書き換え

日本語で「Three.js 使い方」を検索すると、`three.min.js`をscript要素で読み込み、`THREE.`の名前空間からすべてを呼ぶ形のコードが多く出てきます。これはr128前後、2021年ごろの書き方です。現在は配布物の構成が変わっており、そのままでは動きません。どこがいつ消えたのかを整理します。

| 古い記事での書き方                               | 状態       | r187での書き方                                    |
| --------------------------------------- | -------- | -------------------------------------------- |
| `build/three.min.js`をscriptで読込          | r161で削除  | import mapで`build/three.module.js`           |
| `build/three.module.min.js`             | r186で削除  | `build/three.module.js`                      |
| `require('three')`                      | r186で非推奨 | `import * as THREE from 'three'`             |
| `examples/js/controls/OrbitControls.js` | r148で削除  | `three/addons/controls/OrbitControls.js`     |
| `new THREE.GLTFLoader()`                | 名前空間に非公開 | `three/addons/loaders/GLTFLoader.js`からimport |
| `new THREE.Geometry()`                  | r125で削除  | `BufferGeometry` \+ `setAttribute`           |
| `new THREE.Face3()`                     | r126で削除  | 頂点を3つずつ並べて属性に登録                              |
| `new THREE.WebGL1Renderer()`            | r163で削除  | `WebGLRenderer`（WebGL 2が前提）                  |
| `new THREE.Clock()`                     | r183で非推奨 | `new THREE.Timer()`                          |

削除の時期は配布物そのもので確認できます。r160のtarballには`build/three.js`と`build/three.min.js`が入っていますが、r161には入っていません。`examples/js/`配下は0.147.0までHTTP 200で取得できるのに対し、0.148.0以降は404を返します。minify版は0.185.1のtarballに`three.module.min.js`を含む5本がありますが、0.186.1では1本も残っていません。

厄介なのは、古い記事が指定するCDNのURL自体は今も生きている点です。`cdnjs`のr128の`three.min.js`はHTTP 200を返すため、読者は「ファイルは読めているのにエラーになる」状態に陥ります。r128をピン留めしても解決しません。r128のUMDビルドを読み込んで名前空間を検査すると、`THREE.Geometry`も`THREE.Face3`も`THREE.GLTFLoader`もすべて`undefined`です。r128本体だけを読み込んで、これらのクラスを参照するコードは動きません。

### THREE.Geometryで頂点を組むコードの書き換え

頂点を直接指定するコードは`BufferGeometry`に置き換えます。`vertices.push`と`faces.push`の代わりに、座標を`Float32Array`へ平坦に並べ、3要素で1頂点として属性に登録します。

```
import * as THREE from 'three';

const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
  -1,  1, 0,
   1,  1, 0,
   1, -1, 0,
]);
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.computeVertexNormals();

const mesh = new THREE.Mesh(
  geometry,
  new THREE.MeshBasicMaterial({ color: 0xff0000, side: THREE.DoubleSide })
);
scene.add(mesh);
```

`BufferAttribute`の第2引数`3`は1頂点あたりの要素数です。面の表裏は頂点の並び順で決まり、既定のFrontSideでは裏側が描画されません。`side: THREE.DoubleSide`を付けているのはそのためです。ライティングを効かせるマテリアルを使う場合は`computeVertexNormals()`が要ります。

### Clockからの移行先となるTimerの使い方

経過時間の取得に長く使われてきた`THREE.Clock`は、r183で非推奨になりました。r187でもクラス自体は残っており、インスタンス化すると「THREE.Clock: This module has been deprecated. Please use THREE.Timer instead.」という警告が出ます。後継の`Timer`はr179でコアのエクスポートに加わっています。r187でr177の非推奨コードが削除されたのと同じ10リリースの周期が続けば、`Clock`はr193前後で消える見込みです。警告が出ている今のうちに置き換えてください。

移行には生成処理の変更と、毎フレームの更新処理の追加が必要です。`new THREE.Clock()`を`new THREE.Timer()`に変え、毎フレーム`timer.update(time)`を呼んでから`timer.getDelta()`を読みます。`Clock`が呼び出しのたびに時刻を測っていたのに対し、`Timer`は`update()`の時点で値を確定させるため、1フレーム内で`getDelta()`を2回呼んでも同じ値が返ります。アニメーション更新と物理演算で別々のdeltaを使ってしまう事故が起きません。

## 最小構成のシーンを描画するコードと各行の役割

import mapを書いたHTMLから読み込む`main.js`の全体です。立方体を1つ置き、ライトを当てて回転させます。

```
import * as THREE from 'three';

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111418);

const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(3, 2, 5);
camera.lookAt(new THREE.Vector3(0, 0, 0));

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const box = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0x44aa88 })
);
scene.add(box);
scene.add(new THREE.AmbientLight(0xffffff, 0.6));
const light = new THREE.DirectionalLight(0xffffff, 2.5);
light.position.set(3, 5, 4);
scene.add(light);

const timer = new THREE.Timer();
renderer.setAnimationLoop((time) => {
  timer.update(time);
  box.rotation.y += timer.getDelta() * 0.8;
  renderer.render(scene, camera);
});

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});
```

`PerspectiveCamera`の4つの引数は、視野角45度、アスペクト比、手前の描画境界0.1、奥の描画境界100です。手前の値を0.001のように極端に小さくすると深度バッファの精度が落ち、重なった面がちらつくZファイティングが出ます。0.1前後から始めてください。

座標を扱う`Vector3`は`position`、`scale`、ライトの向きなど広範に登場します。`camera.position.set(3, 2, 5)`は`Vector3`への代入の短縮形で、`camera.position.x = 3; camera.position.y = 2; camera.position.z = 5;`という3つの代入と同じです。

`setPixelRatio`に`Math.min(window.devicePixelRatio, 2)`を渡しているのは、描画するピクセル数が比の2乗で増えるからです。devicePixelRatioが3のスマートフォンで無制限に追従させると、2で頭打ちにした場合の2.25倍のピクセルを毎フレーム塗ることになります。

ループは`requestAnimationFrame`を直接書かず`renderer.setAnimationLoop()`を使ってください。WebXRのセッション中はブラウザ側のフレーム供給元が切り替わるため、`requestAnimationFrame`直書きのループはヘッドセット上で描画されません。ブラウザXRの対応状況は[WebXRのデモ・サンプル集と対応ブラウザ一覧【2026年10月】｜試し方と使い方を実測で解説](/tech/details/7076/)にまとめています。

リサイズ時に`camera.updateProjectionMatrix()`を忘れると、描画領域だけが伸びて映像が横に潰れます。`aspect`の書き換えは投影行列に自動反映されません。

## glTFモデルの読み込みとアニメーション再生の実装

### GLTFLoaderとOrbitControlsのaddons経由の読み込み

モデルローダーとカメラ操作は本体に含まれず、`three/addons/`配下にあります。古い記事の`new THREE.GLTFLoader()`が動かないのはこのためで、`THREE`名前空間には最初から入っていません。前章の`main.js`から、先頭のTHREEのimport文と、Timerの生成からアニメーションループの末尾までを削除し、次のコードを追加します。シーン、カメラ、描画器、ライト、リサイズ処理は残してください。モデルは別途用意し、簡易サーバでは公開ルートのmodelsフォルダ、Viteではpublic内のmodelsフォルダにrobot.glbとして配置します。

```
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

let mixer = null;
new GLTFLoader().load('/models/robot.glb', (gltf) => {
  scene.add(gltf.scene);
  if (gltf.animations.length > 0) {
    mixer = new THREE.AnimationMixer(gltf.scene);
    mixer.clipAction(gltf.animations[0]).play();
  }
}, undefined, (error) => {
  console.error('glTFの読み込みに失敗しました', error);
});

const timer = new THREE.Timer();
renderer.setAnimationLoop((time) => {
  timer.update(time);
  const delta = timer.getDelta();
  if (mixer !== null) mixer.update(delta);
  controls.update();
  renderer.render(scene, camera);
});
```

読み込むファイルはバイナリ形式の`.glb`を推奨します。テキスト形式の`.gltf`はテクスチャやバッファを外部ファイルとして参照する場合があり、その場合は相対パスを保って配置する必要があります。参照先を取得できないと、モデルの読み込み失敗やテクスチャ欠落が起こります。データURIによる埋め込みも可能です。`enableDamping`を有効にしたなら、毎フレーム`controls.update()`を呼んでください。呼び忘れると慣性が効かず、ドラッグを離した瞬間に動きが止まります。

### AnimationMixerによるクリップ再生の手順

glTFに含まれるアニメーションは`gltf.animations`に配列で入っています。`AnimationMixer`を対象オブジェクトに紐づけ、取り出したクリップを`clipAction().play()`で再生し、毎フレーム経過秒数を`mixer.update(delta)`に渡します。

再生位置は経過秒数の累積で決まります。r187で、0秒から1秒にかけてY座標が0から2へ動くクリップをglTFに書き出して読み直し、0.5秒ぶん進めるとY座標は1.000でした。`mixer.update()`にミリ秒をそのまま渡すとクリップ長を大きく超え、既定のループ再生では再生位置が折り返します。同じ1秒のクリップに500を渡すと、終端で止まるのではなく再生位置が0秒へ戻り、Y座標は0.000になります。`Timer.getDelta()`が返す秒単位の値をそのまま渡してください。

複数のクリップを持つモデルでは`gltf.animations[0]`決め打ちを避け、`THREE.AnimationClip.findByName(gltf.animations, 'Walk')`のように名前で取得します。書き出しツールによって配列の順序が変わるためです。

## バンドルサイズの実測値とツリーシェイキングの限界

Three.jsを採用してよいかを決める材料として、転送量は無視できません。three 0.187.0をesbuild 0.28.2で`--bundle --minify --format=esm`して`gzip -9 -n`した実測値が次の表です（2026年11月1日測定）。どの構成も本記事に掲載したコードそのものをビルドしています。

| 構成                               | minify後   | gzip後     |
| -------------------------------- | --------- | --------- |
| 最小シーンから`WebGLRenderer`だけ外した構成    | 325,138 B | 74,711 B  |
| 本記事の最小シーン（前章の`main.js`）          | 540,484 B | 135,144 B |
| 最小シーン＋glTFの章のコード                 | 660,495 B | 166,412 B |
| import \* as THREE を全参照          | 752,069 B | 191,959 B |
| 最小シーンの描画器を`WebGPURenderer`に替えた構成 | 824,103 B | 226,567 B |

読み取れることは2つあります。第一に、名前付きインポートで必要な機能だけを取り出しても、全量参照との差はgzip後で191,959バイトから135,144バイトへの約30%減にとどまります。r187のリリースノートには数学クラスのツリーシェイキング改善が入っていますが、この構図は変わっていません。`WebGLRenderer`がシェーダのチャンクとマテリアル定義を広く参照しており、使っていないマテリアルのGLSL文字列まで残るためです。

第二に、描画器を外した構成が74,711バイトである一方、`WebGLRenderer`を1つ足すと135,144バイトになり、gzip後で約60KB増えます。gzipの差分は部品単体のサイズではなく、組み合わせる機能やビルド条件でも動きます。それでも、画面に描く以上は描画器を外せないため、この最小シーンの135KB前後が実際の出発点だと見積もっておくのが安全です。

この数字を踏まえた判断は明確です。装飾目的で背景に3Dを1つ置きたいだけなら、Three.jsは採用しないでください。CSSのグラデーションやCanvas 2D、あるいは用途を絞ったライブラリで足ります。React環境で3Dのグラデーション背景を手早く作る[ShaderGradientとは？React・Vue・Next.jsで3Dグラデーション背景を実装する手順](/tech/details/2679/)のようなパッケージもありますが、こちらは実装を簡略化する選択肢で、内部でThree.jsとReact Three Fiberを使うため転送量は減りません。この転送量を許容する判断基準は、モデルの回転操作、製品コンフィギュレータ、3Dデータの可視化など、3D表示が必要な機能を提供するかどうかです。

削減の手段が無いわけではありません。glTF-Pipelineなどで形状をDraco圧縮し、読み込み時に`DRACOLoader`で復号すればモデル側の転送量を削減できますし、3Dを表示する画面でだけ動的インポートすれば初期表示のバンドルからは外せます。ただしどちらもThree.js本体のサイズには効きません。

## React Three FiberとWebGPURendererの採用条件

### React Three Fiberのバージョン整合

ReactからThree.jsを使う場合、シーングラフをJSXで宣言できるReact Three Fiberが事実上の標準です。最新は2026年10月14日公開の`@react-three/fiber` 9.8.2で、peerDependenciesは`react`が19以上19.4未満、`three`が0.156以上と宣言されています。補助コンポーネント群の`@react-three/drei`は10.7.9で、`three`は0.159以上を要求します。

詰まりやすいのはReactの上限指定です。`>=19 <19.4`という範囲なので、現行のReact 19.3.1は収まりますが、Reactを19.4へ先行して上げるとpeer依存の警告が出ます。Three.js側は下限のみの指定なので、r187との組み合わせに制約はありません。Reactのバージョンを先に確定させてから、fiberとdreiを合わせてください。

素のThree.jsとReact Three Fiberのどちらを使うかは、状態管理の所在で決めます。3D側の状態がReactのstateと連動する画面ならReact Three Fiber、読み込んで回すだけの独立したビューアなら素のThree.jsで十分です。後者にReact Three Fiberを入れると、再レンダリングとフレームループの関係を調整する手間だけが増えます。

### WebGPURendererに切り替える条件

配布物には`three/webgpu`というエントリポイントがあり、`WebGPURenderer`とノードベースのマテリアル記述（TSL）が含まれます。前章の表のとおり、同じ最小シーンの描画器を`WebGPURenderer`に替えるとgzip後226,567バイトで、`WebGLRenderer`版の約1.7倍です。`three/webgpu`からは`WebGLRenderer`を取り出せない点にも注意してください。r187で検査すると`undefined`でした。

既存プロジェクトを`WebGPURenderer`へ全面移行するのは、今の時点では勧めません。マテリアルやポストプロセスの記述がTSLベースに変わり、addons側の対応状況も機能ごとに差があるためです。r186・r187のMigration Guideの項目も、TSLとWebGPU側の仕様変更が大半を占めています。切り替える価値があるのは、コンピュートシェーダでパーティクルを数十万単位で動かす処理や、次に挙げるGaussian Splattingのように`WebGPURenderer`でしか描けない機能を使う場合です。通常の3Dビューアであれば`WebGLRenderer`のままで問題ありません。

## よくある質問

### Three.jsの読み方は？

「スリージェイエス」と読みます。公式サイトの表記は`three.js`で小文字ですが、文中では「Three.js」と先頭を大文字にする書き方が定着しています。npmのパッケージ名は`three`です。`threejs`は存在しませんが、`three.js`という別パッケージが実在します。こちらは2016年で更新の止まった`0.77.1`で、説明文にも「’three.js’ npm package has been deprecated in favor of the ‘three’ npm package.」とあります。打ち間違えてもエラーにならず10年前のコードが入ってしまうため、`npm install three`と正確に指定してください。GitHubのリポジトリ名は`mrdoob/three.js`です。

### Three.jsはどこからダウンロードすればよいですか？

入手元はnpmとGitHubのリリースページの2つです。ファイルを自前のサーバに置きたい場合は`npm pack three@0.187.0`で取得し、`package/build/`の`three.module.js`と`three.core.js`、`package/examples/jsm/`を配置します。`three.module.js`は内部で`three.core.js`を読み込むため、片方だけ置いても動きません。`build/three.min.js`はr161、`build/three.module.min.js`はr186で配布物から削除されており、探しても見つかりません。自前配置の場合もimport mapで解決先を書く必要があります。

### Three.jsは商用利用できますか？

できます。配布物に同梱されるLICENSEはMITライセンスで、著作権表記は「Copyright 2010-2026 three.js authors」です。求められるのは著作権表示とライセンス文をソフトウェアの複製に含めることだけで、利用料、ソースコードの公開、改変内容の開示はいずれも義務付けられていません。商用製品への組み込みや改変後の再配布も可能です。

### Three.jsの日本語ドキュメントやAPIリファレンスはどこにありますか？

APIリファレンスは公式の`threejs.org/docs/`が一次情報で、英語のみです。公式マニュアルにあった日本語版は、r186で翻訳版がまとめて削除されました（[#33997](https://github.com/mrdoob/three.js/pull/33997)）。理由は、翻訳が英語版と同期されず内容の欠落や構成のずれが放置されていたためで、以後は英語版が唯一の正となり、URLも`threejs.org/manual/#installation`の形式に変わりました。日本語で読みたい場合はブラウザの翻訳機能を使い、コードやクラス名は英語版の表記のまま照合してください。生成AIに読ませる用途では、`threejs.org/docs/llms.txt`と`threejs.org/docs/llms-full.txt`が公開されています。

### Three.jsで3D Gaussian Splattingは扱えますか？

r186から扱えます。`three/addons/objects/GaussianSplat.js`が描画を担い、読み込みには`GaussianSplatPLYLoader`、`SPLATLoader`、`KSPLATLoader`と、glTF向けの拡張が用意されています。ただし[GaussianSplat.jsのソース](https://github.com/mrdoob/three.js/blob/r187/examples/jsm/objects/GaussianSplat.js)に明記されているとおり、使えるのは`WebGPURenderer`だけで、`WebGLRenderer`では描けません（`WebGPURenderer`の`forceWebGL`によるWebGLへのフォールバックは可）。import mapを使う場合は`three/webgpu`と`three/tsl`の両方の解決先を書く必要があります。手法の原理は[3D Gaussian Splattingの原理｜3Dガウシアン・微分可能ラスタライズ・最適化の仕組み](/tech/details/3288/)で解説しています。

## 関連記事

- [WebGLとは？仕組み・対応ブラウザの確認・動くコードとUnity WebGLビルドの手順【2026年】](/tech/details/4884/)
- [PixiJSとは？WebGL/WebGPUで動く2D描画エンジンの使い方をv8.22対応で解説](/tech/details/9180/)
- [WebXRのデモ・サンプル集と対応ブラウザ一覧【2026年10月】｜試し方と使い方を実測で解説](/tech/details/7076/)
- [A-Frameとは？HTMLでVR/ARを作る使い方｜v1.8.0の導入・アニメーション・AR実装](/tech/details/3636/)
- [3D Gaussian Splattingの原理｜3Dガウシアン・微分可能ラスタライズ・最適化の仕組み](/tech/details/3288/)

---

出典: [Three.jsとは？r187の導入手順とglTF表示・バンドルサイズ実測まで解説](<https://www.issoh.co.jp/tech/details/3051/>)（株式会社一創）
