New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@rectools/react-rec-viewer

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rectools/react-rec-viewer

Elasto Mania replay viewer for React, drawn with WebGPU or WebGL2

latest
Source
npmnpm
Version
0.1.3
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

@rectools/react-rec-viewer

Plays Elasto Mania and Across replays, and shows levels, in React. It draws with WebGPU, or WebGL2 where WebGPU isn't available, using rectools' renderer.

The renderer is a WebAssembly module of about 3 MB, loaded when the first player is shown. Bundlers that understand new URL("…", import.meta.url), such as Vite and webpack 5, need no configuration.

From URLs: RecPlayer

import { RecPlayer } from "@rectools/react-rec-viewer";

<RecPlayer
  levUrl="https://api.elma.online/dl/level/123"
  recUrls={[mainRecUrl, otherRecUrl]}
  shirtUrls={[mainShirtUrl, otherShirtUrl]}
  style={{ height: 480 }}
/>;
Prop
levUrlThe level
recUrlsThe replays: the first plays, the others are merged in. Empty shows the level on its own.
shirtUrlsEach replay's shirt, a .bmp or a picture
recNamesEach replay's rider, for the follow menu
lgrUrl(name) => url of the LGR a level asks for. Default: elma.online's.
lgrFileUrlOne LGR for every level
defaultLgrUrlUsed when the level's LGR can't be loaded
acrossPackUrlThe Across graphics and built-in levels, an across.res
acrossShow a level on its own as an Across level
fetchInitPassed to fetch

Changing the merged replays while the first stays carries on from the same moment. Downloads are cached by URL. Everything else is passed to RecViewer.

From bytes: RecViewer

RecViewer takes the files as Uint8Arrays: rec, lev, lgr, res (elma.res, for the internal levels), acrossPack, shirt, and ghosts: { rec, shirt }[].

Settings with a default… and an on…Change can be controlled or left to the player.

PropDefault
zoom11 is the game's zoom
playingtrue
speed1Negative plays backwards
follow0The bike followed: the replay's riders, then the merged ones'
centeredCameratrueOff is the game's classic camera
timertrue
minimapfalse
autoZoomfalseZoom out to keep every bike in view. Moving the camera pauses it.
translucentGhostsfalseMerged replays blue and see-through (not on WebGL2)
picturesInBackgroundtrueBikes and objects over every picture
levelOptionsall on but stillObjects{ grass, pictures, customSky, arrows, animatedObjects, stillObjects, fancyboost }. Fancyboost is the 256 single color pictures of a fancyboosted LGR, which every LGR gets.
splitScreentrueBoth bikes of a two player replay
looptrueStart over after the end
timeSeek here when it changes
bikeLabelsNames for the follow menu
controls, keyboardtrueThe control bar, and the keys below
pauseWhenHidden, wakeLocktruePause in a hidden tab; keep the screen on while playing
autoPlaySetting, lgrChoices, lgrChoiceSettings for the page to keep, shown in the menu with their callbacks
onTimeChange, onDurationChange, onEnd, onError, onSettingsOpen
showErrorstrueShow errors over the view

A ref gives play(), pause(), seek(seconds), time(), duration(), recenter(), fitLevel() and toggleFullscreen().

Errors

Errors are a RecViewerError, whose kind is rec, ghost (a merged replay), lev, lgr, res, across-pack, level-changed, topology, graphics or other. A download that failed has its HTTP status. A replay that can't be played clears the view; a merged one that can't be added leaves the replay playing.

Mouse, touch and keys

Drag to move the camera, wheel or pinch to zoom, tap to play or pause, double-click for full screen.

Key
SpacePlay / pause
- / +Slower / faster
BackspaceNormal speed
RReverse
← / →Back / forward 2.5 seconds
, / .Back / forward one frame
W / EZoom out / in
FShow the whole level
CBack onto the bike
N / Shift NFollow the next / previous bike
PPictures and the level's own ground and sky
GGrass
AGravity arrows
Shift GGrass, pictures and the level's own ground and sky on
TTimer
VMinimap

keyList() returns them once the engine is loaded.

Building

pnpm build at the repository root builds the wasm and dist/. It needs Rust with the wasm32-unknown-unknown target and wasm-bindgen-cli at the version in Cargo.lock, and uses binaryen's wasm-opt when it is installed.

To try a change in a site, scripts/try-in-site.sh <site folder> builds the package and copies it over the one in the site's node_modules. yarn install --check-files in the site puts the published one back.

To publish, push a tag react-rec-viewer-v<version> matching package.json. The workflow needs an NPM_TOKEN secret.

FAQs

Package last updated on 13 Oct 2026

Related posts