Bridge Training
Bridge Core

Usage

How to integrate and use @workspace/bridge-core in your application.

Installation

Add the dependency to your app's package.json:

{
  "dependencies": {
    "@workspace/bridge-core": "workspace:*"
  }
}

Engine Factory

The BridgeEngine is the primary way to consume bridge-core. It composes all modules based on a BridgeContext.

Creating an Engine

import { createBridgeEngine } from '@workspace/bridge-core';

const engine = createBridgeEngine({
  teachingMode: 'auction',
  locale: 'fr',
});

BridgeContext

The input context determines how the engine behaves:

PropertyTypeDescription
teachingModeTeachingModeDrives all derived configurations (rules, variant, card count)
localeLocale (optional)Locale for notation parsing/formatting (defaults to "en")

The teachingMode determines:

  • The suit variant (classic or petit-bridge) — which icons, colors, and ranks to use
  • The core config — number of cards per hand, valid ranks, whether auctions are enabled
  • The teaching rules — which features are available in the current mode

Available Modules

The engine exposes these modules:

ModuleDescription
engine.handsHand distribution, validation, queries, transforms
engine.auctionBid parsing, contract calculation, auction state
engine.notationLocale-aware rank parsing, formatting, suit mappings
engine.teachingTeaching mode logic and pedagogy
engine.playerPlayer navigation, rotation, partnerships
engine.playTrick evaluation, card follow rules
engine.rotationHands/auction/vulnerability rotation
engine.pbnPBN format parsing
engine.formatDisplay formatting (contracts, bids)
engine.validationFull deal validation
engine.schemasZod validation schemas
engine.constantsGame constants and defaults
engine.parseCard and bid parsing utilities
engine.statsHand analysis (HCP, distribution, vulnerability)

Examples

Validate a hand:

const engine = createBridgeEngine({ teachingMode: 'auction' });

const hand = { S: ['A', 'K', 'Q'], H: ['J', '10'], D: ['9', '8', '7'], C: ['6', '5', '4', '3'] };
engine.hands.isHandComplete(hand); // true (13 cards)

Parse locale-specific notation:

const engine = createBridgeEngine({ teachingMode: 'auction', locale: 'fr' });

engine.notation.parseRanks('RDV');  // ["K", "Q", "J"]
engine.notation.formatRank('K');     // "R"

Calculate a contract:

const engine = createBridgeEngine({ teachingMode: 'auction' });

const sequence = ['1S', 'Pass', '2S', 'Pass', 'Pass', 'Pass'];
const contract = engine.auction.calculateContract(sequence, 'N');
// { level: 2, suit: 'S', declarer: 'N', doubled: false, ... }

Check teaching mode rules:

const engine = createBridgeEngine({ teachingMode: 'petit-bridge' });

engine.teaching.variant;                    // "petit-bridge"
engine.teaching.areAuctionsEnabled('petit-bridge', false); // false

Direct Module Imports

For tree-shaking or when you don't need the full engine, import modules directly via sub-path exports:

import { getPlayersInTrickOrder } from '@workspace/bridge-core/player';
import { isValidCard } from '@workspace/bridge-core/card';
import { parseRanks } from '@workspace/bridge-core/notation';

These are stateless utilities — they don't require a BridgeContext and have zero configuration. See the Overview page for the full list of sub-path exports.

Architecture

The package is organized in layers:

  1. Foundation — Types, constants, errors (no dependencies)
  2. Primitives — Player, card, format (stateless utilities)
  3. Domain — Auction, hands, play, teaching (game rules, may depend on config)
  4. Cross-cutting — Rotation, validation, schemas, utils
  5. Integration — Engine (composes all modules via BridgeContext)

The engine factory (createBridgeEngine) derives per-module configurations from the BridgeContext, then creates and composes all modules:

BridgeContext
  ├─ deriveHandsConfig()     → createHandsModule()
  ├─ deriveAuctionConfig()   → createAuctionModule()
  ├─ deriveTeachingConfig()  → createTeachingModule()
  ├─ deriveNotationConfig()  → createNotationModule()
  └─ (no config needed)      → createPlayerModule(), createPlayModule(), ...

On this page