> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The Embedded Engine

> SQLite for commerce — a full commerce engine that runs inside your process, not behind a network call.

# The Embedded Engine

iCommerce is **the engine inside the agent**. You don't call it over a network; you compile it into
your runtime.

The analogy is SQLite. Postgres is a server you connect to. SQLite is a library you embed — and
that single difference changes latency, offline behaviour, and how you reason about failure.
iCommerce is that, for commerce.

## What "embedded" buys you

| Property         | API-first (Stripe, Shopify)    | iCommerce                  |
| ---------------- | ------------------------------ | -------------------------- |
| Where it runs    | Their servers                  | **Your process**           |
| Latency per call | Network round-trip             | In-memory                  |
| Works offline    | No                             | **Yes**                    |
| Type safety      | Whatever your client generates | Native, across 11 bindings |
| Failure mode     | Their outage is your outage    | Local                      |

For an agent doing dozens of reads to decide one action, in-process calls are the difference
between a coherent turn and a timeout.

## Start

```js theme={null}
import { Commerce } from '@stateset/embedded';

const commerce = new Commerce('./store.db');   // or ':memory:'
```

That's the whole setup — no server to run, no connection string, no control plane.

```rust theme={null}
use stateset_sdk::prelude::*;
use rust_decimal_macros::dec;

let commerce = Commerce::new("./store.db")?;
```

## A complete flow

```js theme={null}
const cart = await commerce.carts.create({
  customerEmail: 'alice@example.com',
  customerName: 'Alice Smith',
});

await commerce.carts.addItem(cart.id, {
  sku: 'SKU-001',
  name: 'Widget',
  quantity: 2,
  unitPrice: 29.99,
});

const result = await commerce.carts.complete(cart.id);
console.log(`Order created: ${result.orderNumber}`);
```

Same thing in Rust, with exact decimals:

```rust theme={null}
let customer = commerce.customers().create(CreateCustomer {
    email: "alice@example.com".into(),
    first_name: "Alice".into(),
    last_name: "Smith".into(),
    ..Default::default()
})?;

let order = commerce.orders().create(CreateOrder {
    customer_id: customer.id,
    items: vec![CreateOrderItem {
        sku: "SKU-001".into(),
        quantity: 2,
        unit_price: dec!(29.99),
        ..Default::default()
    }],
    ..Default::default()
})?;

commerce.orders().ship(order.id, Some("FEDEX123456".into()))?;
```

## Storage

| Backend     | Use for                        |
| ----------- | ------------------------------ |
| `:memory:`  | Tests, ephemeral agents        |
| SQLite file | Local-first, edge, single-node |
| PostgreSQL  | Shared state across replicas   |

The API is identical across all three, so you can develop against `:memory:` and deploy against
Postgres without changing call sites.

<Note>
  Two domains historically reported `isSupported() == true` on SQLite while every call failed — that
  gap is closed, but it's worth calling `isSupported()` rather than assuming parity when you're
  relying on a less common domain.
</Note>

## Determinism and explicit write intent

Operations are deterministic, and writes require explicit intent rather than being inferred. That's
what makes an agent holding the engine safe to reason about: a read cannot mutate, and a mutation
is a decision someone made. See the
[CLI safety model](/stateset-icommerce/stateset-icommerce-cli-safety) for the same principle at the
command line.

## Money is never a float

```js theme={null}
const order = await commerce.orders.get(id);
order.totalAmount;   // "149.99"  ← string, exact
```

Every monetary value crosses as an exact decimal string. `0.1 + 0.2 !== 0.3` in binary floating
point, and a commerce engine that sells exact settlement cannot afford that drift.

<Warning>
  Some **older binding fields** still convert to `f64` — roughly 50 fields on the Node and Python
  surfaces, including `PaymentOutput.amount` and `OrderResponse.total_amount`. See the
  [money precision note](/stateset-icommerce/stateset-icommerce-bindings#money-precision) for which
  to avoid until that lands.
</Warning>

## When to embed

| Situation               | Why embedding fits                                 |
| ----------------------- | -------------------------------------------------- |
| **Agent workflows**     | Dozens of local reads per decision, no round-trips |
| **Edge deployments**    | Works with no connectivity to a central service    |
| **High throughput**     | In-process calls, minimal overhead                 |
| **Deterministic tests** | `:memory:` gives a real engine with no fixtures    |

## Related

* [Quickstart](/stateset-icommerce/stateset-icommerce-quickstart)
* [Architecture](/icommerce-architecture)
* [Bindings](/stateset-icommerce/stateset-icommerce-bindings) — 11 languages, and their caveats
* [MCP Server](/stateset-icommerce/stateset-icommerce-mcp) — 719 tools over this engine
