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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@heliguy-xyz/splat-viewer

v1.0.0-rc.17

Published

A standalone 3D Gaussian Splat viewer web component with multi-model support, transform system, fly camera, and scene configuration

Readme

Heliguy Web Viewer

A self-contained 3D Gaussian Splat viewer web component built with PlayCanvas for high-performance rendering of point cloud data. Framework-agnostic and embeddable in any web application with zero external dependencies.

Features

  • 🎯 Gaussian Splat Rendering: Native support for .splat files using PlayCanvas
  • 📊 PLY Support: Traditional point cloud rendering for .ply and .ply.compressed formats
  • 📦 SOG Support: Native support for .sog (Spatially Ordered Gaussians) files
  • 🎮 Interactive Controls: Smooth camera navigation and manipulation
  • 🧭 Navigation Cube: Interactive 3D cube for quick camera orientation control
  • 📈 Performance Monitoring: Real-time rendering statistics
  • High Performance: WebGL2-powered rendering with PlayCanvas engine
  • 📱 Responsive Design: Full-screen immersive viewing experience
  • 🔧 Self-Contained: Single file with bundled PlayCanvas engine (2MB)
  • 🎨 Built-in Loading: Professional loading spinner with orange/black theme
  • 🚀 Zero Dependencies: No external scripts required

Enhanced Features (v1.0.0)

  • 🎭 Multi-Model Support: Load and manage multiple models in the same scene
  • 🔄 Transform System: Programmatically position, rotate, and scale models
  • 🎥 Fly Camera Mode: First-person WASD + mouse-look navigation with configurable controls
  • 🎨 Scene Configuration: Adjust FOV and background color with smooth animations
  • 📡 Comprehensive Events: React to model lifecycle, transforms, camera changes, and more
  • 📘 TypeScript Support: Full type definitions for all APIs

Quick Start

Installation

Via npm (Recommended)

npm install @heliguy/web-viewer

Via CDN

<!-- UMD Bundle -->
<script src="https://unpkg.com/@heliguy/[email protected]/dist/web-component/splat-viewer.min.js"></script>

<!-- ESM Bundle -->
<script type="module">
  import '@heliguy/web-viewer/esm'
</script>

Prerequisites

  • Modern browser with WebGL2 support
  • Node.js ≥18.0.0 (for development only)

Usage

Vanilla HTML

<!DOCTYPE html>
<html>
  <head>
    <title>3D Splat Viewer</title>
  </head>
  <body>
    <splat-viewer
      id="viewer"
      width="100%"
      height="600px"
      auto-focus
      enable-navigation-cube
    ></splat-viewer>

    <!-- Import from npm package -->
    <script src="node_modules/@heliguy/web-viewer/dist/web-component/splat-viewer.min.js"></script>

    <script>
      const viewer = document.getElementById('viewer')
      viewer.addEventListener('ready', () => {
        viewer.load('path/to/model.splat')
      })
    </script>
  </body>
</html>

Embed via iframe

Use the provided viewer.html page that reads query parameters and configures the web component. Host viewer.html alongside dist/web-component/splat-viewer.min.js.

Supported query params:

  • src (required): URL to your model (encode it!)
  • width (optional): CSS width (e.g. 100%, 800px)
  • height (optional): CSS height (e.g. 100vh, 600px)
  • autoFocus (optional): true | false (default: true)
  • stats (optional): true | false

Example:

<iframe
  src="https://your-domain.com/viewer.html?src=https%3A%2F%2Fcdn.yourdomain.com%2Fmodels%2FRyhope.ply&width=100%25&height=100vh&autoFocus=true"
  width="100%"
  height="600"
  style="border:0; background:#000"
  allowfullscreen
></iframe>

Notes:

  • Ensure CORS allows the viewer origin to fetch the model (Access-Control-Allow-Origin).
  • Prefer hosting viewer.html, the bundle, and models on the same domain to avoid CORS.
  • URL-encode the src value.

React / Next.js

import { useEffect, useRef } from 'react'
import '@heliguy/web-viewer'

function App() {
  const viewerRef = useRef<any>(null)

  useEffect(() => {
    const viewer = viewerRef.current
    if (!viewer) return

    const handleReady = () => {
      viewer.load('/models/scene.splat')
    }

    viewer.addEventListener('ready', handleReady)
    return () => viewer.removeEventListener('ready', handleReady)
  }, [])

  return (
    <splat-viewer
      ref={viewerRef}
      width="100%"
      height="600px"
      auto-focus
    />
  )
}

TypeScript: Add to your global.d.ts:

declare namespace JSX {
  interface IntrinsicElements {
    'splat-viewer': React.DetailedHTMLProps<
      React.HTMLAttributes<HTMLElement> & {
        ref?: React.Ref<any>
        src?: string
        width?: string
        height?: string
        'auto-focus'?: boolean
        'enable-stats'?: boolean
      },
      HTMLElement
    >
  }
}

