Module Import / Usage

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

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: )


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



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.


being told to split things up into 100kb chunks.

Where does one find this?

It’s all I found.

4.2 Frame Size
The size of a frame payload is limited by the maximum size that a receiver advertises in the SETTINGS_MAX_FRAME_SIZE setting. This setting can have any value between 214 (16,384) and 224-1 (16,777,215) octets, inclusive.

6.1 DATA
DATA frames (type=0x0) convey arbitrary, variable-length sequences of octets associated with a stream.

I have finished the description of how to use modules in the basic examples of the Collection of examples from
See below in the picture.

Here is the pdf file as well. Module usage.pdf (303,6 KB)

1 Like

I can’t find the specific article I read about that right now. I think it was on mdn or v8 blog, my search is turning up nothing right now though. In any case, the 100kb is just a rough number, the point is that with HTTP/2 there’s very little advantage anymore to bundling everything up into a single huge file (aside from a slight increase in gzip performance).

Instead we should create more smaller files, serve the least JS up front to get the page loaded and active and then the rest later as the user needs it. Also, we can make changes to our JS without completely invalidating user cache - that is, when you change your app the user doesn’t need to download the whole three.js library again, just the part of the code that you changed contained in a separate small JS file.
At least that’s the best practice, it’s more complex of course and the benefits are not huge except for on slow mobile devices.

One thing I’ve noticed on the various posts of I’ve read about this is that there’s no mention of tree-shaking, I guess for that to work you still need to bundle into a single large file. That’s kind of a moot point since three.js doesn’t work with tree-shaking yet anyway.


The example in Missing line when passing edgeGeometry to wireframeGeometry2
( @Mugen87 ) imports several modules.

This is a nice example of the possibilities of using modules.
I put the example in the Collection of examples from


The original imports are commented out and replaced by the modified modules.

Please note that:

G’day! Is there a tutorial for beginners* on how best to develop applications using three.js? Some of us three.js users are not that well invested in general JS programming, especially in the context of its rapid development over the last few years. I spent half a day yesterday trying to use an example with HDR env maps and I’ve given up after constant stream of errors. I too come from around r70 of Three and ES5 and my workflow was just to link necessary .js files to develop apps both locally and remotely.

If I install NPM and Three to develop locally via modules (which still gives me errors BTW), how do I then compile it for the final use on the web? How does that work with other libraries and JS code used in my project? Is it just one big-ass JS file? How would one share the development with other people, if necessary?

It would be great if there was some step-by-step example including all necessary installations and recommended development/deployment tools. Thanks :pray: :blush:

I have a threejs boilerplate here. It uses nodejs, es6 imports, and also in typescript.

1 Like

Hi @fallenartist. Unfortunately, there is no tutorial but I’ve created a repository some time ago that demonstrates a minimalistic setup with three.js and rollup.

In your npm project, add rollup and rollup-plugin-node-resolve to your dev dependencies and create a rollup config file to configure the build. The resulting build file can then be added to your index.html.