# Wooden Crate

> A sturdy low-poly wooden crate with a dark corner frame, individually tinted planks and a diagonal brace on every visible face. Switch to the slatted style for a gappy produce crate. Ideal for warehouses, docks, villages and loot spots in RPG and survival games.

![Wooden Crate preview](https://codels.download/m/wooden-crate.png)

Multi-view sheet (3/4, front, side, top): https://codels.download/m/wooden-crate.sheet.png

## Facts

- Category: Props › Containers
- Size (W × H × D): 0.90 × 0.90 × 0.90 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 576 · Meshes: 48 · Materials: 6
- License: CC0-1.0 (Codels built-in)
- Tags: crate, low-poly, stylized, medieval, nautical, pirate, village, adventure, rpg, survival, container, obstacle, prop, wood, boxy-shape, game-ready, instancing-friendly, mobile-friendly, parametric, color-brown, color-orange, size-small, poly-low
- Page: https://codels.download/models/wooden-crate

## Files

| Format | URL |
|---|---|
| three.js ES module (`createWoodenCrate()`) | https://codels.download/m/wooden-crate.js |
| React Three Fiber component (`<WoodenCrate />`) | https://codels.download/m/wooden-crate.jsx |
| Instancing module (`createWoodenCrateInstances(count, place)`, one draw call per material) | https://codels.download/m/wooden-crate.instanced.js |
| Standalone HTML demo | https://codels.download/m/wooden-crate.html |
| glTF binary | https://codels.download/m/wooden-crate.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/wooden-crate.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/wooden-crate.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/wooden-crate.obj · https://codels.download/m/wooden-crate.mtl |
| STL | https://codels.download/m/wooden-crate.stl |
| CodelSpec JSON | https://codels.download/m/wooden-crate.json |

## Parameters

Append them as query parameters to any URL above to get a customized variant (e.g. `?size=...`).

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `size` | number | 0.5 – 1.5 | 0.9 | 0.9 |
| `wood` | color | #rrggbb | #b07a43 | #b07a43 |
| `style` | select | braced \| slatted | braced | braced |
| `seed` | int | 1 – 99 | 7 | 7 |

## Parts

- post (box · frame)
- post (box · frame)
- post (box · frame)
- post (box · frame)
- beam (box · frame)
- beam (box · frame)
- beam (box · frame)
- beam (box · frame)
- beam (box · frame)
- beam (box · frame)
- beam (box · frame)
- beam (box · frame)
- core (box · inner)
- front (group)
  - plank (box · plankDark)
  - plank (box · plankDark)
  - plank (box · plank)
  - plank (box · plank)
  - brace (box · frame)
  - nail (box · nail)
  - nail (box · nail)
- right (group)
  - plank (box · plankAlt)
  - plank (box · plankAlt)
  - plank (box · plank)
  - plank (box · plankDark)
  - brace (box · frame)
  - nail (box · nail)
  - nail (box · nail)
- back (group)
  - plank (box · plank)
  - plank (box · plank)
  - plank (box · plankAlt)
  - plank (box · plank)
  - brace (box · frame)
  - nail (box · nail)
  - nail (box · nail)
- left (group)
  - plank (box · plankAlt)
  - plank (box · plankAlt)

## How to use

Save the code below as `wooden-crate.js`, then:

```js
import { createWoodenCrate } from './wooden-crate.js';
const model = createWoodenCrate();
scene.add(model);
```

## Code

```js
/**
 * Wooden Crate — Codels 3D model library (https://codels.download/models/wooden-crate)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 576 · Size (W × H × D): 0.90 × 0.90 × 0.90 m
 *
 * Usage:
 *   import { createWoodenCrate } from './wooden-crate.js';
 *   
 *   const model = createWoodenCrate();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

export function createWoodenCrate() {
  const root = new THREE.Group();
  root.name = 'WoodenCrate';

  // Materials
  const plankMat = new THREE.MeshStandardMaterial({ name: 'plank', color: 0xb07a43, roughness: 0.9, flatShading: true });
  const plankAltMat = new THREE.MeshStandardMaterial({ name: 'plankAlt', color: 0xc2864a, roughness: 0.9, flatShading: true });
  const plankDarkMat = new THREE.MeshStandardMaterial({ name: 'plankDark', color: 0x9e6e3c, roughness: 0.9, flatShading: true });
  const frameMat = new THREE.MeshStandardMaterial({ name: 'frame', color: 0x78532e, roughness: 0.92, flatShading: true });
  const innerMat = new THREE.MeshStandardMaterial({ name: 'inner', color: 0x382715, roughness: 1, flatShading: true });
  const nailMat = new THREE.MeshStandardMaterial({ name: 'nail', color: 0x3b3b40, roughness: 0.5, metalness: 0.5, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.09, 0.9, 0.09);
  const boxGeo2 = new THREE.BoxGeometry(0.74, 0.09, 0.09);
  const boxGeo3 = new THREE.BoxGeometry(0.09, 0.09, 0.74);
  const boxGeo4 = new THREE.BoxGeometry(0.74, 0.1767, 0.0225);
  const boxGeo5 = new THREE.BoxGeometry(1.0182, 0.0765, 0.019);
  const boxGeo6 = new THREE.BoxGeometry(0.0144, 0.0144, 0.006);

  // Parts
  const post = new THREE.Mesh(boxGeo, frameMat);
  post.name = 'post';
  post.position.set(-0.405, 0.45, -0.405);
  root.add(post);
  const post2 = new THREE.Mesh(boxGeo, frameMat);
  post2.name = 'post';
  post2.position.set(0.405, 0.45, -0.405);
  root.add(post2);
  const post3 = new THREE.Mesh(boxGeo, frameMat);
  post3.name = 'post';
  post3.position.set(0.405, 0.45, 0.405);
  root.add(post3);
  const post4 = new THREE.Mesh(boxGeo, frameMat);
  post4.name = 'post';
  post4.position.set(-0.405, 0.45, 0.405);
  root.add(post4);
  const beam = new THREE.Mesh(boxGeo2, frameMat);
  beam.name = 'beam';
  beam.position.set(0, 0.049, -0.401);
  root.add(beam);
  const beam2 = new THREE.Mesh(boxGeo3, frameMat);
  beam2.name = 'beam';
  beam2.position.set(-0.401, 0.049, 0);
  root.add(beam2);
  const beam3 = new THREE.Mesh(boxGeo2, frameMat);
  beam3.name = 'beam';
  beam3.position.set(0, 0.049, 0.401);
  root.add(beam3);
  const beam4 = new THREE.Mesh(boxGeo3, frameMat);
  beam4.name = 'beam';
  beam4.position.set(0.401, 0.049, 0);
  root.add(beam4);
  const beam5 = new THREE.Mesh(boxGeo2, frameMat);
  beam5.name = 'beam';
  beam5.position.set(0, 0.851, -0.401);
  root.add(beam5);
  const beam6 = new THREE.Mesh(boxGeo3, frameMat);
  beam6.name = 'beam';
  beam6.position.set(-0.401, 0.851, 0);
  root.add(beam6);
  const beam7 = new THREE.Mesh(boxGeo2, frameMat);
  beam7.name = 'beam';
  beam7.position.set(0, 0.851, 0.401);
  root.add(beam7);
  const beam8 = new THREE.Mesh(boxGeo3, frameMat);
  beam8.name = 'beam';
  beam8.position.set(0.401, 0.851, 0);
  root.add(beam8);
  const core = new THREE.Mesh(new THREE.BoxGeometry(0.801, 0.801, 0.801), innerMat);
  core.name = 'core';
  core.position.set(0, 0.45, 0);
  root.add(core);
  const front = new THREE.Group();
  front.name = 'front';
  front.position.set(0, 0.45, 0);
  root.add(front);
  const plank = new THREE.Mesh(boxGeo4, plankDarkMat);
  plank.name = 'plank';
  plank.position.set(0, -0.2809, 0.4118);
  plank.rotation.set(0, 0, deg(-0.384));
  front.add(plank);
  const plank2 = new THREE.Mesh(boxGeo4, plankDarkMat);
  plank2.name = 'plank';
  plank2.position.set(0, -0.0932, 0.4118);
  plank2.rotation.set(0, 0, deg(-0.2039));
  front.add(plank2);
  const plank3 = new THREE.Mesh(boxGeo4, plankMat);
  plank3.name = 'plank';
  plank3.position.set(0, 0.0967, 0.4118);
  front.add(plank3);
  const plank4 = new THREE.Mesh(boxGeo4, plankMat);
  plank4.name = 'plank';
  plank4.position.set(0, 0.2813, 0.4118);
  plank4.rotation.set(0, 0, deg(-0.2668));
  front.add(plank4);
  const brace = new THREE.Mesh(boxGeo5, frameMat);
  brace.name = 'brace';
  brace.position.set(0, 0, 0.4325);
  brace.rotation.set(0, 0, deg(45));
  front.add(brace);
  const nail = new THREE.Mesh(boxGeo6, nailMat);
  nail.name = 'nail';
  nail.position.set(-0.3105, -0.3105, 0.444);
  front.add(nail);
  const nail2 = new THREE.Mesh(boxGeo6, nailMat);
  nail2.name = 'nail';
  nail2.position.set(0.3105, 0.3105, 0.444);
  front.add(nail2);
  const right = new THREE.Group();
  right.name = 'right';
  right.position.set(0, 0.45, 0);
  right.rotation.set(0, deg(90), 0);
  root.add(right);
  const plank5 = new THREE.Mesh(boxGeo4, plankAltMat);
  plank5.name = 'plank';
  plank5.position.set(0, -0.2805, 0.4118);
  plank5.rotation.set(0, 0, deg(-0.0787));
  right.add(plank5);
  const plank6 = new THREE.Mesh(boxGeo4, plankAltMat);
  plank6.name = 'plank';
  plank6.position.set(0, -0.0945, 0.4118);
  plank6.rotation.set(0, 0, deg(-0.1812));
  right.add(plank6);
  const plank7 = new THREE.Mesh(boxGeo4, plankMat);
  plank7.name = 'plank';
  plank7.position.set(0, 0.092, 0.4118);
  plank7.rotation.set(0, 0, deg(-0.1368));
  right.add(plank7);
  const plank8 = new THREE.Mesh(boxGeo4, plankDarkMat);
  plank8.name = 'plank';
  plank8.position.set(0, 0.2841, 0.4118);
  plank8.rotation.set(0, 0, deg(0.0598));
  right.add(plank8);
  const brace2 = new THREE.Mesh(boxGeo5, frameMat);
  brace2.name = 'brace';
  brace2.position.set(0, 0, 0.4325);
  brace2.rotation.set(0, 0, deg(-45));
  right.add(brace2);
  const nail3 = new THREE.Mesh(boxGeo6, nailMat);
  nail3.name = 'nail';
  nail3.position.set(0.3105, -0.3105, 0.444);
  right.add(nail3);
  const nail4 = new THREE.Mesh(boxGeo6, nailMat);
  nail4.name = 'nail';
  nail4.position.set(-0.3105, 0.3105, 0.444);
  right.add(nail4);
  const back = new THREE.Group();
  back.name = 'back';
  back.position.set(0, 0.45, 0);
  back.rotation.set(0, deg(180), 0);
  root.add(back);
  const plank9 = new THREE.Mesh(boxGeo4, plankMat);
  plank9.name = 'plank';
  plank9.position.set(0, -0.2804, 0.4118);
  plank9.rotation.set(0, 0, deg(0.1974));
  back.add(plank9);
  const plank10 = new THREE.Mesh(boxGeo4, plankMat);
  plank10.name = 'plank';
  plank10.position.set(0, -0.0945, 0.4118);
  plank10.rotation.set(0, 0, deg(-0.417));
  back.add(plank10);
  const plank11 = new THREE.Mesh(boxGeo4, plankAltMat);
  plank11.name = 'plank';
  plank11.position.set(0, 0.0963, 0.4118);
  plank11.rotation.set(0, 0, deg(0.0451));
  back.add(plank11);
  const plank12 = new THREE.Mesh(boxGeo4, plankMat);
  plank12.name = 'plank';
  plank12.position.set(0, 0.2792, 0.4118);
  plank12.rotation.set(0, 0, deg(0.39));
  back.add(plank12);
  const brace3 = new THREE.Mesh(boxGeo5, frameMat);
  brace3.name = 'brace';
  brace3.position.set(0, 0, 0.4325);
  brace3.rotation.set(0, 0, deg(45));
  back.add(brace3);
  const nail5 = new THREE.Mesh(boxGeo6, nailMat);
  nail5.name = 'nail';
  nail5.position.set(-0.3105, -0.3105, 0.444);
  back.add(nail5);
  const nail6 = new THREE.Mesh(boxGeo6, nailMat);
  nail6.name = 'nail';
  nail6.position.set(0.3105, 0.3105, 0.444);
  back.add(nail6);
  const left = new THREE.Group();
  left.name = 'left';
  left.position.set(0, 0.45, 0);
  left.rotation.set(0, deg(270), 0);
  root.add(left);
  const plank13 = new THREE.Mesh(boxGeo4, plankAltMat);
  plank13.name = 'plank';
  plank13.position.set(0, -0.2822, 0.4118);
  plank13.rotation.set(0, 0, deg(-0.105));
  left.add(plank13);
  const plank14 = new THREE.Mesh(boxGeo4, plankAltMat);
  plank14.name = 'plank';
  plank14.position.set(0, -0.0928, 0.4118);
  plank14.rotation.set(0, 0, deg(-0.3613));
  left.add(plank14);
  const plank15 = new THREE.Mesh(boxGeo4, plankMat);
  plank15.name = 'plank';
  plank15.position.set(0, 0.0927, 0.4118);
  plank15.rotation.set(0, 0, deg(0.2348));
  left.add(plank15);
  const plank16 = new THREE.Mesh(boxGeo4, plankMat);
  plank16.name = 'plank';
  plank16.position.set(0, 0.2785, 0.4118);
  plank16.rotation.set(0, 0, deg(0.4016));
  left.add(plank16);
  const brace4 = new THREE.Mesh(boxGeo5, frameMat);
  brace4.name = 'brace';
  brace4.position.set(0, 0, 0.4325);
  brace4.rotation.set(0, 0, deg(-45));
  left.add(brace4);
  const nail7 = new THREE.Mesh(boxGeo6, nailMat);
  nail7.name = 'nail';
  nail7.position.set(0.3105, -0.3105, 0.444);
  left.add(nail7);
  const nail8 = new THREE.Mesh(boxGeo6, nailMat);
  nail8.name = 'nail';
  nail8.position.set(-0.3105, 0.3105, 0.444);
  left.add(nail8);
  const top = new THREE.Group();
  top.name = 'top';
  top.position.set(0, 0.45, 0);
  top.rotation.set(deg(-90), 0, 0);
  root.add(top);
  const plank17 = new THREE.Mesh(boxGeo4, plankDarkMat);
  plank17.name = 'plank';
  plank17.position.set(0, -0.2784, 0.4118);
  plank17.rotation.set(0, 0, deg(0.3065));
  top.add(plank17);
  const plank18 = new THREE.Mesh(boxGeo4, plankMat);
  plank18.name = 'plank';
  plank18.position.set(0, -0.0928, 0.4118);
  plank18.rotation.set(0, 0, deg(0.371));
  top.add(plank18);
  const plank19 = new THREE.Mesh(boxGeo4, plankAltMat);
  plank19.name = 'plank';
  plank19.position.set(0, 0.0923, 0.4118);
  plank19.rotation.set(0, 0, deg(-0.1143));
  top.add(plank19);
  const plank20 = new THREE.Mesh(boxGeo4, plankDarkMat);
  plank20.name = 'plank';
  plank20.position.set(0, 0.2806, 0.4118);
  plank20.rotation.set(0, 0, deg(-0.0071));
  top.add(plank20);
  const brace5 = new THREE.Mesh(boxGeo5, frameMat);
  brace5.name = 'brace';
  brace5.position.set(0, 0, 0.4325);
  brace5.rotation.set(0, 0, deg(-45));
  top.add(brace5);
  const nail9 = new THREE.Mesh(boxGeo6, nailMat);
  nail9.name = 'nail';
  nail9.position.set(0.3105, -0.3105, 0.444);
  top.add(nail9);
  const nail10 = new THREE.Mesh(boxGeo6, nailMat);
  nail10.name = 'nail';
  nail10.position.set(-0.3105, 0.3105, 0.444);
  top.add(nail10);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createWoodenCrate;
```

---
Codels — 3D models as code for three.js. Search more: https://codels.download/api/v1/models?q=<query> · Guide: https://codels.download/llms.txt
