npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fourthtemple/fbx-exporter

v0.1.2

Published

A from-scratch binary FBX exporter for browser and Node character pipelines.

Readme

FBX Exporter

License: MIT FBX Target

A from-scratch, MIT-friendly binary FBX exporter for browser and Node character pipelines.

It exports Three.js-style scenes to FBX while preserving meshes, hierarchy, skeletons, skinning, morphs, materials, textures, and baked animation curves well enough to round-trip through Blender and Three.js FBXLoader.

Why This Exists

FBX export is awkward in browser and Node projects. Blender's exporter is useful as a behavioral reference, but its GPL source cannot be copied into an MIT project. Autodesk's SDK is not browser-friendly. This project keeps the implementation original, modular, and testable.

The exporter is packaged as a standalone ESM module with no runtime dependencies. It is designed for web tools that need direct FBX output from Three.js-style scenes.

Current Status

| Area | Status | | --- | --- | | Binary FBX writer | Deterministic FBX 7400 by default, FBX 7500 wide records supported | | Static mesh export | Geometry, normals, tangents/binormals, UV sets, vertex colors, material slots | | Hierarchy | Meshes, nulls, cameras, lights, transforms, pivots, visibility | | Materials | Lambert/Phong-style output with PBR-to-FBX adaptation and custom lanes | | Textures | Sidecar files, data URLs, raw image buffers, embedded Video.Content, metadata | | Skinning | Limb nodes, skin deformers, clusters, bind poses, inverse bind matrices | | Morphs | Blend shape geometry and morph influence animation | | Animation | Multiple stacks/layers, baked TRS/bone/morph/material/texture curves, key tangents | | Validation | Binary preflight, Three.js FBXLoader, Blender background import reports | | Character workflow | High-level character export helper and animated character fixtures are in place |

Quickstart

import { exportFbx } from "@fourthtemple/fbx-exporter";

const bytes = exportFbx(threeSceneOrObject);

Save the returned Uint8Array as a binary .fbx file.

import { writeFileSync } from "node:fs";
import { exportFbx } from "@fourthtemple/fbx-exporter";

writeFileSync("character.fbx", exportFbx(scene));

Target Presets

Use target to write FBX axis and unit metadata for common importers:

const bytes = exportFbx(scene, { target: "unreal" });

| Target | Up Axis | Front Axis | Unit Scale | Use When | | --- | --- | --- | --- | --- | | threejs | Y | Z | 1 | Round-tripping with Three.js FBXLoader | | unity | Y | Z | 1 | Importing into Unity | | unreal | Z | X | 1 | Importing into Unreal Editor | | blender | Y | Z | 100 | Importing into Blender | | maya | Y | Z | 100 | Importing into Maya-style centimeter scenes |

You can override any preset:

exportFbx(scene, {
  target: "unity",
  upAxis: "Z",
  forwardAxis: "-Y",
  unitScale: 10
});

Presets currently write FBX GlobalSettings axis and unit metadata. They do not bake transforms into mesh vertices, skeleton bind poses, animation curves, lights, or cameras.

Character Export

Use exportCharacterFbx when exporting a rigged character with explicit baked animation clips. Pass the final Three.js object tree plus animation clips, and receive a binary FBX file as a Uint8Array.

import { exportCharacterFbx } from "@fourthtemple/fbx-exporter";

const bytes = exportCharacterFbx({
  object3D: characterRoot,
  animations: bakedClips,
  frameRate: timelineFrameRate
}, {
  resolveTextureContent,
  onWarning: (warning) => console.warn(warning)
});

exportCharacterFbx defaults to:

| Option | Default | Purpose | | --- | --- | --- | | bakeAnimations | true | Export the final evaluated animation curves | | embedTextures | true | Prefer self-contained character exports | | textureTransformMode | "blender" | Better Blender texture-transform round trip | | frameRate | 30 | Default timeline rate when the editor does not provide one |

API

exportFbx(source, options?)

Exports either:

  • a Three.js-like Object3D / Scene
  • a normalized scene model for custom pipelines

Returns a Uint8Array.

exportCharacterFbx(input, options?)

Exports editor-ready character input:

{
  object3D: THREE.Object3D,
  animations?: THREE.AnimationClip[],
  frameRate?: number
}

Returns a Uint8Array.

Common Options

| Option | Type | Notes | | --- | --- | --- | | version | 7400 \| 7500+ | FBX 7400 uses 32-bit node records; 7500+ uses wide records | | target / preset | "threejs" \| "unity" \| "unreal" \| "blender" \| "maya" | Apply importer-oriented axis and unit metadata | | upAxis, forwardAxis, coordAxis | "X" \| "Y" \| "Z" \| "-X" \| "-Y" \| "-Z" | Override target preset axes | | unitScale | number | Override target preset unit scale | | frameRate | number | Scene/global frame rate | | animations | AnimationClip[] | Explicit clips when they are not attached to the object tree | | bakeAnimations | boolean | Bake Three.js interpolated tracks into FBX curve keys | | textureTransformMode | "direct" \| "blender" | Choose direct Three.js-style or Blender-compatible texture transforms | | resolveTextureContent | (fileName, context) => bytes \| { content, mimeType } | Synchronous texture embedding hook | | compressArrayBytes | (bytes) => Uint8Array | Optional FBX Encoding=1 array compression | | embedTextures | boolean | Request embedding and emit warnings for unresolved file textures | | warnings | Array | Collect structured export warnings | | onWarning | (warning) => void | Observe warnings as they are emitted |

