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

poker-calculations

v1.3.2

Published

NL Hold'em hand evaluation, Monte Carlo equity, decideAction, and chip / GTO math — C++ core with prebuilt N-API addon.

Downloads

1,643

Readme

poker-calculations — NL Hold’em engine & odds helpers (C++ core, Node addon)

No-Limit Texas Hold’em hand evaluation, Monte Carlo equity (single- and multi-threaded), pot-odds and chip-EV helpers, and a rule-based decideAction layer—implemented in C++ and exposed to Node via N-API.

Published releases ship prebuilt native binaries (node-gyp-build), so npm install does not require CMake, a compiler, or the Windows SDK on the installing machine.

Full TypeScript types: index.d.ts.

Install

Requirements: Node.js 18+.

npm install poker-calculations

Published tarballs include N-API prebuilds under prebuilds/<platform>-<arch>/:

  • node.napi.node — glibc Linux, macOS, Windows (default).
  • node.napi.musl.node — same directory on linux-x64 / linux-arm64 when you install on Alpine / musl.

Linux glibc binaries are linked with -static-libstdc++ / -static-libgcc so they do not require as new a system libstdc++.so as a binary built on the latest Ubuntu runner (this avoids GLIBCXX_* version errors on older Linux images, including many serverless hosts).

Bundlers and Next.js

Load this package from runtime code paths (for example a lazy require() inside a route handler) if your bundler or next build evaluates server modules statically. That avoids optional build-time native resolution issues; you still need a prebuild that matches the deployment OS and libc (glibc vs musl).

Quick start

This is a Node.js libraryrequire or import it and call functions. There are no HTTP endpoints unless you wrap it yourself.

CommonJS

const poker = require('poker-calculations');

poker.evaluateBestHand(['Ah', 'Ac', 'Kd', 'Ks', 'Qh']); // native — best 5 of 7
const equity = poker.simulateHandOutcome(['Ah', 'Kh'], ['Qh', 'Jh', 'Th'], 2000, 42, 1);
const spr = poker.spr(90, 270); // native (C++ chip math)

ESM

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const poker = require('poker-calculations');

Runnable samples are separate ESM scripts under examples/: one topic per file (see the header comment in each script; names align with groups in FEATURES_ADDED.md). From the repo root: node examples/<name>.mjs.

  • examples/native-binding-exports.mjs — print every N-API export at runtime.
  • Topic demosfold-equity.mjs, gto-frequency.mjs, hand-resolution.mjs, heuristics-draws.mjs, icm.mjs, intervals-and-odds-bridge.mjs, kelly-chubukov-jam.mjs, monte-carlo-equity.mjs, multiway.mjs, pot-chip-ev-rake.mjs, reverse-implied-geometry.mjs, side-pots.mjs, sizing-commitment.mjs, stacks-display.mjs, stats-risk.mjs, strategy-decide-action.mjs.

Cards are strings like "Ah", "Td" (ten may be "10h").

API overview

All symbols below are exported from the native addon (C++ via N-API). breakevenCallEquity(potBeforeCall, toCall) equals potOddsRatio(pot, toCall) when the same pot and call amounts are used.

