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

d2r-saver

v0.2.0

Published

Blizzless D2R (Diablo II: Resurrected v105) save file reader/writer for .d2s characters and .d2i shared stashes. Lossless writes preserve all save sections; supports item insert/extract and gold/attribute edits.

Readme

d2r-saver

Blizzless D2R v105 save file reader/writer library. Ported from d2planner.

Features

  • Read/write .d2s (character) and .d2i (shared stash) files
  • Extract and insert items between save files
  • Portable item serialization tokens (d2r1:<base64>)
  • HD/SD icon path resolution
  • Trade DTO generation for backend integration
  • Inventory grid placement helpers
  • TypeScript strict mode, full type safety

Quick Start

import { D2RSaver } from 'd2r-saver';
import { readFileSync } from 'node:fs';

// Initialize with game data
const saver = await D2RSaver.create({
  dataPath: './data/data.json',
  stringsPath: './data/strings.json',
});

// Or from pre-parsed JSON
const saver = D2RSaver.fromData(dataJson, stringsJson);

Reading Save Files

// Auto-detect format
const result = saver.readSave(buffer);
// result.type === 'd2s' | 'd2i'

// Or explicitly
const d2s = saver.readD2S(buffer);  // character file
const d2i = saver.readD2I(buffer);  // shared stash

Trade Flow (Extract → Serialize → Transfer → Insert)

// Seller: extract item from character
const { newBuffer, extractedItem, extractedAllItems } =
  saver.extractItemD2S(sellerBuffer, itemId);

// Serialize to portable token (goes over the network)
const token = saver.serializeItem(extractedItem, extractedAllItems);

// Buyer: deserialize and insert into stash
const { item, allItems } = saver.deserializeItem(token);
const { newBuffer: patchedStash } =
  saver.insertItemD2I(buyerBuffer, item, allItems);

Item Information

// Icon paths
const hdIcon = saver.getItemIconPath(item);  // HD icon key
const sdIcon = saver.getItemIconSD(item);    // SD invfile name

// Trade DTO (for backend)
const dto = saver.toTradeDTO(item, allItems);
// → { token, baseCode, displayName, quality, ilvl, ethereal, sockets, ... }

// Item dimensions
const { width, height } = saver.getItemSize(item);

Placement

import { StashGrid } from 'd2r-saver';

const grid = new StashGrid(16, 13); // stash dimensions
const canPlace = saver.canPlaceItem(grid, x, y, item);
const slot = saver.findFreeSlot(grid, item);

Error Handling

import { D2RSaverError, ErrorCode } from 'd2r-saver';

try {
  saver.extractItemD2S(buffer, 999);
} catch (e) {
  if (e instanceof D2RSaverError) {
    switch (e.code) {
      case ErrorCode.ITEM_NOT_FOUND: // ...
      case ErrorCode.INVALID_FORMAT: // ...
      case ErrorCode.NO_FREE_SLOT:   // ...
    }
  }
}

Architecture

src/
  index.ts              — D2RSaver facade + re-exports
  core/                 — BinaryReader, BitWriter, Huffman, checksum
  types/                — Constants, enums, errors
  game-data/            — GameData class (data.json + strings.json)
  formats/              — D2S/D2I readers/writers, item parser/writer
  items/                — Item types, stats, serializer, icons, DTO
  inventory/            — Grid, placement, dimensions
  operations/           — Extract, insert, readSave

Development

npm test          # run tests (vitest)
npm run build     # compile TypeScript

Requirements

  • Node.js ≥ 18
  • Blizzless v105 save files only