Texture Embedding

File-backed textures can be embedded with a synchronous resolver:

import { readFileSync } from "node:fs";
import { exportFbx } from "./src/index.js";

const bytes = exportFbx(scene, {
  embedTextures: true,
  resolveTextureContent: (fileName) => ({
    content: readFileSync(fileName),
    mimeType: "image/tga"
  })
});

The exporter can also pack data URLs, explicit { content, mimeType } texture records, Three.js byte aliases such as content, bytes, or data, and raw one/two/RGB/RGBA image buffers.

Validation

Install dependencies:

npm install

Run the normal gates:

npm run check
npm test

Generate and validate an animated character round-trip fixture:

npm run sample:mixamo:embedded:compressed
npm run validate:mixamo:embedded:compressed

Validate any external FBX file:

npm run validate:file -- /path/to/model.fbx

validate:file produces a JSON report with:

  • binary FBX preflight results
  • Three.js FBXLoader parse results
  • Blender import results
  • mesh/material/texture/skeleton/morph/action counts
  • importer warnings

Some third-party FBX files contain footer bytes after the top-level null record. Generated exporter output remains strict; external validation reports those bytes as warnings so Blender and Three.js can still be tested.

Samples

| Command | Output | | --- | --- | | npm run sample:static | Static cube mesh | | npm run sample:skinned:embedded | Skinned animated mesh with packed texture | | npm run sample:character:embedded:compressed | Skinned character fixture with morph and texture animation | | npm run sample:mixamo:embedded:compressed | Animated character round-trip fixture |

Matching validate:* scripts run binary preflight plus importer checks where applicable.

Feature Coverage

| Three.js / scene input | FBX output | | --- | --- | | Mesh, BufferGeometry | Geometry, Model, normals, tangents, UV layers, vertex colors | | Object3D, Scene, parented nodes | FBX model hierarchy and transforms | | MeshStandardMaterial, MeshPhongMaterial, MeshBasicMaterial | FBX Lambert/Phong-style materials | | Material texture slots | Texture + Video, layered/custom lanes where needed | | Data URLs and raw image buffers | Packed FBX media content | | SkinnedMesh, Skeleton, Bone | Limb nodes, skin deformers, clusters, bind pose | | AnimationClip TRS tracks | AnimationStack, AnimationLayer, curve nodes, curves | | Bone animation | Baked limb-node transform curves | | Morph targets | Shape geometry, blend shape deformers, channel curves | | Cameras and lights | FBX camera/light attributes, models, animation targets | | Custom model/material/texture properties | User-defined FBX properties and animation curves |

Real-World Probes

The validator is designed to run against real character files, not only synthetic fixtures. Those probes expose useful hardening targets:

  • FBX 7700 with a small trailing footer
  • embedded images
  • large mesh and high bone count
  • 79-frame animation
  • source vertices with more than four skin weights, which Three.js trims on import

Those details help guide compatibility work across real-world importers.

Architecture

The project is intentionally split into small domain folders:

| Directory | Purpose | | --- | --- | | src/three/ | Three.js adapters and Three.js-specific extraction | | src/scene/ | normalized scene model and sample scenes | | src/geometry/, src/skeleton/, src/morph/ | mesh, skinning, and blend-shape data | | src/material/, src/texture/, src/light/, src/camera/ | render-facing FBX features | | src/animation/ | shared animation timing, key, and track helpers | | src/document/ | FBX object/connection/definition assembly | | src/core/, src/node/ | binary writer and low-level FBX node utilities | | src/export/, src/validation/ | public export adapters and validation support |

Low-level code never imports Three.js adapters, and adapters do not write FBX nodes directly. The architecture guard test keeps production files under a line budget and enforces layer boundaries.

See docs/architecture.md for the full extension pattern.

Roadmap

  1. Build a broader fixture corpus from real edited characters.
  2. Harden skin-weight export/import behavior around assets with more than four influences per vertex.
  3. Improve animation fidelity for root/hips travel, loop blends, pre/post rotations, bind pose, and edited key ranges.
  4. Expand texture/material compatibility with Blender, Three.js, Unity, and Unreal importers.
  5. Add side-by-side benchmark tests against other MIT exporters such as @comfyorg/fbx-exporter-three.

License

MIT. Blender's FBX exporter is treated as behavioral reference only; no GPL source is copied into this project.