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

furnace-module-interface

v0.5.1

Published

An interface for loading, processing and saving furnace modules in an object-oriented manner. Fully typed via TypeScript.

Readme

furnace-module-interface

An interface for loading, processing and saving furnace modules in an object-oriented manner. Fully typed via TypeScript.

Installation

npm install furnace-module-interface

Here is an example of a typical usecase:

import fsp from "fs/promises";
import { loadFurnaceModule, deflateBuffer } from "furnace-module-interface";

const file = await fsp.readFile("testfile.fur")
const module = await loadFurnaceModule(file);

if(module instanceof FurnaceSongModule) {
    // only modify name IF this is a furnace song module (.fur extension should always be that!)
    module.info.name = "Example module name";

    const newdata = module.getAsBuffer();
    await fsp.writeFile("editedtestfile.fur", deflateBuffer(newdata));
}

API

Modules

There are 3 types of furnace modules: FurnaceSongModule for full songs, FurnaceInstrumentModule for instrument module files, and FurnaceWavetableModule for wavetable module files. furnace-module-interface supports all 3, but they have many differences. Checking modules you get by calling loadFurnaceModule is recommended as a way to ensure you are processing the right version:

import { loadFurnaceModule } from "furnace-module-interface";

const module = await loadFurnaceModule(fileBuffer);

if(module instanceof FurnaceSongModule) {
    // process song module

} else if(module instanceof FurnaceInstrumentModule) {
    // process instrument module

} else if(module instanceof FurnaceWavetableModule) {
    // process wavetable module

} else {
    // no idea what we got. Maybe this is a future version with even more modules?
}

Subsongs

dev95 introduced subsongs, but before they were not supported. furnace-module-interface pretends the main subsong is just like any subsong, even in older versions. Check FurnaceSongModule.songs[0] for that. The first subsong is handled in a special way when loading or saving, other indices work as subsongs normalöly.

Handling channels

Channels are internally handled by using "systems" and "chips", but to access their properties, its more advantageous to treat them as fully independent entities. furnace-module-interface handles this via creating an intermediate object, that processes the properties of channels into convenient objects. This means however, that some properties are not changeable, while others are. To load channels, you can simply do this:

import { loadFurnaceModule, FurnaceInstrumentTypeEnum } from "furnace-module-interface";

const module = await loadFurnaceModule(fileBuffer);

if(module instanceof FurnaceSongModule) {
    const song = module.info.songs[0];
    const channels = song.getChannels(module.info);
}

Handling instruments

Because of compatibility issues, instrument handling is a little weird. You are required to create a "view", that makes it easier to access relevant information about an instrument. You can create any number of views, but modifying one view can affect another. This is particularly a case for OPLL vs other FM instruments. Here is an example:

import { loadFurnaceModule, FurnaceInstrumentTypeEnum } from "furnace-module-interface";

const module = await loadFurnaceModule(fileBuffer);

if(module instanceof FurnaceSongModule) {
    const instrument = module.info.instruments[0];
    const view = instrument.getView(FurnaceInstrumentTypeEnum.OPMOPN);
}

Sample formats

A simple interface for sample conversions are provided. They can be converted between native format and 16-bit signed PCM. This allows easy handling of sample data without having to deal with the format specifics. Here is an example of how you might handle that in your program:

import { loadFurnaceModule, FurnaceInstrumentTypeEnum } from "furnace-module-interface";

const module = await loadFurnaceModule(fileBuffer);

if(module instanceof FurnaceSongModule) {
    const sample = module.info.samples[0];

    const rawSamples = sample.data.convertToArray();
    /**
     * manipulate sample data here!!!
     */
    sample.data.convertFromArray(rawSamples);
}

Accessing raw sample data is not recommended, as it is easier to get it wrong.

Metadata

Module metadata is a furnace-module-interface and is ignored by Furnace. This is not intended to be used to store critical information about modules. Instead, it is a tool that can be used to store information with a module that may be used for any personal purpose. This format is not formally documented yet.

Typings

furnace-module-interface provides full typings for all relevant user-faccing information. Please use Typescript to get the best experience!

Roadmap

furnace-module-interface follows the development of Furnace closely, and will periodically update to support the latest version.

License

This project is licensed under MIT.

Project status

Currently the project is in its very early days and is expected to be unstable and lack features.

Credits

  • Aurora*Fields Main developer of the project
  • tildearrow Main developer of Furnace