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

@blockutil/kheavyhash

v0.1.0

Published

TypeScript/JavaScript implementation of the KHeavyHash algorithm compatible with the Go reference implementation

Readme

@blockutil/kheavyhash

TypeScript/JavaScript implementation of the KHeavyHash algorithm compatible with the Go reference implementation at github.com/bcutil/kheavyhash.

npm version License: MIT

⚠️ Important Notice: This implementation is not optimized for mining purposes and is not intended for mining. It is designed for reference, testing, and educational purposes. For production mining operations, please use optimized implementations.

Features

  • ✅ Full TypeScript support with type definitions
  • ✅ JavaScript/ES modules compatible
  • ✅ Deterministic output matching Go reference implementation
  • ✅ Comprehensive test suite following FIRST principles
  • ✅ Docker development environment (VS Code/Cursor dev container support)
  • ✅ CI/CD ready
  • ✅ Zero dependencies (pure TypeScript implementation)

Compatibility

  • Node.js: >= 18.0.0
  • TypeScript: >= 4.5.0
  • JavaScript: ES2022+ (modern browsers and Node.js)
  • Module System: ESM (ES Modules) with CommonJS fallback support

Installation

pnpm add @blockutil/kheavyhash

or

npm install @blockutil/kheavyhash

or

yarn add @blockutil/kheavyhash

Quick Start

import { kheavyhash, bytesToHex, hexToBytes } from '@blockutil/kheavyhash';

// Construct 80-byte input
const prePowHash = hexToBytes('0ad86e9bef09726cdc75913e44ec96521391c7ceb2aae3c633f46a94bf4d2546');

// Set timestamp as little-endian 64-bit integer
const timestamp = new Uint8Array(8);
const view = new DataView(timestamp.buffer);
view.setBigUint64(0, BigInt(0x19568d36b3e), true); // true = little-endian

// Padding must be all zeros (32 bytes)
const padding = new Uint8Array(32);

// Set nonce as little-endian 64-bit integer
const nonce = new Uint8Array(8);
view.setBigUint64(0, BigInt(0x571506849306fd39), true); // true = little-endian

// Combine into 80-byte input
const input = new Uint8Array(80);
input.set(prePowHash, 0); // Bytes 0-31
input.set(timestamp, 32); // Bytes 32-39
input.set(padding, 40); // Bytes 40-71 (zeros)
input.set(nonce, 72); // Bytes 72-79

// Hash
const hash = kheavyhash(input);
console.log(bytesToHex(hash)); // 32-byte hash as hex string

Usage Examples

Example 1: Using Hex String Input

import { kheavyhash, bytesToHex } from '@blockutil/kheavyhash';

// All 80 bytes as hex string (160 hex characters)
const hexInput =
  '0ad86e9bef09726cdc75913e44ec96521391c7ceb2aae3c633f46a94bf4d2546' + // prePowHash (32 bytes)
  '3ed68b9501950000' + // timestamp (8 bytes, little-endian)
  '0'.repeat(64) + // padding (32 bytes, must be zeros)
  '39fd0630849571'; // nonce (8 bytes, little-endian)

const hash = kheavyhash(hexInput);
console.log(bytesToHex(hash));

Example 2: Iterative Hashing (Mining Simulation)

import { kheavyhash, bytesToHex, hexToBytes } from '@blockutil/kheavyhash';

// Initial prePowHash
let prePowHash = hexToBytes('0ad86e9bef09726cdc75913e44ec96521391c7ceb2aae3c633f46a94bf4d2546');
const timestamp = 0x19568d36b3e; // Fixed timestamp
let nonce = 0;

// Mine for multiple iterations
for (let i = 0; i < 1000; i++) {
  // Construct input
  const input = new Uint8Array(80);
  input.set(prePowHash, 0);

  // Set timestamp (little-endian)
  const timestampBytes = new Uint8Array(8);
  const view = new DataView(timestampBytes.buffer);
  view.setBigUint64(0, BigInt(timestamp), true);
  input.set(timestampBytes, 32);

  // Padding (already zeros, no need to set)

  // Set nonce (little-endian)
  const nonceBytes = new Uint8Array(8);
  view.setBigUint64(0, BigInt(nonce), true);
  input.set(nonceBytes, 72);

  // Hash
  const hash = kheavyhash(input);

  // Use output as next prePowHash
  prePowHash = hash;

  // Increment nonce for next iteration
  nonce++;

  if (i % 100 === 0) {
    console.log(`Iteration ${i}: ${bytesToHex(hash)}`);
  }
}

Example 3: Input Validation

import { validateInput, kheavyhash } from '@blockutil/kheavyhash';

function safeHash(input: unknown): Uint8Array | null {
  if (!validateInput(input)) {
    console.error('Invalid input: must be 80-byte Uint8Array or 160-char hex string');
    return null;
  }

  try {
    return kheavyhash(input);
  } catch (error) {
    console.error('Hash failed:', error);
    return null;
  }
}

