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

crack-pack

v0.10.0

Published

A Magic: The Gathering pack-collation simulator — as realistic as the available print-sheet data allows (see ASSUMPTIONS.md; contributions welcome)

Readme

crack-pack

A dependency-free TypeScript library that simulates Magic: The Gathering pack openings as realistically as the available print-sheet data allows — by modelling the physical print-sheet collation process rather than flat rarity odds. Cards are cut from ordered print sheets in a deterministic walk, so a pack is a correlated run of cards and a box is not N independent packs.

How realistic? Only as realistic as the underlying data. For some sets the sheets and collation are validated against real openings; for others the sheet data is solid but the collation is assumed, simplified, or (in one case) the sheet itself is a placeholder. Every such gap is documented, per set, in ASSUMPTIONS.md — read it before trusting any given set's output. Help closing these gaps is very welcome — see Help wanted.

Sets

Twelve sets, from Alpha (1993) through Mirage (1996). For each set's exact per-sheet structure and how confident we are in its collation (validated / assumed / simplified / placeholder), see the status matrix in ASSUMPTIONS.md.

| Code | Set | | --- | --- | | lea | Limited Edition Alpha (1993) | | leb | Limited Edition Beta (1993) | | 2ed | Unlimited Edition (1993) | | 3ed | Revised Edition (1994) | | 4ed | Fourth Edition (1995) | | arn | Arabian Nights (1993) | | atq | Antiquities (1994) | | leg | Legends (1994) | | drk | The Dark (1994) | | fem | Fallen Empires (1994) | | ice | Ice Age (1995) | | mir | Mirage (1996) |

Core model

| Type | Meaning | | --- | --- | | Sheet | Ordered 11×11 grid of card positions; basic lands are filler and can appear in any slot. | | CollationMethod | How a sheet is walked into a stream. Both striped and sequential (plain row-major read, wrapping) are implemented. | | stripeCycle | Repeating stripe-width cycle (Alpha [2,3,4,5]); collation is deterministic given it. Either one cycle for the whole set, or a per-rarity map when sheets stripe differently (Arabian Nights: common [3,4,5], uncommon [3,4]). | | PackLayout | Cards drawn per sheet, in order. Booster: 11C / 3U / 1R. Starter: 45C / 13U / 2R. Arabian Nights: 6C / 2U (no rare). | | SetDefinition | code, name, sheets, layout, stripeCycle; resolved via getSet(code) / sets. |

Striped collation

Each sheet is cut by a striped walk: start at position 1 = (col 11, row 11); take width cards up each column; traverse columns right → left; advance the band up by width when a stripe finishes the leftmost column; wrap top→bottom and across sheets. Widths follow the fixed cycle 2, 3, 4, 5, so the walk is deterministic and realigns to position 1 every 14 sheets (1694 cards).

All sheets are phase-locked to one pack index N: rare = rare-position N, uncommons = uncommon-positions 3N…3N+2, commons = common-positions 11N…11N+10. Pack 0 is the first pack of a fresh run; there are 1694 distinct packs. The only free choice is N — supplied explicitly via startPack, or derived from seed.

Install

npm install crack-pack

Usage

import { getSet, openPack, openPacks } from 'crack-pack';

const lea = getSet('lea');
const first = openPack(lea, { startPack: 0 }); // the canonical first-ever pack
const box = openPacks(lea, 36, { seed: 42 });  // 36 correlated packs, reproducible

Runs on Node 22.18+ with no build step (native TypeScript type-stripping):

npm test          # sheet + collation tests
npm run demo 42   # open a pack

Data & validation

