THREE.Geometry will be removed from core with r125

The upcoming release r125 will contain a major, potentially breaking change. The class THREE.Geometry will be no longer part of the core but moved to jsm/deprecated/Geometry.js. It will only be available as an ES6 module and not as a global script.

What does that mean for me?

If you are loading your assets with one of the official loaders like GLTFLoader or procedurally generate geometry data with THREE.BufferGeometry, this change won’t affect you. If you are using THREE.Geometry, please note the following changes:

  • THREE.Geometry is no longer renderable and can’t be used to create 3D objects (meshes, lines, points) anymore.
  • All geometry related library features like raycasting, helpers or exporters do not support THREE.Geometry anymore.
  • All geometry generators (like THREE.BoxGeometry) produce THREE.BufferGeometry now.


It’s actually best if you directly work with THREE.BufferGeometry. If your project budget is tight and you can’t afford to refactor your code from scratch, you have the possibility to convert your instances of THREE.Geometry to THREE.BufferGeometry with two new methods:

  1. Geometry.toBufferGeometry() is the default method for converting a mesh geometry to THREE.BufferGeometry. It is used like so:
const bufferGeometry = geometry.toBufferGeometry();
  1. All faceless geometries (lines and points) have to use the static method Geometry.createBufferGeometryFromObject(). You have to pass in the 3D object so it’s possible for the code to detect the type of render primitive (points, lines, meshes):
const bufferGeometry = Geometry.createBufferGeometryFromObject( points );


Deprecating THREE.Geometry and focusing on THREE.BufferGeometry as our main geometry class was decided years ago and we are happy to finally remove it with r125. This will allow us to reduce the complexity of various engine components and make the maintenance and development process more easy. Besides, by forcing users into THREE.BufferGeometry they automatically work with the more efficient and future-proof geometry representation.


In the future there might be a point where we rename THREE.BufferGeometry to THREE.Geometry (but keep THREE.BufferGeometry as an alias). It’s also possible that more concrete geometry classes will be introduced (MeshGeometry, LineGeometry and PointsGeometry) that make it easier for the engine to detect the actual type of geometry.


Is this essentially what people refer to as a breaking change? If i upgrade to 125, my project wont work if i refer to THREE.Geometry?

Yes, it is a breaking change. You will have to move away from THREE.Geometry or at least convert your geometries to THREE.BufferGeometry.

Let me make this more clear in the original post^^.


This seems curious … with a breaking change this massive, why is BufferGeometry not named Geometry now instead of breaking our projects again in a year or so? Wouldn’t it be better to make it quick and painless, just be done with it? It seems counterproductive to break code but shy away from a small naming inconsistency given that the code breaks anyway, and then break everything … again. Could you still consider it?

1 Like

Use of Geometry has been discouraged for a long time, and we’ve removed its support from many parts of three.js already. For any projects that have been reading the deprecation warnings and moving to BufferGeometry as advised, r125 will not be a breaking change at all. Personally, I don’t think we should rename BufferGeometry to Geometry now or in the future, it does not seem like enough benefit for the cost and potential confusion.


r125 will not be a breaking change at all

How can it not be a breaking change if geometry is removed? I’m for removal, don’t get me wrong, but if 125 breaks code, and it looks like it will, it would be great if it could be one strike instead of two. Personally, i would enjoy not having to write “Buffer” if it can be avoided. In any other project this would be a semver major, and everything’s permitted in a hard change to a new major.

1 Like

With a semver major, this feels like it would be a non-event though?

Looks like it will only be one break for people not using ‘BufferGeometry’ and none for those that do…

@Mugen87 would this be more effective/quicker than just renaming ‘Geometry’ to ‘BufferGeometry’ in a project? For instance just using notepad++ to rename all instances at once?

Right — Geometry has been deprecated for a long time, and no project written in the past couple of years should have been using it. If you’re already using BufferGeometry, and I expect most projects are, then upgrading from r124 -> r125 will not change anything.

In other words, renaming “BufferGeometry” to “Geometry” now would make this a major change for all users, with no prior warning. As it is, it’s a major change for only a subset of users, with quite a bit of prior warning.

If your project was using Geometry anyway, this would be a great time to upgrade. But if you can’t do that yet you can still import it from the examples/jsm/deprecated folder.


one question, the only place i’ve had to use cube geometry is to detect collisions with other objects in “collidableMeshList[]” like this… where MovingCube is a CubeGeometry…

var originPoint = MovingCube.position.clone();

for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
var directionVector = globalVertex.sub( MovingCube.position );

var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
var collisionResults = ray.intersectObjects( collidableMeshList );

in r124 if i try to make MovingCube a BoxBufferGeometry it actually breaks the code as it can’t determine geometry.vertices.length, all meshes pushed to collidableMeshList[] use BoxBufferGeometry so bit confused…

will this not be a problem in r125 if updating MovingCube to a BoxBufferGeometry? or would i have to refer to this…?

edit: is there a different syntax to detect vertices of a buffer geometry? are vertices not accessable on buffer geometry or do they need to be declared in a Float32Array first?

I think someone on discord mentioned that removing Geometry is one thing, but renaming BufferGeometry to Geometry will absolutely confuse anyone trying to learn three.js with tutorials / guides / videos / courses.

If you get an error in the console that Geometry doesn’t exist - that’s pretty straight forward. It doesn’t exist -> go to docs -> learn about BufferGeometry (or just Google: “why doesn’t Three.Geometry exist?”)

But if you follow some tutorial that uses old Geometry, and you use new Geometry - then only half of the methods work, the other half doesn’t seem to exist at all, and nothing works as described in the tutorial - it’s mind bending for a beginner, and searching Google / SO for “why doesn’t [this] in Three.Geometry work” will then likely lead to outdated answers about the original Geometry.

It’d feel kinda like placing this in a beginners code.


@forerunrun Your code will definitely not work with r125 even if you include THREE.Geometry from the examples since raycasting does not support THREE.Geometry anymore. So you will have to learn how to work with BufferGeometry.

As a small teaser, you iterate through all vertices like so:

const positionAttribute = MovingCube.geometry.getAttribute( 'position' );

const localVertex = new THREE.Vector3();
const globalVertex = new THREE.Vector3();

for ( let vertexIndex = 0; vertexIndex < positionAttribute.count; vertexIndex ++ ) {

	localVertex.fromBufferAttribute( positionAttribute, vertexIndex );
	globalVertex.copy( localVertex ).applyMatrix4( MovingCube.matrixWorld );


Notice that you have no clone() operation in your for loop anymore which is good for performance. Besides, always use matrixWorld if you want to transform something to world space.


amazing! thanks for the pointers and clarification, the fact that of course THREE.Geometry would be stripped from support of raycasting went completely over my head… i do need to learn how to properly work with BufferGeometry and this is the perfect time to do so!

1 Like

I don’t think we should rename THREE.BufferGeometry to THREE.Geometry, it would be too confusing.

I suggested introducing THREE.MeshGeometry, THREE.LineGeometry and THREE.PointsGeometry (which would extend THREE.BufferGeometry) as a solution for prettifying the API.


@Mugen87 I did try try to implement this exact solution to my collision detections but it failed to detect any collisions…

Is there something I am missing here?

The code looks like what I have provided. It’s best if you create a new topic with a live example. We can then debug the code.

Yes apologies it is a seperate tangential topic. Will create one

1 Like

Does BufferGeometry have an equivalent to Geometry.mergeMesh()?

The closest method is BufferGeometryUtils.mergeBufferGeometries([a, b, c, d, ...]), but when using it you would need to first apply the world transform of each mesh to its geometry.