Three.js Troubleshooting

Resolving Import Map Conflicts for THREE and three in Three.js

I spent an hour fighting a cryptic 'module not found' error today caused by inconsistent module naming. When different parts of my dependency tree started expecting 'THREE' while others looked for 'three', the standard import map configuration just fell apart.

Need HDRIs, model references, material inspiration, or scene support to push this Three.js setup further?

Open on 3DCGHub

1. Symptoms of the Module Resolution Failure

The error surfaced immediately upon loading the page: the browser console threw a 404 failure, unable to locate one of the module names while simultaneously ignoring the other. My initial suspicion was a simple syntax error in my JSON import map declaration.

However, double-checking the map revealed the keys were technically valid. The problem wasn't the map syntax itself, but rather how my script tags were attempting to consume those definitions while bypassing the resolution layer entirely.

  • Browser console reporting module fetch failures
  • Conflicting references between uppercase and lowercase keys
  • Inconsistent module resolution patterns across dependencies
  • Direct URL imports interfering with map mapping

2. Why Direct URLs Break Your Mapping

I realized I had accidentally hardcoded full CDN paths in some of my sub-modules. By bypassing the import map, I forced the browser to treat those files as independent origins rather than shared dependencies.

This created a dual-version nightmare where the main entry point tried to share a global state, but the sub-modules loaded their own isolated instances. This discrepancy effectively broke the standard Three.js singleton pattern.

  • Audit script tags for hardcoded URLs
  • Verify that sub-modules are not pulling their own Three.js versions
  • Ensure the entry point relies solely on map aliases
  • Check for version mismatches between core and add-ons

3. Unifying Your Import Strategy

To fix this, I chose a single standard naming convention: lowercase 'three'. I updated the import map to map both potential variants to the same, singular CDN source.

Once I stripped out the hardcoded URLs in my source files and relied exclusively on the mapped alias, the browser stopped attempting to fetch multiple versions of the library.

  • Select a single alias as the project source of truth
  • Update the import map to point all aliases to the same URL
  • Remove all direct URL imports from your codebase
  • Verify all project dependencies use the identical version

4. Confirming the Configuration

After clearing the cache and refreshing, the network tab showed only one successful request for the library. The console warnings regarding missing modules vanished immediately.

I verified that my custom shaders and auxiliary loaders were now correctly attaching to the main Three.js instance without trying to instantiate their own separate libraries.

  • Monitor the browser network tab for duplicate library fetches
  • Test for global namespace collision errors
  • Confirm that version numbers match across all imported files
  • Validate standard import syntax in the application entry file

FAQ

Can I keep both 'THREE' and 'three' in my import map?

Technically yes, but it is a bad practice. It invites version conflicts and duplicate code bloat. It is much safer to map both keys to the same single URL.

Why did my direct URL imports break the import map?

Import maps only intercept bare module specifiers. When you provide a full URL, you bypass the mapping logic entirely, which often leads to loading multiple distinct versions of the library.