// Usage
const hash1 = safeHash(new Uint8Array(80)); // ✅ Valid
const hash2 = safeHash('0'.repeat(160)); // ✅ Valid
const hash3 = safeHash(new Uint8Array(79)); // ❌ Invalid (wrong length)

Input Format

KHeavyHash requires exactly 80 bytes with the following structure:

| Bytes | Field | Size | Description | Endianness | | ----- | ------------ | -------- | --------------------------- | ----------------- | | 0-31 | prePowHash | 32 bytes | Previous proof-of-work hash | N/A | | 32-39 | timestamp | 8 bytes | Block timestamp | Little-endian | | 40-71 | padding | 32 bytes | Must be all zeros | N/A | | 72-79 | nonce | 8 bytes | Mining nonce | Little-endian |

Important Notes:

  • The timestamp and nonce must be encoded as little-endian 64-bit integers
  • The padding field (bytes 40-71) must be all zeros
  • Total input must be exactly 80 bytes (160 hex characters if using hex string)

API Reference

For complete API documentation, see API.md.

Main exports:

  • kheavyhash(input: Uint8Array | string): Uint8Array - Main hash function
  • validateInput(input: unknown): boolean - Input validation type guard
  • hexToBytes(hex: string): Uint8Array - Convert hex string to bytes
  • bytesToHex(bytes: Uint8Array, prefix?: boolean): string - Convert bytes to hex string

All functions are fully documented with JSDoc comments. Use your IDE's IntelliSense for inline documentation.

Development

Prerequisites

  • Node.js >= 18.0.0
  • pnpm >= 8.0.0 (or npm/yarn)

Setup

# Install dependencies
pnpm install

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Build
pnpm build

# Lint
pnpm lint

# Format code
pnpm format

# Type check
pnpm type-check

Docker Development

This project includes a Docker development environment for consistent builds:

# Build and start container
docker-compose up -d

# Run commands in container
docker-compose exec kheavyhash pnpm test
docker-compose exec kheavyhash pnpm build

# Stop container
docker-compose down

VS Code / Cursor Dev Container

The project includes a .devcontainer configuration for VS Code and Cursor:

  1. Open the project in VS Code/Cursor
  2. When prompted, click "Reopen in Container"
  3. The development environment will be set up automatically

Testing

This project follows FIRST principles for unit testing:

  • Fast: Tests run quickly with no external dependencies
  • Independent: Each test is isolated and independent
  • Repeatable: Tests produce deterministic results
  • Self-Validating: Clear pass/fail outcomes
  • Timely: Tests written alongside implementation

Test Suites

# Run all tests
pnpm test

# Run tests with coverage
pnpm test:coverage

# Run tests in watch mode
pnpm test:watch

Test Vectors

Test vectors from the Go reference implementation are available in test/kheavyhash-vectors.test.ts. These validate the implementation against known outputs from github.com/bcutil/kheavyhash.

Iteration Testing

Test 1000 iterations by feeding output back as input:

# TypeScript-only test
pnpm test:iterations

# Compare with Go implementation (requires Go)
pnpm test:iterations:go

Extended Comparison Script

Compare the TypeScript implementation with the Go reference implementation side-by-side:

# Test if Go module is accessible
bash scripts/test-go-module.sh

# Using bash script (requires Go and built TypeScript)
bash scripts/compare-with-go.sh

# Using TypeScript script (requires Go, tsx, and built TypeScript)
pnpm test:compare

Prerequisites for comparison script:

  • Go must be installed
  • Go module github.com/bcutil/kheavyhash must be available
  • TypeScript implementation must be built (pnpm build)

Versioning

This project follows Semantic Versioning (SemVer 2.0.0).

Version Format

MAJOR.MINOR.PATCH

Version Bump Rules

  • MAJOR version: Incompatible API changes
  • MINOR version: Backward-compatible new features
  • PATCH version: Backward-compatible bug fixes

Current Version

  • Current: 0.1.0 (pre-release)
  • Stability: Pre-1.0.0 versions may have breaking changes

Version History

See CHANGELOG.md (if available) or git history for version history.

Contributing

This project uses Conventional Commits for commit messages.

Commit Format

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Allowed types:

  • feat: New feature (→ MINOR bump)
  • fix: Bug fix (→ PATCH bump)
  • docs: Documentation changes
  • style: Formatting, no code logic changes
  • refactor: Code changes that neither fix bugs nor add features
  • test: Add/modify tests only
  • chore: Maintenance tasks
  • perf: Performance improvements
  • build: Build system changes
  • ci: CI configuration changes
  • revert: Reverts a previous commit

Breaking changes:

  • Must include ! after the type/scope, OR
  • Must include a BREAKING CHANGE: footer
  • Breaking changes require a MAJOR version bump

License

MIT - See LICENSE file for details.

Third-Party Licenses

This package includes code adapted from external sources. See THIRD_PARTY_LICENSES.md for details.

References