Registry / serialization / bsmap
library2.3.4jsnpmunverified

bsmap is a general-purpose TypeScript library for creating, reading, and modifying Beat Saber beatmaps programmatically. Current stable version is 2.3.4. Maintained actively with frequent releases (every few months). It supports all major beatmap schema versions (v1 through v4.1.0) and modding extensions like Chroma, Cinema, Noodle Extensions, and Mapping Extensions out of the box. Key differentiators: fully-typed schema wrappers for cross-version compatibility, partial object creation with default filling, tree-shakeable modules, built-in validators and optimisers, and utilities for math, color, and easing. Works with Deno, Bun, Node.js (ESM/CJS), and browser bundlers.

npm install bsmap
INSTALL
IMPORT
SIG · BSMAP
B
bsmap
serializationjavascriptv2.3.4
harness data pending
Install & Compatibility
Where this runs

No compatibility data collected yet for this library.

Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

bsmap
import * as bsmap from 'bsmap'
const bsmap = require('bsmap')
For ESM (Deno, Bun, Node with 'type':'module'). CJS users: use require('bsmap'). Default import (import bsmap from 'bsmap') is not available.
readDifficultyFileSync
import { readDifficultyFileSync } from 'bsmap'
import readDifficultyFileSync from 'bsmap/io'
Named export from the main package. There is no subpath export for io in v2+.
Beats
import { Beats } from 'bsmap/beats'
import { Beats } from 'bsmap'
Beats utility class is exported from a subpath 'bsmap/beats' since v2.0.0. Also available as named export from main, but subpath is preferred for tree-shaking.
Difficulty
import { Difficulty } from 'bsmap'
Wrapper class for difficulty beatmap data. Available directly from main import.

Reads a v4 difficulty file, adds a note at beat 10, and writes the modified beatmap back. Uses synchronous file I/O and the V4Note wrapper.

import * as bsmap from 'bsmap'; import { readFileSync, writeFileSync } from 'fs'; // Read a v4 difficulty file const inputPath = './ExpertPlus.beatmap.dat'; const outputPath = './ExpertPlus_modified.beatmap.dat'; const rawData = readFileSync(inputPath, 'utf-8'); const data = bsmap.readDifficultyFileSync(rawData, 4); // Modify: add a note at beat 10, line 0, layer 1, color red const note = new bsmap.V4Note({ beat: 10, color: 0, // Red line: 0, layer: 1, direction: 1, // Down type: 0, // Note }); data.difficulty.colorNotes = data.difficulty.colorNotes || []; data.difficulty.colorNotes.push(note); // Write back const serialized = bsmap.writeDifficultyFileSync(data, 4); writeFileSync(outputPath, serialized, 'utf-8'); console.log('Done! Modified note added.');
Debug
Known issues
breakingIn v1.6.0, constructor and create() static method were removed. Use fromJSON() static method instead.
fix
Replace new Beatmap(data) or Beatmap.create(data) with Beatmap.fromJSON(data).
affects: >=1.6.0
breakingIn v2.0.0, the main export changed from default to namespace. import * as bsmap from 'bsmap' is now required, import bsmap from 'bsmap' no longer works.
fix
Use import * as bsmap from 'bsmap' (ESM) or const bsmap = require('bsmap') (CJS).
affects: >=2.0.0
breakingIn v2.0.0, some utility classes (e.g., Beats) moved to subpath exports like 'bsmap/beats'. Direct import from main may be removed in future.
fix
Import utility classes from their respective subpaths for tree-shaking and future compatibility.
affects: >=2.0.0
breakingIn v1.5.0, v3 beatmap schema updated to 3.3.0. Events collection classes changed; FX Event Box Group and FX Events Collection added.
fix
Update any v3 beatmap code to handle new FX event structures. Old v3 events still parse but may not serialize correctly.
affects: >=1.5.0
gotchaWhen using Node.js CJS with require('bsmap'), TypeScript types will not be available. You must use a separate type declaration or ESM.
fix
Use ESM (import * as bsmap from 'bsmap') in TypeScript or with ts-node. For plain JS, types are not needed.
affects: *
gotchaPartial creation of beatmap objects: absent fields default to undefined, not schema defaults. Missing required fields may cause validation errors on save.
fix
Always provide all required fields or use fromJSON() to fill defaults. Use the 'defaults' utility to apply schema defaults if needed.
affects: *
Errors
Common errors & fixes
TypeError: Class constructor Beatmap cannot be invoked without 'new'
Using static create() method which was removed in v1.6.0, or incorrectly calling constructor as a function.
fix
Use Beatmap.fromJSON(data) instead of new Beatmap(data).
ERR_MODULE_NOT_FOUND: Cannot find module 'bsmap'
Running ESM without 'type':'module' in package.json, or using wrong import style (default import instead of namespace).
fix
Create script.js and add import * as bsmap from 'bsmap' (ESM) or use require('bsmap') (CJS).
Duplicate identifier 'Beats'
Importing Beats from both main and subpath 'bsmap/beats'.
fix
Import Beats from only one source, preferably 'bsmap/beats'.
Property 'colorNotes' does not exist on type 'V4Difficulty'
Using an older version of bsmap (<1.5.0) that uses different property names for v4.
fix
Update to bsmap >=1.5.0 and use the correct schema property names (e.g., colorNotes instead of notes).
Upgrade
Version history
2.3.4latest on npm
Audit
Dependencies
typescriptoptionalLibrary requires TypeScript for type checking and development, though runtime can be any JS runtime.
Agent activity
14 hits · last 30 days
node
12
OpenAI (training)
1
Resources
bsmap — npm install bsmap · libregistry