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

dice-table

v1.0.5

Published

CLI and SDK for tabletop RPG dice rolling

Readme

Dice Table

A powerful, fast, and secure dice rolling utility for tabletop RPGs. Works both as a CLI tool and an importable library for Node.js projects.

Features

  • Zero Dependencies - Core engine uses only Node.js built-ins
  • Cryptographic Randomness - Uses crypto.randomInt() for fair, secure rolls
  • Complete Notation Support - All standard tabletop RPG dice notation including shorthand
  • CLI & Library - Use from command line or integrate into your projects
  • Dual Output Modes - Human-readable and JSON output for applications
  • Comprehensive Error Handling - Helpful hints for humans, structured errors for apps
  • Fast & Lightweight - Optimized for high performance

Installation

Global CLI Installation

npm install -g dice-table

Library Installation

npm install dice-table

Quick Start

Command Line Usage

# Basic roll
dice roll 1d20

# Roll with modifier
dice roll 1d20+5

# Advantage roll (D&D 5e) - shorthand notation
dice roll 2d20kh

# Generate ability scores
dice roll 4d6kh3 --times 6

# Statistical analysis
dice stats 3d6 --iterations 10000

# JSON output for applications
dice roll 2d6+5 --json

Library Usage

const dice = require('dice-table');

// Simple roll
const result = dice.roll('2d6+5');
console.log(result.total); // 7-17

// Multiple rolls
const results = dice.rollMany('1d20+5', 6);

// Statistical analysis
const stats = dice.stats('4d6kh3', { iterations: 10000 });

// Error handling
if (result.valid) {
  console.log(`Rolled: ${result.total}`);
} else {
  console.error(`Error: ${result.error}`);
}

Dice Notation Reference

Basic Notation

| Expression | Description | |------------|-------------| | 1d6 | Roll one six-sided die | | 2d20 | Roll two twenty-sided dice | | 3d8+5 | Roll three d8s and add 5 | | 1d20-2 | Roll one d20 and subtract 2 |

Keep/Drop Mechanics

| Expression | Description | |------------|-------------| | 2d20kh | Roll 2d20, keep highest 1 (advantage - shorthand) | | 2d20kh1 | Roll 2d20, keep highest 1 (advantage - explicit) | | 2d20kl1 | Roll 2d20, keep lowest 1 (disadvantage) | | 4d6kh3 | Roll 4d6, keep highest 3 (ability scores) | | 4d6dh1 | Roll 4d6, drop highest 1 | | 4d6dl1 | Roll 4d6, drop lowest 1 |

Complex Expressions

| Expression | Description | |------------|-------------| | 1d20+1d8+5 | Attack roll with weapon damage | | 2d20kh1+1d6+3 | Advantage attack with sneak attack | | 3d6+2d4-1 | Multiple dice types with modifier |

Supported Die Types

  • Standard RPG Dice: d4, d6, d8, d10, d12, d20, d100

CLI Reference

Commands

dice roll <expression> [options]

Roll dice using standard RPG notation.

Options:

  • --times, -t <N> - Roll the expression N times (max: 1000)
  • --json - Output result in JSON format for applications
  • --help, -h - Show help for this command

Examples:

dice roll 1d20                 # Single d20
dice roll 2d6+5                # 2d6 with +5 modifier
dice roll 4d6kh3               # 4d6 keep highest 3
dice roll 2d20kh+5             # Advantage with modifier (shorthand)
dice roll 3d6 --times 6        # Roll 6 times for stats
dice roll 1d20+5 --json        # JSON output for apps

dice stats <expression> [options]

Analyze the statistical distribution of a dice expression.

Options:

  • --iterations <N> - Number of simulations (default: 10000, range: 100-100000)
  • --json - Output result in JSON format for applications
  • --help, -h - Show help for this command

Examples:

dice stats 3d6                 # Basic 3d6 analysis
dice stats 4d6kh3              # Ability score generation
dice stats 1d20+5 --iterations 50000  # High-precision analysis
dice stats 2d20kh --json       # JSON output for analysis

dice help [command]

Show help information.

Examples:

dice help                      # General help
dice help roll                 # Help for roll command
dice help stats                # Help for stats command

Error Handling

Dice Table provides comprehensive error handling for both human users and applications:

CLI Error Handling

# Human-readable errors with helpful hints
$ dice roll invalid
Error: Invalid dice expression format. Use format like "2d6", "1d20+5", or "4d6kh3"
Hint: Use format like "2d6", "1d20+5", or "4d6kh3"

# JSON errors for applications
$ dice roll invalid --json
{"success":false,"error":"Invalid dice expression format. Use format like \\"2d6\\", \\"1d20+5\\", or \\"4d6kh3\\"","hint":"Use format like \\"2d6\\", \\"1d20+5\\", or \\"4d6kh3\\""}

# Parameter validation
$ dice roll 1d20 --times -1
Error: --times must be at least 1, got: -1
Hint: Use a positive number: --times 5

Library Error Handling

const result = dice.roll('invalid expression');

if (result.valid) {
  console.log(`Result: ${result.total}`);
} else {
  console.error(`Error: ${result.error}`);
}

Library API

Core Functions

dice.roll(expression)

Execute a single dice roll.

const result = dice.roll('2d6+5');

// Result structure:
{
  expression: '2d6+5',
  dice: [
    { type: 'd6', value: 4, kept: true, dropped: false },
    { type: 'd6', value: 3, kept: true, dropped: false }
  ],
  modifier: 5,
  total: 12,
  details: '[4, 3] + 5 = 12',
  valid: true
}

// Error handling:
const invalid = dice.roll('invalid');
// Returns: { error: 'Error message', expression: 'invalid', valid: false }

dice.rollMany(expression, times)

Roll multiple times and return array of results.

const results = dice.rollMany('1d20+5', 6);
// Returns array of 6 roll results

// Error handling:
const invalid = dice.rollMany('bad', 5);
// Returns array with error objects if expression is invalid

dice.parse(expression)

Parse a dice expression without rolling.

const parsed = dice.parse('4d6kh3');

// Returns parsed structure:
{
  valid: true,
  expression: '4d6kh3',
  parts: [
    {
      count: 4,
      sides: 6,
      keep: { type: 'highest', count: 3 }
    }
  ]
}

dice.validate(expression)

Validate a dice expression.

const validation = dice.validate('2d20kh1');

// Returns:
{ valid: true }

// Or for invalid expressions:
{ valid: false, error: 'Error message' }

dice.stats(expression, options)

Get statistical analysis of a dice expression.

const stats = dice.stats('3d6', { iterations: 10000 });

// Returns comprehensive statistics:
{
  expression: '3d6',
  iterations: 10000,
  theoretical: { min: 3, max: 18 },
  actualRange: { min: 3, max: 18 },
  statistics: {
    mean: 10.5,
    median: 11,
    mode: 10,
    standardDeviation: 2.96
  },
  percentiles: {
    p5: 6,
    p25: 8,
    p50: 11,
    p75: 13,
    p95: 15
  }
}

Utility Functions

dice.rollCli(expression, options)

Roll dice and format for CLI display.

const output = dice.rollCli('2d6+5');
console.log(output);
// "Rolling 2d6+5: [4, 3] + 5 = 12"

dice.rollData(expression)

Roll dice and return structured data for APIs.

const data = dice.rollData('1d20+5');
// Returns clean data structure suitable for JSON APIs

Use Cases

Discord Bot

const dice = require('dice-table');

bot.on('message', msg => {
  if (msg.content.startsWith('!roll ')) {
    const expression = msg.content.slice(6);
    const result = dice.roll(expression);

    if (result.valid) {
      msg.reply(`🎲 ${result.details}`);
    } else {
      msg.reply(`❌ ${result.error}`);
    }
  }
});

Game Engine

const dice = require('dice-table');

class Character {
  rollAttack() {
    const result = dice.roll(`1d20+${this.attackBonus}`);
    return result.total >= this.target.ac;
  }

  rollDamage() {
    return dice.roll(`${this.weapon.damage}+${this.strengthMod}`);
  }

  rollAbilityScores() {
    return dice.rollMany('4d6kh3', 6);
  }

  // Advantage/disadvantage
  rollWithAdvantage() {
    return dice.roll('2d20kh'); // Shorthand notation
  }
}

Web API

const express = require('express');
const dice = require('dice-table');

app.post('/api/roll', (req, res) => {
  const { expression } = req.body;
  const result = dice.rollData(expression);
  res.json(result);
});

app.get('/api/stats/:expression', (req, res) => {
  const stats = dice.stats(req.params.expression);
  res.json(stats);
});

Campaign Management

const dice = require('dice-table');

// Generate NPC stats
function generateNPC() {
  const stats = dice.rollMany('4d6kh3', 6);
  const hp = dice.roll('8d8+16'); // For a high-level character

  return {
    abilities: stats.map(r => r.total),
    hitPoints: hp.total
  };
}

// Mass combat simulation
function simulateBattle(rounds = 10) {
  const results = [];

  for (let i = 0; i < rounds; i++) {
    const attack = dice.roll('1d20+8');
    const damage = attack.total >= 15 ? dice.roll('2d6+4') : null;
    results.push({ attack: attack.total, damage: damage?.total || 0 });
  }

  return results;
}

Advanced Features

Statistical Analysis

The stats function provides comprehensive analysis:

const analysis = dice.stats('4d6kh3', { iterations: 100000 });

console.log(`Mean: ${analysis.statistics.mean}`);
console.log(`Standard Deviation: ${analysis.statistics.standardDeviation}`);
console.log(`95th Percentile: ${analysis.percentiles.p95}`);

Input Validation

function safeRoll(expression) {
  const validation = dice.validate(expression);

  if (!validation.valid) {
    throw new Error(`Invalid dice expression: ${validation.error}`);
  }

  return dice.roll(expression);
}

Performance & Constraints

Performance

  • Single Roll: < 1ms
  • 10,000 Rolls: < 100ms
  • Complex Expression (2d20kh1+1d8+5): < 2ms
  • Statistical Analysis (10k iterations): < 500ms

Constraints & Limits

  • Dice Count: 1-999 dice per component
  • Die Sides: d4, d6, d8, d10, d12, d20, d100 only
  • Modifiers: -9999 to +9999
  • CLI Times: 1-1000 rolls
  • CLI Iterations: 100-100,000 for stats
  • Total Dice: Maximum 999 dice across all components

Memory Usage

  • Zero Dependencies: No external packages
  • Lightweight: Small package size
  • Efficient: Minimal memory footprint

Security

  • Cryptographic Randomness: Uses crypto.randomInt() for true randomness
  • Input Validation: All expressions validated before execution
  • No Eval: Parser doesn't use eval() or similar unsafe functions
  • Bounded: All inputs have reasonable limits to prevent abuse

Contributing

Development Setup

git clone https://github.com/yourusername/dice-table.git
cd dice-table
npm install
npm test

Running Tests

npm test                    # Run all tests
npm run test:parser         # Test parser only
npm run test:roller         # Test roller only
npm run test:cli            # Test CLI only

Project Structure

dice-table/
   index.js                # Library entry point
   cli.js                  # CLI entry point
   lib/                    # Core modules
      parser.js           # Expression parser
      roller.js           # Random number generation
      validator.js        # Input validation
      formatter.js        # Output formatting
      stats.js            # Statistical analysis
   package.json

Adding Features

  1. Add functionality to appropriate module in lib/
  2. Export new functions from index.js
  3. Add comprehensive tests
  4. Update documentation
  5. Submit pull request

Changelog

v1.0.0

  • Initial release
  • Complete dice notation support including shorthand (2d20kh)
  • CLI interface with dual output modes (human/JSON)
  • Library API with comprehensive error handling
  • Statistical analysis with Monte Carlo simulation
  • Cryptographic randomness using crypto.randomInt()
  • Parameter validation with helpful error messages

License

ISC License - see LICENSE file for details.

Support

For help and support:

  • Use dice --help for CLI usage
  • Use dice <command> --help for command-specific help
  • Check error messages for helpful hints
  • Review examples in this README

Dice Table - Roll with confidence. 🎲