Skip to content

Getting started ​

Show one scene file in a React app, then add clicks and live state. Isora draws isometric scenes as plain SVG React components, so it fits anywhere a React component does — a product page, an operations dashboard, a digital-twin floor view.

1. Install ​

bash
npm install @isora/core @isora/react @isora/assets
  • React 18 or 19. No bundler setup (Vite, Next.js, webpack) is needed. ESM only.
  • @isora/react does not depend on MUI. It draws a single SVG.

2. Make a scene ​

A scene is a .isora.json file. There are two ways to make one.

  • Studio (GUI scene editor): run pnpm dev in this repo, or in your app folder run pnpm isora init --dir ../my-app → pnpm isora studio --dir ../my-app. The UI is English or Korean — switch with the language menu in the top bar (or open with ?lang=ko). Try it in the browser. Drag assets from the palette, seat people on chairs, pick their routines, and save.
  • Code: make an empty scene with createScene() and add objects to objects.
ts
import { createRegistry, createScene, createSceneBuilder } from '@isora/core'
import { officialPacks } from '@isora/assets'

const registry = createRegistry(officialPacks)
const scene = createScene({ id: 'lab', name: 'Lab', width: 10, depth: 8 })
const b = createSceneBuilder(scene, registry)

b.floor('isora/common/floor-wood', 0, 0, 10, 8)                 // 80 floor tiles
const desk = b.add('isora/office/desk', 2, 2)                    // footprint corner (2, 2). Returns the id 'desk-1'
b.add('isora/office/monitor', 2.75, 2.25, 0, { state: 'code' })  // height is worked out: the desk top
const chair = b.add('isora/office/chair', 2.75, 3, 180)          // in front of the desk (+y), facing it
b.sit('isora/people/developer', chair, 0, { id: 'kim', behavior: { routine: 'office', desk: chair } })
  • add sets the height with the same stacking rules Studio uses when you drop an object, and throws on an unknown asset.
  • To place by center instead, placeAt(scene, registry, assetId, [cx, cy], rotation) works out the corner and height.

3. Show it ​

tsx
import { parseScene } from '@isora/core'
import { IsoScene } from '@isora/react'
import { common } from '@isora/assets/common'
import { office } from '@isora/assets/office'
import { people } from '@isora/assets/people'
import sceneJson from './scenes/main.isora.json'

// A JSON import widens the types, so validate it to get a Scene. Throws SceneValidationError (with an errors list) if invalid.
const scene = parseScene(sceneJson)
// Pass only the packs the scene uses. Keep this outside the component so it is not a new array on every render.
const packs = [common, office, people]

export function Office() {
  return <IsoScene scene={scene} packs={packs} style={{ height: 480 }} />
}

IsoScene fills its parent with the SVG (width and height 100%). Put it inside a parent that has a height.

4. Clicks and live state ​

tsx
const [states, setStates] = useState<Record<string, string>>({})

useEffect(() => {
  // Say equipment states arrive over a WebSocket: object id → a state name defined by the asset
  const ws = new WebSocket('wss://example/telemetry')
  ws.onmessage = (e) => setStates((s) => ({ ...s, ...JSON.parse(e.data) })) // { 'line-a/beacon': 'alarm' }
  return () => ws.close()
}, [])

<IsoScene
  scene={scene}
  packs={packs}
  states={states}                                  // beacon alarm, monitor off …
  onObjectClick={(obj) => openPanel(obj.id)}       // object click
  playTimelines                                    // conveyor cargo, robot arm keyframes
/>
  • State names come from the asset (asset.states). Check them in the Studio properties panel or with registry.get(id).states. To show a state's display name in another language, use stateLabel(asset, state, 'ko') (Languages).
  • states from the app win over states set by behavior playback (such as turning off the monitor on an empty desk).

5. Move people ​

Give a person object behavior: { routine: 'office', desk: 'chair-3' } and turn on playBehaviors, and they work, rest and wander according to the routine. To send people yourself from the app, use commands (command) in Moving people.

tsx
<IsoScene scene={scene} packs={packs} playBehaviors behaviorSpeed={2} showActivities />

6. Next.js App Router ​

  • Component and hook files ship with 'use client'. Import IsoScene directly in a server component and the server renders the SVG; animation continues after hydration.
  • Pass function props such as onObjectClick from inside a 'use client' file.
  • Passing packs from a server component puts the pack data in the RSC payload (all official packs are about 340 kB of JSON, 38 kB gzipped). Pass only the packs you need.

Next ​

  • Concepts — coordinates and time
  • Moving people — commands, routines, reading positions
  • Rendering — overlays, click coordinates, drawing it yourself

Released under the MIT License.