Vue 3

<template>
  <splat-viewer
    ref="viewerRef"
    width="100%"
    height="600px"
    auto-focus
  />
</template>

<script setup>
import { ref, onMounted } from 'vue'
import '@heliguy/web-viewer'

const viewerRef = ref(null)

onMounted(() => {
  const viewer = viewerRef.value
  const handleReady = () => {
    viewer.load('/models/scene.splat')
  }
  viewer.addEventListener('ready', handleReady)
})
</script>

Commands

| Command | Description | | ----------------------------- | ---------------------------------- | | npm run web-component:serve | Start development server | | npm run web-component:build | Build self-contained web component | | npm run web-component:clean | Clean build artifacts | | npm run lint | Check code quality with ESLint | | npm run lint:fix | Fix linting issues automatically | | npm run format | Format code with Prettier | | npm run format:check | Check code formatting |

Web Component API

Attributes

Basic Configuration

  • src - Model file path or URL
  • width - Canvas width (default: "100%")
  • height - Canvas height (default: "400px")
  • auto-focus - Auto-focus on load (default: true)
  • enable-stats - Show performance stats (default: false)
  • max-splats - Maximum splat count (default: 2000000)

Camera Controls

  • orbit-sensitivity - Mouse orbit sensitivity (default: 0.3)
  • pan-sensitivity - Mouse pan sensitivity (default: 0.5)
  • zoom-sensitivity - Mouse zoom sensitivity (default: 0.1)
  • min-distance - Minimum camera distance (default: 1)
  • max-distance - Maximum camera distance (default: 100)

Navigation Cube

  • enable-navigation-cube - Show interactive navigation cube (default: false)
  • navigation-cube-size - Cube size in pixels (default: 120)
  • navigation-cube-transition - Camera transition duration in ms (default: 800)

Events

Core Events

  • ready - Component initialized
  • loading-start - Model loading started
  • loading-progress - Model loading progress update
  • loaded - Model loaded successfully
  • error - Loading error occurred
  • stats-update - Performance statistics update
  • camera-change - Camera position/target changed
  • interaction-start / interaction-end - User interaction with orbit controls

Multi-Model Events (v1.0.0)

  • model-added - Model added to scene
  • model-removed - Model removed from scene
  • scene-cleared - All models cleared

Transform Events (v1.0.0)

  • model-transform-changed - Model transform updated

Camera Events (v1.0.0)

  • camera-mode-changed - Camera mode switched (orbit/fly)
  • fly-camera-move - Fly camera position changed
  • fly-camera-look - Fly camera rotation changed

Scene Config Events (v1.0.0)

  • camera-fov-changed - Camera FOV changed
  • background-color-changed - Background color changed

Project Structure

src/
├── web-component/        # Main web component implementation
│   ├── SplatViewerElement.ts    # Web component class
│   ├── SplatViewerCore.ts       # Core rendering engine
│   ├── NavigationCubeController.ts  # Navigation cube controller
│   ├── OrbitCameraScript.ts     # Camera controls
│   ├── navigation-cube/     # Navigation cube modules
│   │   ├── CubeRenderer.ts           # 3D cube visual rendering
│   │   ├── ControlPointManager.ts    # Control point UI elements
│   │   └── CameraTransitionController.ts  # Camera animations
│   ├── types/           # TypeScript definitions
│   ├── loader/          # File loading system (.ply, .sog, .splat)
│   └── utils/           # Utility functions
├── build/               # Build configuration
├── dist/web-component/  # Built self-contained web component
│   └── splat-viewer.min.js  # Single 2MB file with PlayCanvas
├── test-web-component.html  # Basic test page
└── test-navigation-cube.html  # Navigation cube test page

assets/                  # 3D model assets for testing
docs/                    # Documentation

Supported File Formats

  • .sog - Spatially Ordered Gaussians (PlayCanvas native support)
  • .splat - Gaussian Splat files (PlayCanvas native support)
  • .ply - Point cloud files (standard format)
  • .ply.compressed - Compressed PLY files (gzip/deflate)

Self-Contained Bundle

The web component is distributed as a single 2MB file (splat-viewer.min.js) that includes:

  • Complete PlayCanvas engine (v2.11.8)
  • Web component implementation
  • File format loaders
  • Performance monitoring
  • Interactive controls

Benefits:

  • Zero external dependencies
  • Version consistency guaranteed
  • Easy embedding in any web application
  • Offline functionality

Development

# Start development server
npm run web-component:serve

# Build for production
npm run web-component:build

# Clean build artifacts
npm run web-component:clean

Deployment

Netlify

  • Publish directory: dist
  • Build command: npm run build
  • Node version: 18 (configured in netlify.toml)

The build emits dist/index.html from viewer.html using a small zero-dependency Node script (build/copy-viewer-to-index.mjs). Rollup uses an ESM config at build/rollup.config.mjs.

License

MIT License - see LICENSE file for details.