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

@linear_non/stellar-gl

v1.6.3

Published

WebGL setup & helpers for Non-Linear Studio projects.

Readme

stellar-gl

@linear_non/stellar-gl — WebGL / Three.js layer for Non-Linear Studio projects.

A lightweight and modular WebGL layer built on top of Three.js, designed to integrate seamlessly with stellar-kit. Supports full-page single-canvas setups and per-DOM-element modular GL components.

Installation

npm install @linear_non/stellar-gl

Requires three and @linear_non/stellar-kit:

npm install three @linear_non/stellar-kit

@theatre/core is bundled as a direct dependency — no additional install needed.
For the editor UI, install in devDependencies only: npm install -D @theatre/studio


Package exports

@linear_non/stellar-gl/classes   → classes/index.js
@linear_non/stellar-gl/utils     → utils/index.js
@linear_non/stellar-gl/three     → libraries/three/index.js
@linear_non/stellar-gl/loaders   → loaders/index.js
@linear_non/stellar-gl/shaders/* → shaders/*
@linear_non/stellar-gl/decoders/* → decoders/*

Classes

| Class | Description | | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | App | Main entry point. Wires stellar-kit events → world + canvas lifecycle. Supports ManagerClass / managerOptions for swappable managers | | Canvas | Owns scene, camera instance, and renderer | | Camera | PerspectiveCamera / OrthographicCamera wrapper with getViewSize() | | Renderer | THREE.WebGLRenderer wrapper (alpha, high-performance, DPR capped at 2, AA off) | | RenderTarget | THREE.WebGLRenderTarget wrapper with size-change guard | | Materials | Caching material + HDR env map manager (auto-unwraps renderer wrapper) | | PostPass | Full-screen post-processing: scene → RT → custom ShaderMaterial quad | | ShaderPlane | PlaneGeometry(1,1) + ShaderMaterial — fullscreen or DOM-tracked, with built-in uTime / uResolution uniforms | | TextGL | Troika-powered 3D text — standalone or DOM-tracked with CSS-driven responsive sizing via getTextStyles | | GLSpritePlayer | KTX2 compressed sprite sequence player on a ShaderPlane — two-phase loading, scroll-driven playback, cover-fit rendering | | WorldManager | Per-DOM-element GL component manager ([data-{name}] selectors) — always-on, all components tick every frame | | ScrollableWM | Extends WorldManager — adds isActive gating, scrollProgress (0→1), and onEnter/onLeave lifecycle hooks | | SceneManager | Multi-scene manager with RT-based transitions — pluggable transition shaders, manual/scroll-driven progress, auto Theatre sheets per scene |

Loaders

| Loader | Description | | ------------- | ---------------------------------------------------------------------------- | | ModelLoader | GLTFLoader + DRACOLoader with batch API (loadAll) | | AssetLoader | Preferred. Unified manifest loader — texture, cubeTexture, gltf, hdr, ktx2. Promise + event API. | | Resources | Deprecated. Texture + cube texture only, event API. Kept for backward compat — use AssetLoader instead. |

Utils

| Util | Description | | ----------------- | ----------------------------------------------------------------------------------------------------- | | Tracker | Tracks a DOM element's bounds → position + size in 3D world space | | DOMSync | DOM → mesh sync for both Lenis smooth-scroll (desktop) and native scroll (mobile) — same API for both | | boundsToView | DOMRect → world { position, size } at camera plane | | boundsToViewAtZ | DOMRect → world { position, size } at arbitrary Z depth | | OrbitControls | THREE.OrbitControls wrapper that integrates with App services pattern | | Theatre | Theatre.js (@theatre/core) service wrapper | | getTextStyles | Reads computed CSS from a DOM element and converts px → 3D world units (fontSize, lineHeight, etc.) | | MeshSampler | sampleSurface, sampleSurfaceWithNormals, sampleSurfaceForInstancing, normalsToQuaternions, sampleVertices, sampleToTexture — mesh sampling for particles, instancing + GPGPU seeds | | dracoPath | Draco CDN URL constant used by ModelLoader |


Usage

Full-page single world

import { setupKit } from "@linear_non/stellar-kit"
import { App } from "@linear_non/stellar-gl/classes"

setupKit()

class MyWorld {
  constructor({ scene, camera, gl, services }) { ... }
  update({ time, current }) { ... }
  resize() { ... }
  destroy() { ... }
}

const app = new App({ canvas: document.querySelector("canvas"), WorldClass: MyWorld })

Modular DOM-synced GL components

const app = new App({
  canvas: document.querySelector("canvas"),
  components: [
    { name: "hero", Class: GLHero },
    { name: "slider", Class: GLSlider },
  ],
})
// Each class receives: { el, index, scene, camera, gl, services }
// Mapped via [data-hero], [data-slider] attributes

Post-processing

import { PostPass } from "@linear_non/stellar-gl/classes"

const app = new App({
  canvas,
  WorldClass: MyWorld,
  services: {
    post: new PostPass({
      fragmentShader: myFrag,
      uniforms: { uIntensity: { value: 0.5 } },
    }),
  },
})

Multi-scene transitions

import { App, SceneManager } from "@linear_non/stellar-gl/classes"

const app = new App({
  canvas,
  WorldClass: class extends SceneManager {
    constructor(opts) {
      super({
        ...opts,
        scenes: [
          { name: 'hero', Class: HeroScene },
          { name: 'about', Class: AboutScene },
        ],
        transitionShader: gridRevealFrag,
        transitionUniforms: { uGridSize: { value: 50 } },
      })
    }
  },
  services: { theatre: new Theatre({ projectName: 'MyProject' }) },
})

// Animated transition
app.world.go('about', { duration: 1.8 })

// Scroll-driven
app.world.setManualMode(true)
app.world.prepareTransition('hero', 'about')
app.world.progress = scrollProgress // 0→1

Model loading

import { ModelLoader } from "@linear_non/stellar-gl/loaders"

const app = new App({
  canvas,
  WorldClass: MyWorld,
  services: { models: new ModelLoader() },
})

// In MyWorld.constructor:
const { hero } = await this.services.models.loadAll({ hero: "/models/hero.glb" })
this.scene.add(hero)

Local Development

npm install
npm run dev

Dev pages:

| Route | Demo | | ------------------- | ---------------------------------------------------------------------- | | / | Index | | /world/ | Spinning cube + ModelLoader | | /particles/ | GPU tube particles | | /manager/ | DOM-synced planes + backgroundSize shader | | /loaders/ | GLTF + DRACO + OrbitControls | | /asset-loader/ | AssetLoader — GLTF + HDR env map + progress | | /gl-sprite-player/| GLSpritePlayer — KTX2 sprite sequence, scroll-driven playback | | /fbo/ | FBOSystem — 16 384 curl-noise particles advanced via GPGPU ping-pong | | /post/ | PostPass — chromatic aberration + vignette | | /shader-plane/ | ShaderPlane — fullscreen + DOM-tracked | | /scroll-manager/ | ScrollableWM — scroll progress, isActive gating, lifecycle hooks | | /text/ | TextGL — standalone + CSS-driven 3D text | | /rt/ | RenderTarget — off-screen scene on a cube | | /theatre/ | Theatre.js Studio + sequence keyframes |

Note: Dev pages require local binary assets (sprites, models, HDR, fonts) that are gitignored to keep the repo lightweight. See claude.md "Local development" section for details.


Roadmap

High priority

  • [x] GlobalUniforms singleton (classes/GlobalUniforms.js) — { uTime, uResolution, uDpr } as plain { value } refs. Spread into any ShaderMaterialApp keeps them in sync every tick and resize. No UBO/WebGL2 needed.
  • [x] time.scale on App clockapp.timeScale (default 1). Scales delta and uTime. Existing code unaffected.
  • [x] AssetLoader (loaders/AssetLoader.js) — unified manifest loader. Supports texture, cubeTexture, gltf, hdr. Promise API (await loader.load(sources)) + event API. Key-based deduplication. Resources kept untouched.
  • [x] Tracker as Object3D subclassTracker now extends THREE.Object3D. scene.add(tracker), tracker.add(mesh). Fully backward-compatible.
  • [x] GLSL shader chunks library (shaders/chunks/) — cnoise, simplex, valueNoise, mapRange, rotate2d, rotate3d, applyQuat, backgroundCover as JS template-literal GLSL. Import from @linear_non/stellar-gl/shaders/chunks.
  • [x] onBeforeCompile shader injector (utils/shaderInjector.js) — injectShader(mat, { uniforms, vertex, fragment }) replaces #include tokens in Three.js built-in materials. Sets customProgramCacheKey, warns on unknown tokens.
  • [x] MeshSampler utility (utils/MeshSampler.js) — sampleSurface, sampleSurfaceWithNormals, sampleSurfaceForInstancing, normalsToQuaternions, sampleVertices, sampleToTexture. Wraps MeshSurfaceSampler for particle BufferAttributes, instanced geometry, and GPGPU DataTexture seeds.
  • [x] GPU performance tier (utils/gpuTier.js) — getTier()1|2|3, tierScale([0,64,96,128]), setTierOverride(). Tier 1 = mobile, 2 = Safari desktop, 3 = all other desktop.
  • [x] assignMaterials model traversal util (utils/assignMaterials.js) — assignMaterials(gltfRoot, { 'Wheel*': mat, '*Glass*': glassMat }) with glob wildcards. Returns Map<Mesh, Material> of all updated meshes.
  • [x] TextGL (classes/TextGL.js) + getTextStyles (utils/getTextStyles.js) — Troika-powered 3D text with standalone and CSS-driven DOM-tracked modes. getTextStyles converts computed CSS (font-size, line-height, letter-spacing, color) to world units. preloadFont re-exported from @linear_non/stellar-gl/three.

Medium priority

  • [ ] ScrollableWM cross-fade hook — optional onTransition(from, to, progress) callback called each frame as scrollProgress changes between two active components.
  • [x] Three.js Layers helper (utils/layers.js) — createLayerMap() + setLayer(object3D, layer) for per-section render isolation. Shipped v1.4.0.
  • [x] ktx2 type in AssetLoader{ name, type: 'ktx2', path } support via KTX2Loader (Basis Universal). Shipped v1.5.0.

Lower priority

  • [x] FBOSystem GPGPU wrapper (classes/FBOSystem.js) — ping-pong WebGLRenderTarget helper (no external dependencies). Shipped v1.4.0.
  • [x] SceneManager (classes/SceneManager.js) — multi-scene manager with RT-based transitions, pluggable transition shaders, manual/scroll-driven progress, auto Theatre sheets per scene. Shipped v1.6.0.
  • [ ] App async init pathasync init() gates first render behind await resources.load(manifest) to prevent blank frames.
  • [ ] LazyLoader — visibility-gated asset loading with IntersectionObserver + Web Worker image decoding via createImageBitmap.
  • [ ] Theatre.js per-scene wrappercreateSheet(project, sheet, state) helper reducing boilerplate for per-scene authoring.

Nice to have

  • [ ] Debug stats via URL param — auto-mount three-perf overlay when ?debug is active. Zero overhead in production.
  • [ ] DestroyManager mixin — tracks all IntersectionObservers, event listeners, and timers for automatic flush on destroy().

Completed

  • [x] Post-processing pipeline — shipped as PostPass
  • [x] Theatre.js service — Theatre class bundled with @theatre/core as a direct dependency (@theatre/studio dev-only)
  • [x] ModelLoader — shipped in loaders/ModelLoader.js
  • [x] RenderTarget support — shipped in classes/RenderTarget.js
  • [x] Renderer.dispose() fix (B1)
  • [x] WorldManager drops services fix (B2)
  • [x] Resources hangs on unknown types fix (B3)
  • [x] boundsToViewAtZ raw camera expectation documented (B4)
  • [x] README antialias correction (B5)
  • [x] boundsToView + Tracker container-aware (B6)
  • [x] Renderer.resize() updates pixel ratio (B7)
  • [x] Materials auto-unwraps renderer wrapper (B8)
  • [x] Resources empty-sources emits with items (B9)

Made with ❤️ by Non-Linear Studio