Module Import / Usage

I start work with some years ago. Many things has changed since then. Now three is imported as module. and I am confused about including three.js into a project. How does it work?

I’ve downloaded three.js from github. I now have a bunch of directories. I can see examples and open them. But, when I try to import three.modules.js and e.g. OrbitControls.js I get an error message, because of missing dependencies.

How a directory should look, who’s three completely in it, but without examples and not needed stuff like models? And then, how to import needed Modules?

When working with modules, it’s typical to work with a bundler in order to generate a build file containing the entire source code of your app (libs + custom code). The following sample project shows how you setup a simple module based three.js project with rollup.js.

Also read the following guide for more information about modules:

1 Like

Thank you so far. It is complicated. I use Win10 at the moment. Is there any bundler available for?

They all require node.js which is available on all operating systems. I highly recommend you study how ES6 modules work before proceeding. The following resource might help in this context:

OMG. Why is three js now so complicated and unuseful? Is there any complete build without using three js as module?

You can still develop your code like similar to the old style. Just with modules: three.js dev template - module - JSFiddle - Code Playground

Not much of a difference if you ask me.

Well, it’s just the way JavaScript works these days. And that’s a good thing. The entire development process becomes much more stable and predictive. If you don’t understand these benefits, you should really invest some time in learning state-of-the-art web development.

1 Like

There are people (including myself) that would argue the opposite. The alternative ways are 20 years old.

If you’re finding this step frustrating, you don’t need to do do it. You can do this:

<script type="module">
   import * as THREE from './path/to/three.module.js';

I think nearly 90% of browsers support that syntax now. It’s not any more complicated than the old way, arguably it’s simpler.

This is a very simple example that demonstrates how to do it:

And this one show you how to include the OrbitControls module:


This is NOT the old style. The old style was:

<script src="three.js"></script>
<script src="lib/controls/TrackballControls.js"></script>
<script src="lib/controls/OrbitControls.js"></script>

Truly not. Three.js isn’t twenty years old. I worked with about four or five years ago.

At least I get it run, but I only can use file paths from examples. But I don’t want to. I now think about babylon.js or an other alternative to three.js. Why should I install and learn to export/import modules and install node.js to develope my own application? Now three.js is not useful anymore, I think. So many errors at the begin frustrates beginners. Me, I am programmer since 1984.I could learn it. But for what? To make myself addicted? Never.

I think you have a point there. However, I believe you have several alternate options.

You can use an older version of three.
You can use no three whatsoever.
You can fork three, and change the import/export mechanism to whatever works for you.

Well, that’s reasonable. If three.js no longer suits you then you should check out the alternatives.

However, you can still use the old style:

<script src="three.js"></script>
<script src="lib/controls/OrbitControls.js"></script>

These files are still in the repo to maintain backwards compatibility:


I’m not aware of any plans to remove them in the near future. @Mugen87 do you know if there’s been any discussion about how long we’ll keep these old files around for?

In any case, even if they get removed, as @pailhead says you can always use an old version of three.

EDIT: Just found. Thank you. :slight_smile:

1 Like

I can understand your frustration a little.
If you’re not constantly busy with something and it develops rapidly, it can happen. :worried:

I’ve had these phases for the last :five: :zero: years. But I couldn’t just continue on the basis of my first program either. Although this beginning still gives me a lot! Back in autumn 1969 it was interesting to find a square root with assembler. (Polish calculator Zam 2 ZAM-2 – Wikipedia, wolna encyklopedia)

When I had to deal with HTML about :two: :five: years ago, I found a lot to criticize about it. I had worked with some programming languages in the meantime. HTML was a stylistic break for me. But at the beginning it was not foreseeable what it would be used for later. It came from a pure side design. I found the tags horrible. (Still a little bit! :wink: )

Now with JavaScript three.js there are ongoing developments.

You can approach it differently and then possibly venture further.