| Area | Exports | | --- | --- | | Hands & equity | evaluateBestHand, evaluateHandStrength, evaluateHandCategory, handRankCategoryOrder, validateCardString, cardStringsHaveDuplicate, canonicalCardString, parseCompactCardList, compareBestHands, simulateHandOutcome, parallelHandSimulation, exactHuEquityVsRandomHand, straightMadeFlopToRiverExactProbability | | Strategy | decideAction | | Pot / EV | potOddsRatio, expectedValueCall, expectedValueCallWithRake, breakevenCallEquity, breakevenCallEquityFromPotOddsDisplayRatio, potOddsDisplayRatioFromBreakevenCallEquity, breakevenCallEquityWithRake, rakeFromPot, formatPotOddsReducedFraction, equityToWinningOddsAgainst, winningOddsAgainstToEquity | | Stacks & display | spr, effectiveStack, normalizedStackFractions, stackInBigBlinds, potOddsRatioDisplay, formatPotOdds, harringtonM, harringtonMEffective, harringtonMEffectiveActiveAntes, harringtonQ, orbitCostChips, nlMinimumRaiseToTotal, preflopCombosFromNotation, preflopCombosFromNotationsList | | Heuristics & draws | ruleOfFourEquity, ruleOfTwoEquity, estimatedOutsFromRuleOfTwo, estimatedOutsFromRuleOfFour, impliedBreakevenFutureWin, hypergeometricOneCardHitProbability, runnerRunnerBackdoorFlushTwoCardProbability, runnerRunnerStraightDrawHitProbability, flopToRiverAtLeastOneHitProbability, flopToRiverAtLeastOneHitUnionTwoCategories, flopToRiverAtLeastOneHitUnionThreeCategories, flopToRiverAtLeastOneHitUnionFourCategories, flopToRiverAtLeastOneHitDisjointOutsSum, duplicationAdjustedOuts | | Reverse implied / geometry | reverseImpliedOddsMaxFutureLoss, geometricPotAfterMatchedPotFractions | | Stats & risk | monteCarloStandardError, monteCarloTrialsForStandardErrorBound, monteCarloTrialsForHoeffdingBound, wilsonScoreInterval, agrestiCoullInterval, normalWaldBinomialInterval, riskOfRuinDiffusionApprox, bankrollForTargetRorDiffusion, betaBinomialFoldPosterior | | Kelly & jam toys | kellyCriterionBinary, chubukovSymmetricJamBreakevenStack, chubukovSymmetricJamEv, chubukovMaxSymmetricJamStackChipsBinarySearch, chubukovMaxSymmetricJamStackBinarySearch, chubukovMaxSymmetricJamStackFromHandBinarySearch | | GTO-style | minimumDefenseFrequency, alphaFrequency, bluffToValueRatio, valueToBluffRatio | | Sizing & commitment | betAsPotFraction, sprAfterCall, commitmentRatio | | Fold equity | breakevenFoldEquityPureBluff, breakevenFoldEquityPureBluffWithRake, breakevenFoldEquitySemiBluff, breakevenFoldEquitySemiBluffWithRake, twoStreetPureBluffSameFoldEquity, twoStreetPureBluffEv, breakevenFoldEquitySecondStreetPureBluff, breakevenFoldEquityFirstStreetPureBluff | | Multiway | multiwaySymmetricBreakevenCallEquity, multiwaySymmetricBreakevenCallEquityWithShare | | ICM | icmWinProbabilitiesHarville, icmHarvillePlacementProbabilities, icmTopKFinishProbabilities, icmLastPlaceProbabilitiesHarville, icmExpectedPayouts, icmPairwiseBubbleFactor | | Side pots | sidePotLadderFromCommitments, layeredPotChipEvFromEquities, sidePotLayersTotalChips |

Breaking change (v1.2.0): poker-math.js was removed; require poker-calculations (or the .node binding) for all math. Rebuild native artifacts after upgrading from a git clone.

API note: chubukovMaxSymmetricJamStackBinarySearch / chubukovMaxSymmetricJamStackFromHandBinarySearch take hole cards, board (3–5 cards), dead money, and max stack; they return the largest integer jam size with nonnegative symmetric-jam EV using exact HU equity vs a random hand. The FromHand variant uses int32 coercion for maxStackChips in native code.

Responsible use

Use this for your own simulator, research, or automation you are permitted to run. It is not intended to help bypass third-party terms of service on real-money sites.

Features (engine)

