Skip to content

What is SceneryStack?

SceneryStack is the open-source TypeScript framework behind PhET Interactive Simulations. It provides everything needed to build accessible, multi-modal, interactive HTML5 applications: a scene graph renderer, a reactive state system, math utilities, UI components, and an application shell.

It is published as a single npm package, scenerystack, with each library exposed as a subpath export.

The libraries

LibraryImport pathPurpose
axonscenerystack/axonReactive state: Property, DerivedProperty, Emitter, Multilink
dotscenerystack/dotMath: Vector2, Bounds2, Matrix3, Range, Utils
kitescenerystack/kiteGeometric shapes and boolean operations: Shape, LineStyles
sceneryscenerystack/sceneryScene graph: Node, Path, Text, input listeners, accessibility (PDOM)
sunscenerystack/sunUI components: buttons, sliders, checkboxes, combo boxes
scenery-phetscenerystack/scenery-phetSimulation-specific reusable components: arrows, thermometers, PhetFont
twixtscenerystack/twixtAnimation and easing
joistscenerystack/sim (app shell classes) / scenerystack/joist (preferences panels, locale utilities)Application shell: Sim, Screen, ScreenView, navigation bar — see Troubleshooting for why the import subpath differs from the library name
tandemscenerystack/tandemPhET-iO instrumentation and serialization
phetcommonscenerystack/phetcommonShared utilities, notably ModelViewTransform2

Installation

bash
npm install scenerystack

A minimal example

ts
import { Property } from 'scenerystack/axon';
import { Circle, Node } from 'scenerystack/scenery';
import { Vector2 } from 'scenerystack/dot';

// Model: reactive state, no view knowledge
const positionProperty = new Property( new Vector2( 0, 0 ) );

// View: a scenery Node that observes the model
const ball = new Circle( 20, { fill: 'crimson' } );
positionProperty.link( position => {
  ball.translation = position;
} );

This model/view split is the foundational pattern of every SceneryStack application — see Model-View Separation.

Where to go next