Getting started with Lemma

Lemma is an open language for business rules. Teams write pricing, commercial agreements or product terms in Specs that everyone can read and systems and agents can evaluate with certainty.

If you're comfortable with spreadsheets and formulas, you'll probably write Lemma rules in no-time.

Still trying to figure out what Lemma is? We recommend reading the introduction first.
spec invoice

data quantity: 3
data unit_price: 100

rule subtotal: unit_price * quantity

rule vat: subtotal * 21%

rule total: subtotal + vat

The way policy is written

In natural language, law, policy and agreements are not written as a series of if-statements. Instead, a principle is declared, followed by exceptions for specific scenarios. This is how we generally reason about rules: the rule is always X, unless specific scenario Y applies, then it is Z. Lemma follows the same shape, which makes rules easy to read and extend.

In Lemma, the last matching exception wins. Rentals get three views in principle; if premium_member is true, that exception raises the limit to five. Playback stays denied unless the title was purchased or the rental still has views left.

spec movie_access

data type: text
  -> option "none"
  -> option "rental"
  -> option "purchase"

data viewed: number
  -> minimum 0

data premium_member: false

rule max_views: 3
  unless premium_member then 5

rule can_view: no
  unless type is "purchase" then yes
  unless type is "rental" and viewed < max_views then yes

Evaluating Lemma Specs

Specs are inert text until loaded into the Lemma engine. Once loaded, the same Spec evaluates against any Data you provide.

Evaluation is deterministic and stateless: same Spec and Data always produce the same outcomes. No database is required for the run itself.

$ lemma run movie_access type=rental viewed=1
┌───────────┬──────┐
│ max_views ┆ 3    │
├───────────┼──────┤
│ can_view  ┆ true │
└───────────┴──────┘

The same load and evaluate loop works from libraries, HTTP, and MCP.

A rich ecosystem

Lemma ships as a CLI and engine that runs on Linux, macOS, and Windows, and compiles to WASM for browsers and edge hosts.

Embed in-process from application languages, or run as a local HTTP server or MCP server when you want process isolation or agent access.

  • Operating systems

    Linux, macOS, and Windows via the Lemma CLI and native engine

  • Browser

    WASM evaluation in the page or at the edge

  • Language embeds

    JS/TS, Rust, Elixir, Java, and similar load Specs and call run in-process

  • HTTP server

    lemma server for evaluation over the network (Docker image available)

  • MCP server

    lemma mcp so assistants can check, show, and evaluate Specs safely

$ lemma server --prefix ./policies
$ lemma mcp

Every outcome explained

When you ask for an explanation, Lemma shows each Rule outcome as a tree: which conditions matched or failed, which Data fed them, and where the Rule was declared. Auditors and operators can see why a decision was made without reconstructing it from application logs.

Explanations are opt-in. Day to day evaluation stays lean; when you need the trace, it is there.

$ lemma run movie_access type=rental viewed=6 --explain
┌───────────────────────────────┐
│ max_views: 3                  │
│ └─ premium_member is false    │
├───────────────────────────────┤
│ Source: movie_access.lemma:13 │
└───────────────────────────────┘
┌──────────────────────────────────┐
│ can_view: false                  │
│ ├─ type is not purchase          │
│ │  └─ type: rental               │
│ └─ viewed >= max_views           │
│    ├─ viewed: 6                  │
│    └─ max_views: 3               │
│       └─ premium_member is false │
├──────────────────────────────────┤
│ Source: movie_access.lemma:16    │
└──────────────────────────────────┘

Rules that respect time

Every Spec can carry an effective date. You publish a new version for the future instead of rewriting history. Earlier versions remain available for the same inputs, so past decisions can still be reproduced.

Evaluation picks the version that applied at a given moment. The same rental, viewed with the same membership status, can yield a different answer in 2026 and in 2027 because the Rules themselves changed on a date.

spec movie_access 2026
"""
Playback access policy for a movie catalog,
effective from January 1st, 2026.
"""

data type: text
  -> option "none"
  -> option "rental"
  -> option "purchase"

data viewed: number
  -> minimum 0

data premium_member: false

rule max_views: 3
  unless premium_member then 5

rule can_view: no
  unless type is "purchase" then yes
  unless type is "rental" and viewed < max_views then yes
spec movie_access 2027
"""
Playback access policy for a movie catalog,
effective from January 1st, 2027.
"""

data type: text
  -> option "none"
  -> option "rental"
  -> option "purchase"

data viewed: number
  -> minimum 0

data premium_member: false

rule max_views: 2
  unless premium_member then 10

rule can_view: no
  unless type is "purchase" then yes
  unless type is "rental" and viewed < max_views then yes

Evaluating the rules as of Valentine's day 2027:

$ lemma run movie_access type=rental viewed=2 --explain --effective 2027-02-14
┌───────────────────────────────┐
│ max_views: 2                  │
│ └─ premium_member is false    │
├───────────────────────────────┤
│ Source: movie_access.lemma:40 │
└───────────────────────────────┘
┌──────────────────────────────────┐
│ can_view: false                  │
│ ├─ type is not purchase          │
│ │  └─ type: rental               │
│ └─ viewed >= max_views           │
│    ├─ viewed: 2                  │
│    └─ max_views: 2               │
│       └─ premium_member is false │
├──────────────────────────────────┤
│ Source: movie_access.lemma:43    │
└──────────────────────────────────┘

Compose rules across domains

Specs can import other Specs. Membership, access, pricing, and tax can live in separate places and still evaluate as one decision.

Teams keep each domain coherent on its own, then compose them when a product or process needs a shared outcome. The language stays portable across systems instead of locking rules inside one application.

spec membership

uses lemma units

data start: date
data length: units.calendar
  -> suggest 1 year

rule valid: now in start...start + length
spec movie_access

uses membership

data type: text
  -> option "none"
  -> option "rental"
  -> option "purchase"

data viewed: number
  -> minimum 0

rule max_views: 3
  unless membership.valid then 10

rule can_view: no
  unless type is "purchase" then yes
  unless type is "rental" and viewed < max_views then yes

Open by design

Lemma is licensed under Apache 2.0 so organizations can adopt it freely, including in commercial products, and treat it as a shared standard rather than a vendor format.

LemmaBase.com is where teams write, review, version, and publish those Rules for production.

v0.9.11

Licensed under Apache 2.0 for free use, modification, and distribution. Commercial use is permitted, including in proprietary products. The Lemma name and mark remain trademarks and may only be used to identify the official language.

Lemma.run (opens in new tab)

Bring Lemma into your organization

If your organization applies Rules through software, we can show how Lemma expresses them and how you explain the results afterward. Bring a real policy, and we will walk through Specs, evaluation, and the audit trail together.