Skip to content

Repository files navigation

Open Pricing Engine

CI npm version npm downloads License: MIT TypeScript

A configurable, framework-agnostic pricing engine for any business domain.

Define your pricing rules in a simple JSON config — the engine does the math.

Why

Every business has pricing logic. Most teams build it from scratch, tightly coupled to their application. This engine extracts that logic into a reusable, testable, configurable module.

Born from real-world experience building ERP pricing systems — area-based calculations, tiered rates, minimum charges, discounts. Abstracted to work across any domain: manufacturing, logistics, SaaS, e-commerce.

The npm ecosystem has plenty of billing and payment platforms (subscriptions, invoicing, tax), but few dedicated, standalone pricing engines — especially ones that handle physical dimensions like area, length, volume or weight. This library focuses purely on the pricing calculation: typed, validated, framework-agnostic, with no dependency on any payment provider.

Features

  • Config-driven — define pricing rules in JSON, no hardcoding
  • Multiple pricing strategies — area, linear, volume, weight, time, piece and flat
  • Discounts & surcharges — percentage and fixed adjustments, applied as a cascade
  • Minimum charge — guaranteed price floor per item
  • Per-strategy validation — each strategy's required dimensions are checked with descriptive errors
  • Framework-agnostic — pure TypeScript, runs anywhere
  • Minimal dependencies — only Zod for validation
  • 100% test coverage — tested with Vitest
  • TypeScript-first — full type safety, great DX

Quick Start

npm install open-pricing-engine
import { PricingEngine } from 'open-pricing-engine';

const engine = new PricingEngine({
  rules: [
    {
      name: 'flat-surface',
      type: 'area',
      unitPrice: 12.5,
      unit: 'm2',
      minCharge: 25.0,
    },
  ],
});

const result = engine.calculate({
  rule: 'flat-surface',
  dimensions: { width: 2.0, height: 1.5 },
  quantity: 10,
});

// Result:
// {
//   rule: 'flat-surface',
//   measure: 3.0,
//   unitPrice: 12.50,
//   subtotal: 37.50,        // 3.0 × 12.50
//   adjustments: [],        // no adjustments configured
//   adjusted: 37.50,        // subtotal after adjustments
//   quantity: 10,
//   total: 375.00           // 37.50 × 10
// }

Strategies

The calculation type is chosen per rule via the type field. Each strategy turns the input dimensions into a billable measure, then subtotal = measure × unitPrice.

type Required dimensions measure Example unit
area width, height width × height
linear length length m
volume width, height, depth width × height × depth
weight weight weight kg
time hours hours h
piece 1 (per-unit item) pc
flat 1 (fixed service fee) job
const engine = new PricingEngine({
  rules: [
    { name: 'cable', type: 'linear', unitPrice: 3, unit: 'm' },
    { name: 'tank', type: 'volume', unitPrice: 8, unit: 'm3' },
    { name: 'setup', type: 'flat', unitPrice: 50, unit: 'job' },
  ],
});

engine.calculate({ rule: 'cable', dimensions: { length: 4 }, quantity: 1 }).measure; // 4
engine.calculate({ rule: 'tank', dimensions: { width: 2, height: 2, depth: 2 }, quantity: 1 })
  .measure; // 8
engine.calculate({ rule: 'setup', dimensions: {}, quantity: 1 }).measure; // 1

Missing required dimensions throw a descriptive validation error (for example, a volume rule without depth).

Use Cases

The engine works for any business where price depends on item dimensions:

  • Metal coating & powder painting (price per m²)
  • CNC machining, laser cutting (price per area)
  • Glass, flooring, fabric (price per m² with minimum charge)

Future versions will support tiered pricing, discounts, and custom formulas — see Roadmap.

Roadmap

Version Scope Status
v0.1 Area-based pricing, JSON config, minimum charge Released
v0.2 Discounts & surcharges (%, absolute) Released
v0.3 Calculation strategies (area, linear, volume, weight, etc.) Released
v0.4 Price list versioning, effective dates Planned
v0.5 Tiered pricing (volume & graduated) Planned
v0.6 REST API wrapper (Fastify) Planned
v0.7 Interactive playground (React) Planned
v1.0 Plugin system for custom formulas Planned

Project Structure

open-pricing-engine/
├── packages/
│   ├── core/          — pricing logic (npm package)
│   ├── api/           — REST API wrapper (planned)
│   └── playground/    — interactive demo (planned)
├── docs/              — architecture decisions
└── .github/workflows/ — CI/CD

Development

# Prerequisites: Node.js 22+, pnpm 10+

pnpm install        # Install dependencies
pnpm test           # Run tests
pnpm typecheck      # Type-check
pnpm build          # Build
pnpm format         # Format code

Contributing

Contributions are welcome! Please open an issue first to discuss what you'd like to change.

  1. Fork the repository
  2. Create your branch (git checkout -b feat/my-feature)
  3. Commit using conventional commits
  4. Open a Pull Request

License

MIT

About

A configurable, framework-agnostic pricing engine for any business domain

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages