// a living layer for your web page

bysters

Little bots move onto your page, notice everything around them, and make themselves at home. Scroll down to meet them.

bysters is an open-source JavaScript library that brings any web page to life with small procedural bots that walk your layout, notice the cursor, and break and fix things.

watch it come back

many little minds

Give each one its own behaviour, and the scene plays itself.

Nobody scripted this. One bot chases, another runs, a third fixes what breaks. You give each of them a few habits and let them loose.

click to turn it blue

what you just watched

Not a canvas trick. A little society on your page.

None of this is animated by hand. Each byster looks at your real layout and the bots near it, then works out what to do on its own.

Your DOM is their terrain

They read your real layout as walls, floors and undersides and climb it from any angle. Resize the window and they re-plan the whole world on the fly.

They notice you

Each byster senses the cursor and every other byster, so they chase, flee, crowd and dodge without you scripting a single interaction.

You write the personality

A byster is a short stack of tiny habits: wander, chase, doze, perch, fix. Reorder the stack and you get a different character.

Polite by default

No WebGL, or a reduced-motion request? bysters quietly does nothing and hands your page back exactly as it found it.

how it works

Point it at your page. That is the setup.

Mark what they can walk with one attribute, hand mount() your cast, and they wake up. Everything you scrolled past is about a dozen lines of this.

  • + compose behaviours from the built-in library
  • + bring your own creatures, or use the pack
  • + pure core, headless-tested, framework-agnostic
// wake the cast up on your page
import { mount, behaviors } from 'bysters'
const { operateFixtures, flee, followCursor } = behaviors

await mount({
  terrain: '[data-walk]',     // what they climb
  fixtures: '[data-fixture]',  // what they operate
  bysters: [
    { name: 'byte', character: Byte, behaviors: [
      operateFixtures({ match: (fx) => fx.state === 'fixed', drive: 'broken' }),
      flee((v) => v.name === 'sarge') ] },
    { name: 'pip',  character: Pip, behaviors: [
      operateFixtures({ match: (fx) => fx.state === 'broken', drive: 'fixed' }),
      followCursor() ] },
  ],
})

Give your page a pulse.

Free and open source. Drop it into anything with a DOM and watch the place get inhabited.