Sheet layouts come from The Collation Project and observation data. Each sheet is checksum-validated against known rarity totals (Alpha: 74 / 95 / 116) and basic-land fills. The striped model is validated against real pack-opening sequences (test/collation-observed.test.ts) and against known sheet positions and the 14-sheet period (test/collation-model.test.ts).

  • Orientation: row 1 = top, column 1 = left, row-major.
  • Alpha has two basic-land variants (A/B); Beta and Unlimited have three (A/B/C).
  • Beta/Unlimited add Circle of Protection: Black (common) and Volcanic Island (rare); Alpha replaced the latter with a basic Island.
  • Unlimited reuses Beta's exact sheet layout and collation (only the printed cards differ — white border).
  • Revised (3ed) is a base-set reprint with a Beta/Unlimited-like layout (non-land totals 75 / 95 / 121; three basic-land variants A/B/C). Basic lands fill both the common and uncommon sheets; the rare sheet has none (the Beta rare-Islands were removed, so Islands are slightly short-printed). Stripe cycle assumed [2,3,4,5] (no explicit cycle in the source).
  • No half-sheet splitting; whole 11-row sheets only.
  • Arabian Nights has no rare sheet — rarity is emergent from how often a card repeats (common: 16×4 + 9×5 + Desert ×11 + Mountain ×1; uncommon: 33×2 + 17×3 + Oasis ×4, both checksum-validated). 15 common cards have "light"/"dark" versions (the earlier bottom-right 6×6 quadrant), kept verbatim in the sheet data. The two sheets stripe with different width cycles, giving 1694 distinct packs.
  • Antiquities is like Arabian Nights: no rare sheet, rarity by repeat count (common: 11×C1 + 5×C2 + 25×C4; uncommon: 26×U1 + 4×U2 + 29×U3, both checksum-validated). Five non-basic lands (Urza's Mine/Power Plant/Tower, Mishra's Factory, Strip Mine) have four art variants each, notated (A)(D). Stripe widths are provisional — the sheet grids are validated, but the stripe order (which cards pack together) is assumed equal to Arabian Nights pending validation against a box-opening video.
  • Legends has three sheets (common 75, uncommon 114, rare 121 — checksum-validated). Its uncommon sheet is collated as two half-sheets — top 6 rows ("A", incl. Mana Drain) and bottom 5 rows ("B", incl. Karakas) — and a whole box draws uncommons from one half; pass openPacks(leg, n, { half: 'A' | 'B' }). Provisional: stripe widths assumed [2,3,4,5], and the half split assumed row-major top-6/bottom-5 (doesn't perfectly reproduce the source's "only Hammerheim on both halves"), pending validation against box openings.
  • The Dark is like Arabian Nights/Antiquities: no rare sheet, rarity by repeat count (common: 40×C3 + Maze of Ith ×1; uncommon: 43×U2 + 35×U1, both checksum-validated). Its real collation is variable per box (sheets may or may not split, with 2–3 independent common sequences, or width-7 stripes when unsplit), so it can't be reproduced deterministically — we model it as a plain two-sheet striped set with an assumed [2,3,4,5] cycle. The grids are validated; the pack grouping is a deliberate simplification.
  • Fallen Empires: no rare sheet (common: 15×C4 + 20×C3 + Delif's Cone ×1; uncommon: 25×U3 + 5×U2 + 36×U1, checksum-validated). Its commons are multi-art — a common has a distinct artwork for each time it appears (C4 → four, C3 → three), notated (A)(D). Like The Dark, the uncommon sheet may or may not split per box, so collation is simplified to a plain two-sheet striped model with an assumed [2,3,4,5] cycle.
  • Ice Age (121 commons / 121 uncommons / 121 rares) has real sheet data for all three rarities. The common and uncommon sheets come from the Collation Project; the rare sheet was transcribed by hand from a photo of the uncut rare sheet on magiclibrarities.net (the Collation Project page has no rare-sheet gallery), validated so all 121 rares appear exactly once, with positions eyeballed against the photo. Its individual rare positions rest on a manual read of a photograph, so a small number could be off by a cell — corrections welcome. Basic/snow-covered lands are on a separate land sheet and don't appear in boosters. Common uses "version 1" of two printings; stripe cycle [2,3,4,5] assumed.
  • Mirage (110 commons / 110 uncommons / 110 rares, all real grids) had two printings — a US sequential one (four common runs) and a Belgian striped one. We model the Belgian striped printing; the engine now supports sequential collation, but the US printing's multi-run, probabilistic-split assembly isn't modelled yet. Sheets are 10×11 (non-square), so the walk depends on row/column orientation, which the source doesn't pin down — we assume 10 rows × 11 columns. Stripe cycle [2,3,4,5] assumed. Basic lands (four variations) aren't in boosters.

See ASSUMPTIONS.md for the full list of modelling assumptions and their validation status.

Help wanted

This project is only as accurate as the print-sheet data behind it — and there are gaps. If you have specialist knowledge of Magic's print-sheet collation, or images/data for print sheets or collation patterns we're missing or only approximating, please open an issue or PR.

Particularly wanted (see ASSUMPTIONS.md for details):

  • Missing sheets — any set's sheets not yet on The Collation Project (e.g. Chronicles, Homelands, Alliances).
  • Stripe-width sequences — the real per-sheet widths for Antiquities, Legends, The Dark, Fallen Empires, Mirage (currently assumed).
  • Collation specifics — e.g. the Legends uncommon half-split orientation, and the Mirage US sequential multi-run splits.
  • Anything — corrections, box-opening footage, or physical-sheet scans that can validate or refine a set.

Contributions and expertise are hugely appreciated — the goal is to make this as realistic as the community's collective knowledge allows.