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

@badiiix/strike-core

v0.1.2

Published

Strike — lightweight sprite runtime. Actor-driven scheduling, framework-agnostic core.

Readme

@badiiix/strike-core

Lightweight, framework-agnostic sprite runtime for the web.


✨ Why Strike Core?

  • Agnostic core — pure TS + Canvas2D, no framework lock-in (Vue/React adapters coming).
  • Actor model — each sprite owns state + action channels (timed events).
  • Simple spritesheets — single row, optional spacing/margin, auto frame-size inference.
  • Small & clear — clean modules (actor, view, viewport, render), easy to extend.

📦 Install

# npm
npm i @badiiix/strike-core

# bun
bun add @badiiix/strike-core

# pnpm
pnpm add @badiiix/strike-core

🚀 Quick start

HTML:

<div id="stage"></div>

TS:

import { createSurface, createActor, loadImage } from '@badiiix/strike-core'

const surface = createSurface({
  mount: '#stage',
  mode: 'actor',              // "cage" strategy by default
  background: 'transparent',
})

const img = await loadImage('/cat.png')   // 1×8 spritesheet
const actor = createActor({ sheet: { frames: 8 }, x: 50, y: 150 })

surface.add({ actor, sheet: img, anchor: 'topleft', scale: 2 })

actor.channel('frames').every(140, () => actor.nextFrame(), { name: 'frames' }).start()
actor.channel('move').every(500, () => actor.addPos(20, 0), { name: 'drift' }).start()

🧠 Concepts

Actor

Owns runtime state and actions

const actor = createActor({ sheet: { frames: 8 }, x: 0, y: 0 })
actor.setPos(100, 120)
actor.nextFrame()
actor.channel('frames').every(200, () => actor.nextFrame(), { name: 'tick' }).start()

View

Binds an Actor to an image and render flags (scale, flips, anchor, z)

const view = surface.add({ actor, sheet: img, scale: 2, anchor: 'center', z: 1 })
surface.update(view, { flipX: true })

Surface & Viewport

Surface orchestrates rendering through a viewport strategy:

  • mode: 'actor' → Cage: canvas follows the actor; canvas size = current frame × scale.
  • mode: 'fixed' → fixed canvas size; pair with camera viewport if needed.
  • mode: 'parent' → canvas matches parent size; pair with camera viewport.

🖼️ Spritesheets

Single row of frames. You can provide or omit frameSize:

const actor = createActor({
  sheet: {
    frames: 8, //If nothing else provided, will calculate automaticly the frame size
    // Optional if the image is known; will be inferred:
    // frameSize: [20, 14],
    // spacing: 0,
    // margin: 0,
  }
})

If frameSize is omitted, the core infers it from imageSize and frames. Spacing/margin are supported (uniform).


🔧 API (high level)

// Surface
createSurface(options)
  .add({ actor, sheet, scale?, anchor?, z?, flipX?, flipY?, visible? })
  .update(view, patch)
  .remove(view)
  .setFollow(view?)   // for camera-like strategies
  .play() / .pause() / .destroy()

// Actor
createActor({ sheet, x?, y?, frame?, facing? })
  .setPos(x, y) / .addPos(dx, dy)
  .setFrame(i) / .nextFrame() / .prevFrame()
  .channel(name).every(ms, fn, { name?, immediate?, catchUp? }).start()
  .channel(name).once(ms, fn, { name? })

Types are fully exported if you need them:

import type { SheetMeta, Anchor, ViewModel } from '@badiiix/strike-core'

🛠️ Build targets

  • ESM: dist/index.mjs
  • CJS: dist/index.cjs
  • Types: dist/index.d.ts

Package exports are configured for both import and require.