Kumi

CI Gem Version License: MIT

Try the interactive demo →


What is Kumi?

Kumi is a declarative DSL for calculation logic — tax rules, pricing, scoring, financial projections — that compiles to plain Ruby and JavaScript.

You declare the shape of your input data and the values you want computed. The compiler determines evaluation order, checks types, detects impossible conditions, and emits dependency-free code for each target.

schema do
  input do
    array :items do
      hash :item do
        integer :quantity
        decimal :unit_price
      end
    end
  end

  value :line_totals, input.items.item.quantity * input.items.item.unit_price
  value :subtotal, fn(:sum, line_totals)
end

No loops, no iteration plumbing: line_totals is computed per item because that's where the data lives, and fn(:sum, ...) collapses it back to a scalar. This works through arbitrarily nested arrays.

Why

  • One source of truth, two targets. The same schema compiles to Ruby and JavaScript with identical semantics — write pricing logic once, run it in your backend and in the browser preview.
  • Broadcasting from data shape. Operations align over arrays automatically based on the declared input structure, including nested and ragged data.
  • Static checks at compile time. Type checking, dependency cycle detection, and unsatisfiable-constraint detection happen when the schema is defined, not in production.
  • Boring generated code. Output is deterministic, dependency-free, straight-line code with explicit loops. What you read is what runs.

Use Cases

Tax engines, pricing models, financial projections, compliance rules, insurance underwriting, shipping rate calculators — anywhere calculation logic must be correct, auditable, and consistent across platforms.


Status: experimental. Public API may change. Typing and some static checks are still evolving.

Feedback: have a use case or hit a rough edge? Open an issue or reach out (andremuta+kumi@gmail.com).


Install

gem install kumi

Requires Ruby 3.1+. Runtime dependencies: mutex_m and zeitwerk (bundled via Rubygems).

Quick Start

require 'kumi'

module Double
  extend Kumi::Schema

  schema do
    input { integer :x }
    value :doubled, input.x * 2
  end
end

# Execute in Ruby
result = Double.from(x: 5)
result[:doubled]  # => 10

# or just call the method directly
Double._doubled(x: 5) # => 10

# Export to JavaScript (same logic)
Double.write_source("output.mjs", platform: :javascript)
# ./output.mjs
# export function _doubled(input) {
#   let t1 = input["x"];
#   let t3 = t1 * 2;
#   return t3;
# }

You can also override the compilation strategy without touching code by setting KUMI_COMPILATION_MODE to jit or aot (e.g. export KUMI_COMPILATION_MODE=aot).

Examples

  • US Tax Calculator (2024) — a single schema computes federal, state, and FICA taxes across multiple filing statuses. Open in the demo.
  • Monte Carlo Portfolio — probabilistic simulations and table visualizations. Open in the demo.
  • Conway's Game of Life — array operations powering a grid-based simulation. Open in the demo.

Documentation


License

MIT License. See LICENSE.