Skip to content

AdametherzLab/brewkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

brewkit 🍻

CI TypeScript License: MIT

Homebrew's secret sauce - Precision brewing calculations for grain, hops, and water chemistry. Never guess your strike temps or IBUs again!

🔥 Features

  • ✅ Mash calculations: Strike water temps, infusion volumes, efficiency
  • 🌡️ IBU formulas: Tinseth vs Rager methods with hop contribution breakdown
  • 🧪 Water chemistry: Mineral adjustments and profile balancing
  • ⚖️ Unit-aware: Metric/imperial conversions built-in
  • 🛠️ Fully typed API with production-grade error handling

📦 Installation

npm install @adametherzlab/brewkit
# or
bun add @adametherzlab/brewkit

🚀 Quick Start

// REMOVED external import: import { strikeWaterTemp, calculateIBU, adjustWater } from '@adametherzlab/brewkit';
// REMOVED external import: import type { MashConfig, HopAddition } from '@adametherzlab/brewkit';

// Calculate strike water temperature
const mashConfig: MashConfig = {
  grainWeight: 5.4,
  waterRatio: 2.8,
  targetTemp: 67,
  grainTemp: 18
};
console.log(`Heat water to ${strikeWaterTemp(mashConfig)}°C`); // → 72.3°C

// Determine IBUs for recipe
const hops: HopAddition[] = [
  { name: 'Amarillo', alphaAcid: 8.5, weight: 50, boilTime: 60 },
  { name: 'Mosaic', alphaAcid: 12.2, weight: 30, boilTime: 15 }
];
const ibuResult = calculateIBU(hops, 1.055, 5.5, 'TINSETH');
console.log(`Total IBU: ${ibuResult.totalIBU.toFixed(1)}`); // → 45.6 IBU

📚 API Reference

Mash Calculations

strikeWaterTemp(config: MashConfig): number
Params: grainWeight(kg), waterRatio(L/kg), targetTemp(°C), grainTemp(°C)
Returns: Strike temperature in °C

strikeWaterTemp({ grainWeight: 4.5, waterRatio: 3, targetTemp: 65, grainTemp: 22 }); // → 70.1

infusionVolume(currentVolume: number, grainWeight: number, currentTemp: number, targetTemp: number): number
Params: Current volume (L), grain weight (kg), current/target temps (°C)
Returns: Liters of boiling water needed

infusionVolume(15, 5, 63, 68); // → 4.87 L

Bitterness Calculations

calculateIBU(additions: HopAddition[], og: number, volumeGallons: number, method: IBUMethod): IBUResult
Params: Hop additions array, original gravity (1.XXX), batch volume (gal)
Returns: Object with total IBU and per-hop breakdown

calculateIBU([{alphaAcid: 6, weight: 30, boilTime: 60}], 1.050, 5, 'RAGER');

Water Chemistry

adjustWater(source: WaterProfile, target: WaterProfile, volumeLiters: number): MineralAddition[]
Throws if: Target requires ion reduction (use RO water instead)

adjustWater(
  {Ca: 50, Mg: 10, SO4: 80, Cl: 40}, 
  {Ca: 150, Mg: 20, SO4: 300, Cl: 50},
  25
);
// → [{mineral: 'CaSO4', grams: 12.4, volume: 25}]

🧪 Advanced Usage: Full Recipe Setup

// TypeScript example
import { 
  strikeWaterTemp, 
  calculateIBU,
  adjustWater,
  BrewTypes,
  type MashConfig,
  type HopAddition
} from '@adametherzlab/brewkit';

// Configure mash for American IPA
const mashSetup: MashConfig = {
  grainWeight: 6.8,
  waterRatio: 2.6,
  targetTemp: 66,
  grainTemp: 20.5
};
const strike = strikeWaterTemp(mashSetup);

// Calculate hop schedule
const hopAdditions: HopAddition[] = [
  { name: 'Centennial', alphaAcid: 10, weight: 60, boilTime: 60 },
  { name: 'Simcoe', alphaAcid: 13.5, weight: 40, boilTime: 10 }
];
const ibu = calculateIBU(hopAdditions, 1.065, 6, BrewTypes.IBUMethod.TINSETH);

// Adjust water profile for crisp bitterness
const additions = adjustWater(
  { Ca: 75, Mg: 8, SO4: 120, Cl: 50 },
  { Ca: 150, Mg: 15, SO4: 300, Cl: 75 },
  25
);

🧠 Knowledge Base

IBU Methods Showdown

  • Tinseth
    Formula: IBU = (AA% * Util * Weight(g) * 7489) / (Vol(gal) * (1 + GA))
    GA = (OG - 1.050)/0.2

  • Rager
    Formula: IBU = (Weight(oz) * AA% * Util * 7489) / Vol(gal)

Water Chemistry Primer

Beer Style Ca (ppm) SO4 (ppm) Cl (ppm) SO4/Cl Ratio
Czech Pilsner 50-70 30-50 20-30 1.5:1
West Coast IPA 100-150 200-400 50-100 3:1
NEIPA 100-150 50-100 150-200 1:2
Dry Stout 50-100 50-100 50-100 1:1

🚨 Troubleshooting

Units Gotchas

  • All grain weights in kilograms
  • Water volumes in liters unless specified (IBU uses gallons)
  • Alpha acids as percentage (6.5% = 6.5, not 0.065)
  • Temperature always in Celsius

Common Errors

  • RangeError: Target temp exceeds boiling → Check unit conversion (F vs C)
  • Invalid mineral: NaCl → Use standardized mineral names (CaSO4, MgCl2)
  • Negative delta for Ca → Start with softer water if reducing minerals

🤝 Contributing

See CONTRIBUTING.md for development setup and guidelines.

📜 License

MIT © AdametherzLab

About

Homebrew recipe toolkit — mash, IBU, water chemistry, style guidelines

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors