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 🙏

© 2025 – Pkg Stats / Ryan Hefner

rpatcher

v0.1.0

Published

Zero-dependency ROM patching library

Readme

RomPatcher.ts

Zero-dependency JS ROM patching library for browsers

Installable (PWA) Web Demo

RomPatcher.ts is a re-write of MarcroBledo's RomPatcher.js - providing modularity, typing & simplicity.

To install, run

npm install rompatcher-ts

As of now, only Browsers are supported. For Node support, check out node-rompatcher on Gitlab.

Supported Formats

  • BPS
  • UPS
  • IPS

PR Contributions for more formats are welcome.

Usage

import Patcher from 'rompatcher-ts';

// 1. Initialize a patcher instance with a format.
const patcher = new Patcher([
  new IPSPattern,
  new BPSPattern,
  new UPSPattern
]);

// 2. Load ROM file
patcher.setROMFile(romFile);

// 3. Load Patch file asynchronously (2 & 3 can be interchanged)
try {
  await patcher.setPatchFile(patchFile)
} catch(e) {
  // Cannot recognize type of patch file
}

// This returns the pattern that will be used - i.e. IPS
// Must be called after patch file is loaded.
const patternToUse: string = patcher.pattern;

// 4. Load files asynchronously
await patcher.loadFiles();

// 5. Parse files
patcher.parseFile();

// 6. Patch the ROM
const resultPreparedFile = patcher.patch();

// 7. The blob can be obtained by calling export() on the resulting PreparedPatchFile.
const resBlob: Blob = resultPreparedFile.export();

API & Helpers

Patcher Patcher.ts

  • constructor(patternsToLoad: IPatchPattern[]) Initialize a patcher instance with the patterns to be used.

  • async setPatchFile(patchFile: File): Promise<void> Asynchronously sets a patch file, which determines the type of the patch file supplied. If it is not recognized, it throws an Error.

  • setROMFile(romFile: File) Sets a ROM file to be patched

  • async loadFiles() Asynchronously loads the supplied ROM file & patch file into the stateful supplied pattern. Throws an error if both are not supplied.

  • parseFile() Parses the supplied ROM file & patch file with the supplied pattern. Throws an error if both are not supplied.

  • patch(validateStrictly = false) (Do not change validateStrictly) Patches the ROM file with the patch file, returning a PreparedPatchFile instance with the resulting file.

Utils utils/crc.ts

  • crc32Table() Generates a CRC32 table. Caching recommended.

  • crc32(preparedPatcherFile: PreparedPatchFile, headerSize: number | boolean, ignoreLastFourBytes: boolean) Uses a CRC32 table to return a crc32 value for checksum purposes.

PreparedPatchFile utils.ts

  • static async create(file: File) Asynchronously create an instance of a PreparedPatchFile, using the load function.

  • static createEmpty(size: number) Ccreate an instance of a PreparedPatchFile, Create an empty PreparedPatchFile with the size of the provided integer.

  • async load(file: File) Asynchronously load the supplied file, which creates an internal Uint8Array byte array of the data.

  • public copyTo(target: PreparedPatchFile, offsetSource: number, length?: number, offsetTarget: number = offsetSource) Copy the current instance to the target.

  • seek(offset: number) Set internal offset to offset.

  • skip(offset: number) Skip internal offset by the value of offset.

  • slice(offset: number, length?: number) Create a copy of the current file, starting from the offset of the current file with the length of the provided number. Returns the new file.

  • isEOF() Returns if the internal offset counter is at the end of file.

  • readString(len: number) Reads the string of byte array. Adds to internal offset counter by len.

  • readBytes(len: number) Reads the bytes of the byte array. Adds to internal offset counter by len.

  • writeBytes(len: number) Reads the bytes of the byte array. Adds to internal offset counter by len.

  • read/writeU*(forceLittleEndian?: boolean = false) Reads or writes bits. forceLittleEndian options are for U16 and higher. Increases the internal offset counter by bytes read or written.

  • export() Returns a Blob of the current instance.

Writing Patterns

All patterns extend IPatchPattern, where you must implement these methods:

interface IPatchPattern {
  // Magic string for patch formats - i.e. BPS - "BPS1"
  MAGIC: string;

  // Constructor. Load the rom file & the patch file here, using
  // PreparedPatchFile.create(romFile | patchFile) here.
  // Initialize class variables here too.
  // Load the romFile and the patchFile as a class variable.
  init(romFile: File, patchFile: File): void;

  // Parse the patch file - current implementations use an array
  // to go through the Uint8Array and digest it to array of records or actions.
  parse(): void;

  // Create an output file with createEmpty(), and using the array of
  // records/actions created in parse(), write to the output file.
  // This varies by format.
  patch(strictValidation?: boolean): PreparedPatchFile;

  // Uses header to check if it belongs to the pattern.
  belongsTo(header: string): boolean;

  // Name of the patch - i.e. ups - "ups"
  name(): string;
}

Refer to implemented examples and MarcroBledo's RomPatcher.js.

Contributing

  • Run prettier
  • Respect ESLint rules
  • Testing before creating a PR. Unfortunately, tests cannot be done due to licensing issues for Nintendo ROMs.
  • For changing content inside /docs/ folder (which is the demo app), run npm run docs:build before pushing.

Examples

View the source code for the web demo in the docs/ directory, or go here for the installable live demo.

License

This library is licensed under GPLv3.