# Quick start

> From an empty file to a decision your code can act on, in five steps.

Section: Getting started · HTML: https://jevascript.org/docs/quick-start · Markdown: https://jevascript.org/docs/quick-start.md

This page builds a support-ticket triage for Northwind, a fictional B2B payments API. By the end, a ticket goes in and plain TypeScript decides who gets paged.

### 1. Install and set the key

```bash
npm i jevascript
pnpm add jevascript
yarn add jevascript
bun add jevascript
```

```bash
# .env
JEV_API_KEY=apikey_...
```

With the key in the environment, nothing else needs configuring. See [Installation](https://jevascript.org/docs/installation) for package managers and how to load `.env`.

### 2. Ask a yes/no question

`is()` takes a proposition and returns a boolean. Write the proposition as a claim about the text, not as a question or a label.

```ts
// triage.ts
import { semantic } from "jevascript"

const ticket = {
  plan: "enterprise",
  subject: "All card payments failing since 14:02",
  body: "Every charge returns gateway_timeout since 14:02.",
}

const blocked = await semantic(ticket).is(
  "The customer cannot take money from their own customers right now.",
)
// true
```

The state can be a string, an array of strings, or any object. Objects are serialised as JSON, so field names carry meaning too.

### 3. Ask for a number

`score()` returns a number on a range, `0` to `100` by default. Under the hood it is a probability mapped onto your range, so the same rules about propositions apply.

```ts
// triage.ts
const urgency = await semantic(ticket).score(
  "A human needs to act on this ticket urgently.",
)
// 91
```

The threshold lives in your code, where it can be reviewed and tested:

```ts
if (urgency > 80) pageOnCall()
```

### 4. Pick one of a fixed set

`choose()` returns one of the options you pass. The return type is the literal union, with no `as const` needed.

```ts
// triage.ts
const team = await semantic(ticket).choose(["billing", "integration", "payments", "security"])
//    ^? "billing" | "integration" | "payments" | "security"
```

Describing each option instead of naming it improves accuracy noticeably:

```ts
const team = await semantic(ticket).choose({
  integration: "SDK usage, API errors, webhooks, authentication",
  payments: "Declines, settlement, payouts, chargebacks",
  billing: "Our own invoices, pricing, plan changes",
  security: "Credential exposure, suspicious access, vulnerability reports",
})
```

### 5. Ask everything at once

Three separate `await`s are three requests. `batch()` sends them together, and the state travels once:

```ts
// triage.ts
import { semantic, is, score, choose } from "jevascript"

const t = await semantic(ticket).batch({
  urgency: score("A human needs to act on this ticket urgently."),
  frustration: score("The person writing this sounds frustrated or angry."),
  blocked: is("The customer cannot take money from their own customers right now."),
  team: choose({
    integration: "SDK usage, API errors, webhooks, authentication",
    payments: "Declines, settlement, payouts, chargebacks",
    billing: "Our own invoices, pricing, plan changes",
    security: "Credential exposure, suspicious access, vulnerability reports",
  }),
})

// One request. Then the consequences are ordinary code.
const priority =
  t.blocked && ticket.plan !== "free" ? "critical"
  : t.urgency >= 80 || t.frustration >= 90 ? "high"
  : "normal"

if (priority === "critical") pageOnCall()
route(t.team)
```

Notice that the plan check is deterministic. The model judges meaning; facts you already have stay in code.

## Put it in one file

In an application, create the instance once and import it everywhere, the same way you would a database client. Naming the export `semantic` keeps every call site identical to the examples above.

```ts
// lib/semantic.ts
import { createSemantic, jev } from "jevascript"

export const semantic = createSemantic({
  provider: jev(),
  defaults: { timeoutMs: 5_000, cache: "10m" },
})
```

```ts
// anywhere.ts
import { semantic } from "./lib/semantic"

const t = await semantic(ticket).batch({ /* ... */ })
```

`createSemantic` returns a private instance with its own provider, cache and hooks. It never touches the module-level `semantic`, so a test can swap the provider without affecting anything else. See [Configuration](https://jevascript.org/docs/configuration).

## Where next

- [Primitives](https://jevascript.org/docs/primitives): Every option on `is`, `score` and `choose`, and how to write criteria that work.
- [Definitions](https://jevascript.org/docs/definitions): Declare a schema once and apply it to every ticket.
- [Uncertainty](https://jevascript.org/docs/uncertainty): Bands, measured confidence and fallbacks.
- [Testing](https://jevascript.org/docs/testing): Swap the provider for a mock and assert on the decisions.