| Area | What’s included | | --- | --- | | Cards / deck | 52-card deck, shuffle with injected std::mt19937, deal, burn on board deals in GameEngine | | State & rules | PokerGameState, blinds, pot, per-street commits, phase machine (pre-flop → river → showdown), GameEngine::apply_action with Decision | | Evaluation | Best five of up to seven cards, full ranking + kickers, evaluate_hand_strength scalar | | Strategy | decide_action(..., BotConfig, OpponentModel*) using MC equity (or strength fallback when sim count is 0), pot odds, and call EV | | Simulation | simulate_hand_outcome, parallel_hand_simulation (chunked async workers, distinct seeds) | | Config | BotConfig::load_from_config_file / save_to_config_file (key=value, # comments) | | Tests | GoogleTest suite (deck, engine, evaluator, card strings, poker math, ICM, side pots, exact equity, strategy, opponent model, MC, config) |

Developing from source

If you clone the repo or install from a git URL without local prebuilds, you need a C++ toolchain (CMake 3.16+, and MSVC with C++ workload on Windows, Xcode CLI tools on macOS, or GCC on Linux). Published tarballs from npm do not compile native code during install.

npm ci
npm run build:native
node scripts/stage-prebuild.js <platform-arch>

Use the <platform-arch> tuple node-gyp-build expects (for example win32-x64, linux-x64, darwin-arm64). For Alpine/musl, stage with node scripts/stage-prebuild.js linux-x64 musl (writes node.napi.musl.node). On Windows, delete a stale build folder if configure fails; ensure the Windows SDK is installed if you see resource-compiler (rc) or manifest (mt) errors.

Rebuild after changing C++:

npm run build:native

Native tests

npm test

On Windows this expects MSVC on PATH like the build steps above.

Maintainers: publishing

Publishing uses .github/workflows/npm-publish.yml. It starts automatically when package.json or package-lock.json changes on main (for example merging a version bump). The release gate still skips the native build and npm publish when that version is already on npm, so dependency-only lockfile edits do not republish. You can also re-run from Actions → npm publishRun workflow (same branch as the failed run, usually main) without a new commit.

npm Trusted Publishing (OIDC)

Publishing uses trusted publishing — GitHub Actions proves identity to npm with OIDC; you do not store an NPM_TOKEN secret for npm publish.

  1. On npmjs.com → package poker-calculationsSettingsTrusted Publisher, connect GitHub Actions using:
    • Repository that matches repository.url in package.json exactly (npm validates at publish time; npm does not validate when you save). Current value: git+https://github.com/DevomB/Poker-Calculations.git
    • Workflow filename npm-publish.yml (same casing and .yml extension). If you previously used native-prebuild.yml, update the trusted publisher entry on npm to this filename (or add a second allowed workflow and remove the old one).
  2. After proving publishes work, optionally tighten Publishing access (“Require 2FA and disallow tokens”) and revoke old automation tokens, per npm’s migration guidance.

All dependencies used during CI are public; npm ci does not need a read token. If you later add private npm dependencies, use a read-only granular token only on install steps, not for publish.

Release steps

  1. On main, bump package.json version and keep package-lock.json in sync (for example npm install --package-lock-only after dependency or version changes), then push or merge to main.
  2. The npm publish workflow runs from that push. If it failed before npm accepted the package, fix and push (or use Run workflow on main to retry without changing files).

The release gate runs npm ci (so a broken or stale lockfile fails fast), then checks whether name@version already exists on npm. If not, it builds native targets (including musl artifacts as node.napi.musl.node), merges them under prebuilds/, and runs npm publish via OIDC. No git tags — the version field is the release input. With trusted publishing on a public repo, npm records provenance automatically. If that version is already on npm, the workflow skips build and publish.

If publish fails: fix the underlying issue, push commits without bumping version again, and re-run the same workflow until it succeeds — then increment only for the next release. That keeps npm version numbers from skipping.

Use GitHub-hosted runners for this workflow: OIDC trusted publishing does not support self-hosted runners yet (npm docs). The workflow pins Node ≥22.14 to satisfy npm’s trusted-publishing runtime requirement alongside npm CLI ≥11.5.1 in the publish job.

In the GitHub repo, under Settings → Actions → General → Workflow permissions, use the default that allows Actions to run; the publish job sets id-token: write so OIDC works for npm publish.

Manual publish: assemble binaries under prebuilds/, then npm publish. Without binaries, prepack fails unless SKIP_PREBUILD_CHECK=1.

Repository layout

include/poker/     Public headers (Card, Deck, GameEngine, HandEvaluator, poker_math, …)
src/               Implementations (`poker_math.cpp` — SPR, MDF, fold equity, …)
native/            Node-API binding (built when CMAKE_JS_INC is set by cmake-js)
tests/             Unit tests
examples/          Node ESM sample scripts (one feature area per file; see FEATURES_ADDED.md)
CMakeLists.txt     Static poker_lib; optional poker_tests; optional poker_calculations.node when built by cmake-js

Generic (single-configuration generators)

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

Run tests:

cd build
ctest --output-on-failure

Windows: MSVC with NMake (when cl is not on PATH)

Open x64 Native Tools or run vcvars64.bat, then:

cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -S . -B build_nmake
cmake --build build_nmake
cd build_nmake
ctest --output-on-failure

CMake options

| Option | Default | Meaning | | --- | --- | --- | | POKER_BUILD_TESTS | ON (non–cmake-js); OFF if CMAKE_JS_INC is set | Build poker_tests and GoogleTest. Off for fast npm addon builds. |

When cmake-js configures the project, it defines CMAKE_JS_INC and only poker_calculations.node plus poker_lib are built—tests are skipped so the addon build stays fast and does not pull GoogleTest.

Disable tests manually:

cmake -S . -B build -DPOKER_BUILD_TESTS=OFF

GCC note

Tests link libstdc++fs when using GNU C++ for std::filesystem in config tests.

Configuration file (BotConfig)

# bot.txt
aggression_threshold=0.55
risk_tolerance=0.92
monte_carlo_simulations=800
monte_carlo_villains=1
raise_pot_fraction=0.55
opponent_aggression_weight=0.05
rng_seed=2463534242

Load with BotConfig::load_from_config_file("bot.txt").

Quick C++ API sketch

  • State & engine: poker::PokerGameState, poker::GameEngine::start_new_hand, apply_action, advance_phase_if_ready
  • Hands: poker::evaluate_best_hand, poker::evaluate_hand_strength, poker::evaluate_hand
  • Equity: poker::simulate_hand_outcome, poker::parallel_hand_simulation
  • Decision: poker::decide_action(state, hero_hole_cards, cfg, opponent_model, hero_seat)
  • Chip / GTO math: poker::spr, poker::minimum_defense_frequency, poker::breakeven_fold_equity_pure_bluff, … (poker_math.hpp)
  • Integration: subclass poker::PokerBotInterface or use poker::MockPokerBotInterface for tests

Headers live under include/poker/. Link against poker_lib.

Contributing

Strategy thresholds and MC counts are centralized in BotConfig. After changes, run npm test or ctest; MC-heavy tests use statistical bands (e.g. AA pre-flop equity vs one random hand).

License

ISC — see LICENSE in this repository.