Skip to content

The package

OpenDice is the npm package that does the rolling. It has no dependencies, ships its own types and source maps, and runs in browsers, Node 20 or newer, and edge runtimes alike.

Terminal window
npm i opendice
Export What it does
roll(formula, options?) Rolls a formula and returns the result
parseFormula(text, opts?) Reads a formula without rolling it, for checking input
rollDie(sides, source?) Rolls one die and returns a number
cryptoRandom() The raw random number the dice are built on
keptFlags(group) Which dice counted, aligned to the roll order
soleDieGroup(result) The dice in a result, if it used only one kind

The package README documents each export in full. What follows is what you need most often.

Parses and rolls, returning the shape described in Result fields.

import { roll } from 'opendice'
const result = roll('4d6kh3')

options carries the same three things the API takes in a request body.

Option Type Meaning
advantage 'advantage' | 'disadvantage' Applied to the first plain d20 term
bonuses array of numbers or strings Extra terms added to the roll, such as 3 or '1d4'
tags array or Set of strings The trailing words to accept as a tag

Two things catch people out. A bonus that is a plain number must be sent as a number: the string '3' contains no dice and throws. And tags must be a list, not a single string — a bare 'fire' is rejected rather than read as one tag.

Reads a formula and throws if it cannot, without rolling anything. Costs roughly a hundredth of what rolling does, which makes it the right way to check input as it is typed. See Validate a formula someone typed.

Takes one entry from result.dice and returns booleans aligned to its results.

import { keptFlags, roll } from 'opendice'
const result = roll('4d6kh3')
keptFlags(result.dice[0]) // [true, true, true, false]

Over HTTP this arrives as a field on the group instead. It is a function here so the package does not build the list unless you ask for it.

Every die goes through crypto.getRandomValues. cryptoRandom() is that source directly, and rollDie(sides, source?) takes an optional source of your own.

That last parameter exists for testing, and it is the one part of the package the API does not expose — see What Rollful does not know.