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

@molecule/app-three-viewer-react

v1.0.1

Published

WebGL 3D model viewer wrapping three.js — supports GLTF/GLB, OBJ, STL with orbit controls + lighting presets

Readme

@molecule/app-three-viewer-react

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

3D model viewer wrapping three.js.

Exports <ThreeViewer> — a React component that renders GLTF/GLB, OBJ, or STL models with orbit controls, lighting presets (studio/sunset/flat), auto-fit camera, and full GPU resource cleanup on unmount — plus the resolveFormat() and disposeObject3D() helpers and the prop types.

Quick Start

import { ThreeViewer } from '@molecule/app-three-viewer-react'

function ModelPage() {
  // Inline callbacks/arrays are safe — they do not tear down WebGL.
  return (
    <div style={{ height: 480 }}>
      <ThreeViewer
        src="/models/duck.glb"
        lighting="studio"
        autoRotate
        onLoad={() => console.log('loaded')}
      />
    </div>
  )
}

Type

feature

Installation

npm install @molecule/app-three-viewer-react @molecule/app-react @molecule/app-ui @molecule/app-ui-react react three
npm install -D @types/react @types/three

API

Interfaces

ThreeViewerProps

Props for the {@link ThreeViewer} component.

interface ThreeViewerProps {
  /** URL or path to the 3D model file. */
  src: string
  /**
   * Model format. If omitted, inferred from the `src` extension. Falls back
   * to `'gltf'` for unknown extensions.
   */
  format?: ThreeViewerFormat
  /** Lighting preset. Defaults to `'studio'`. */
  lighting?: ThreeViewerLighting
  /** Optional CSS background colour for the canvas (CSS string or hex). */
  background?: string
  /** Slowly rotate the camera around the model. Defaults to `false`. */
  autoRotate?: boolean
  /**
   * Override the orbit camera target (world-space x/y/z). When omitted, the
   * target is automatically set to the centre of the model's bounding box.
   */
  cameraTarget?: [number, number, number]
  /** Fired when the model has loaded into the scene. */
  onLoad?: () => void
  /** Fired when loading fails. */
  onError?: (error: Error) => void
  /** Extra classes merged onto the outer wrapper. */
  className?: string
}

Types

ThreeViewerFormat

Supported 3D model formats.

type ThreeViewerFormat = 'gltf' | 'glb' | 'obj' | 'stl'

ThreeViewerLighting

Lighting presets — drive the scene's light rig.

type ThreeViewerLighting = 'studio' | 'sunset' | 'flat'

Functions

disposeObject3D(root)

Walk an Object3D tree and dispose every geometry, material, and texture so three.js does not leak GPU resources when the viewer unmounts or swaps models.

function disposeObject3D(root: Object3D<Object3DEventMap>): void
  • root — The root node to dispose.

resolveFormat(src, explicit)

Resolve a model format from an explicit prop or the file extension on src.

function resolveFormat(src: string, explicit?: ThreeViewerFormat): ThreeViewerFormat
  • src — The model URL.
  • explicit — The explicit format prop, if provided.

Returns: The resolved format.

ThreeViewer(props)

3D model viewer wrapping three.js.

Supports GLTF/GLB, OBJ, and STL inputs, orbit controls, and a small set of lighting presets. The camera auto-fits to the model's bounding box on load. All three.js GPU resources (geometry, materials, textures, the renderer itself) are disposed on unmount or when the model source (src/format) or scene structure (lighting/background) changes.

The heavy setup (renderer creation + model download) depends ONLY on those inputs; onLoad, onError, cameraTarget, and autoRotate are routed through refs, so passing them inline (fresh arrows / [x,y,z] literals) does NOT tear down the WebGL context or re-download the model on a parent re-render.

function ThreeViewer(props: ThreeViewerProps): JSX.Element
  • props — Component props.

Returns: The rendered viewer.

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-react ^1.0.1
  • @molecule/app-ui ^1.0.1
  • @molecule/app-ui-react ^1.0.1
  • react ^18.0.0 || ^19.0.0

Runtime Dependencies

  • @molecule/app-react

  • @molecule/app-ui

  • @molecule/app-ui-react

  • react

  • three

  • Ships a REAL pinned three dependency — a substantial bundle-size add. Lazy-load the importing route/component (React.lazy / dynamic import) so non-3D pages do not pay for it.

  • The heavy setup effect (renderer creation + model download) depends ONLY on src/format (and lighting/background, which restructure the scene). onLoad, onError, cameraTarget, and autoRotate are routed through refs + light sync effects, so passing them inline (fresh arrows / [x,y,z] literals) does NOT tear down the WebGL context or re-download the model on a parent re-render. Changing src/format reloads the model; changing cameraTarget's value re-aims the camera in place.

  • The wrapper is width/height: 100% with min-height: 240px — give the PARENT an explicit height or the canvas collapses to 240px.

  • Requires WebGL in a real browser: do not render during SSR and do not expect it to work under jsdom tests. Model URLs must be same-origin or CORS-enabled.

  • format is inferred from the src extension (unknown extensions fall back to gltf); pass it explicitly for extension-less URLs.

  • Must render inside the app's i18n provider and with a ClassMap bond wired (loading/error overlays use useTranslation()); translations ship in @molecule/app-locales-feature-three-viewer.