[Project] SHRINE-98: A high-performance Danmaku (Bullet Hell) engine built with React 18, HTML5 Canvas, and Object Pooling.

Most people use React for standard CRUD apps. I wanted to see if I could bypass the Virtual DOM limits to build a high-density, vertical Bullet Hell (Danmaku) engine that stays locked at 60FPS on my M2.

The result is SHRINE-98. It manages 2,500+ active bullet entities and items simultaneously without garbage collection stutters.

Live Demo: https://project-voidshrine-98.vercel.app/ | Source Code: https://github.com/berinelson122-design/project-voidshrine-98

// THE ARCHITECTURE

  • Decoupled Logic Loop: I used a custom requestAnimationFrame hook that operates entirely on Mutable Refs. This allows the physics engine to run at 60Hz without triggering a single React re-render for the game objects.
  • Object Pooling: Instead of instantiating and destroying bullet objects (which causes memory fragmentation), the engine recycles a fixed array of pre-allocated entities. This keeps the heap stable during high-load boss phases.
  • Procedural Audio: To keep the bundle size microscopic and ensure zero-latency sound effects, I implemented a custom synthesizer using the Web Audio API. No external MP3 assets are loaded for the SFX.
  • State Management: I used Zustand to sync the high-level game stats (Score, Lives, Power) back to the React UI overlay once every 10 frames, balancing data integrity with performance.

// WHY CANVAS? I chose pure HTML5 Canvas over libraries like Phaser or Three.js because I wanted total sovereignty over the render pipeline. This allowed me to implement a dithered, PC-98 aesthetic that mirrors the original Touhou games.

I’m looking for feedback on the input latency and the collision mathematics (Hitbox vs. Graze radius).

ARCHITECT // VOID_WEAVER

Posted Mar 1, 2026, 1:56 AM UTC

06
Loading comments…