Take instructions let and const.
In three.js and three.module.js you only find
if ( ! array || // let 'undefined' and 'null' pass
and const in shader parts.

@looeee writes there

“ES6 introduced let and const, which are basically designed to replace var. You can still use var to keep things backward compatible, but you don’t need to anymore, and we’ll never use var in this book.”

I have resisted first (let like ancient BASIC :upside_down_face: )
Then I tried it. It is a matter of familiarization.

On the other hand, @Mugen87 continues to use var in its jsfiddles.

:sun_with_face: Serenity is appropriate. :slightly_smiling_face:

I will try out the module variant next year.

By the way - for my Collection of examples from (basic examples) I copy the required files of the current revision. So the examples remain safely executable. (A classic problem for demonstration: geometry - Three.js v74 and up don't support LatheGeometry - Stack Overflow )


2020 :fireworks: It’s next year! :sparkler:

For the collection (basic examples) I copy the required files of the current revision. So the examples remain safely executable.

The example
( ShaderLib normalmap is no longer available ) @Mugen87 uses modules.

My first attempt to include it in the collection failed.
The renaming of three.module.js with revision number caused problems. So I created a folder jsm112 for the revision.

But there was a strange error message. There was a folder “build” to be recognized. I don’t have one of those at all. Then I took out “OrbitControls” and it worked. In the module version it says further above


This is the solution to the riddle, the source of the error! The modules are statically interdependent. I find this a big disadvantage compared to the old version.

I have to modify the file.


But maybe I haven’t found the smartest way to do it with as little effort as possible without accessing an external site or taking over the revision completely?

But it’s working.

:sun_with_face: Serenity is appropriate. :slightly_smiling_face:

1 Like

If this works, it would be great! Thank you. I’ll do that at last, when I know, what modules I need. At the moment, I use modules from examples. I’ve tried nodejs, but it is a mess! Needs about twenty minutes to install, then on npm install pathtomyproject three: no package.json found… no help, no documentation, nothing. Will never use again.

BTW: Happy new year!

May your 51st year be both prosperous and serene, sensei.

The modules are statically interdependent

I don’t think that’s the case here. The examples rely on three.module.js but three.module.js doesn’t rely on any of the examples. For code to be statically interdependent you have to have two files that import each other (at least that’s my understanding).

There was a folder “build” to be recognized. I don’t have one of those at all.

Ah, yeah now I see your problem. That’s kind of a difficult problem for us to solve on the three.js side. This was discussed on Github a few times, I’m not sure if there was any resolution except to tell users to keep the same folder structure as in the repo:

  • vendor
    • three
      • build
        • three.module.js
      • examples
        • jsm
          • controls
            • Orbitcontrols.js

Then in your code:

import { WebGLRenderer }  from "./vendor/three/build/three.module.js";
import { OrbitControls } from "./vendor/three/examples/jsm/controls/OrbitControls.js";

If you do this then modules will work.


I meant one-way dependency.

You know my English is bad and I don’t know the technical terms in English exactly. The translator is not always helpful with things that should be exact in the technical language. :sob:

I took a closer look at the structure. The imports are almost all very simple.


Just a few more complicated ones.

Since in the collected basic examples of discourse only a few modules are used over and over again, it is easier and clearer if I copy them into a directory and adjust the import path.

Especially beginners who use the examples have more problems if they find nested directories. And especially for me it would make more effort. :sweat:

I will point out the exact structure vendor etc. at the appropriate place. I will give an example of the change.

I noticed that only a few modules are available as .min. , not even three.module.js.
Is there a reason for this :question:

By the way, I found some lost links during the review. A three.js professional can fix that for sure.

broken (or changed) links


GitHub - dataarts/dat.gui: dat.gui is a lightweight controller library for JavaScript.

SubdivisionModifier.js server error 500



I think the reasoning here is that users should be using a bundler and minifying their code for production.

I’m not sure that reasoning still holds now that we are switching to http/2 and being told to split things up into 100kb chunks.