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

@jhlagado/glimmer

v0.6.0

Published

Glimmer: a reactive Z80 game framework compiling to readable AZM — state cells, cards, routines, layout types, and source-level Debug80 maps

Readme

Glimmer

Glimmer is a preprocessor and project format for AZM. Its initial purpose is to help us learn how to build a practical Z80 game engine while keeping real Z80 assembly visible.

The first target is game writing for the TEC-1G. The format should also leave room for other Z80 systems as Debug80 expands its supported platforms.

Longer term, Glimmer is expected to become a Debug80-facing format: a structured way to describe blocks, state records, bindings, effects, resources, and generated AZM glue for interactive Z80 programs.

Documentation:

The project is game-first because games exercise timing, input, graphics, sprites, state, sound, packaging, and performance. It is not intended to be game-only.

Status

Version 0.6.0 is the scheduling-contract and behavioural-confidence line. Glimmer distinguishes source-order-independent trigger delivery from the live-memory execution order of Z80 bodies, warns when same-phase blocks are scheduled together with a shared update target and rejects different unconditional routes that would make the destination source-order dependent. The release is exercised through Debug80's public headless runtime by bounded Dot, Tetro, Sprite Chase and scheduling scenarios. Glimmer continues to target AZM 0.3.4 and Debug80 treats .glim as a native source format.

The language: scalar, array, and typed state (layout types compiled to AZM .type records), pulses, timers and ramps, held/rising key bindings, compute/effect/render blocks with verbatim Z80 bodies, callable routines, cards (screens/modes with enter blocks and goto navigation), sound cues, curve tables, matrix shapes, multi-file programs (part), and hand-written AZM module imports.

The toolchain: glimmer build generates AZM, checks its declared and inferred register contracts, assembles to .hex/.bin/.d8.json, and rewrites the Debug80 map so breakpoints and stepping land in your .glim source for block bodies while generated glue stays in readable AZM. The same pipeline is a programmatic API (@jhlagado/glimmer/build) shaped like AZM's compile API and consumed by Debug80's native Glimmer backend.

Version 0.4.0 completed the data story: pieces, sprites, tiles, and LCD messages are declarations — shape rotation groups generate the corpus piece-engine tables, sprite/tile resources generate patterns, colour groups, and the VRAM upload, text brings the LCD slice — and the generated sprite_at/tile_at/lcd_row AZM ops keep every piece of sugar visible in the generated file. Tetro and sprite-chase play the corpus feature set with only irreducible engine code hand-written.

Version 0.3.0 added the second display: display tms9918 (the TEC-Deck VDP) generates a vblank-paced loop with a commit phase that flushes shadow tables to VRAM — proving the profile architecture on two opposite display models (the matrix the CPU is, the VDP the CPU writes to) — and build errors inside block bodies are now reported at the .glim line, the same way breakpoints resolve there.

Examples, smallest first: counter.glim (generic profile), dot.glim, slide.glim, trail.glim (TEC-1G matrix profile features), then the games — snake.glim, tetro.glim, and sprite-chase.glim (TMS9918). The repo's debug80.json carries a target for each.

Getting Started

Glimmer requires Node.js 20 or newer.

npm ci
npm run build
node dist/src/cli.js build examples/counter.glim   # asm + hex + bin + d8 map

The plain command stops at generated, contract-checked AZM (node dist/src/cli.js examples/counter.glim); build continues through assembly and the source-level debug map.

The generated AZM is readable: API equates, change-flag constants, state storage, the runtime loop, binding polling, phase dispatch, wrapped user blocks, and frame cleanup, in that order. Inspect examples/counter.main.asm after building to see the whole runtime.

The Meta-Source Format (v0)

program CounterToy

state Count : byte = 0 changed

pulse IncPressed

bind key KEY_1 rising -> IncPressed

effect ApplyIncrement
    on IncPressed
    updates Count
begin
    ld hl,Count
    inc (hl)
    ld a,(hl)
    cp 10
    jr c,_done
    xor a
    ld (hl),a
_done:
end

Block bodies land in the generated file byte-for-byte verbatim; AZM scopes _name labels to the block's entry label, so every block can have its own _done (the leading underscore is AZM's local-label syntax — block-internal branch targets must use it). Blocks run when any of their on cells changed; updates cells are marked changed after the block runs.

Development

npm run typecheck
npm run lint
npm test          # includes a round trip that assembles generated AZM

# The generated file declares its contract policy and routine boundaries.
# The CLI checks them with AZM automatically; --no-check stops after
# generation. Manual assembly uses the same MON-3 register profile:
npx azm --reg-profile mon3 examples/dot.main.asm
npm run format:check

License

GPL-3.0-only. See LICENSE.