---
url: https://jer-k.github.io/effect-prophet/guide/getting-started.md
description: Install effect-prophet, fit a model to your history and forecast future dates.
---

# Getting started

## Install

```sh
npm install effect-prophet effect
```

Effect Prophet needs **Node.js 22.19 or newer** and is an ES module, so use `import`, not
`require`. It also runs in browsers; see [Browsers and bundlers](./browsers).

## Your first forecast

Copy this into a file called `forecast.ts`:

```ts
import { Effect } from "effect";
import { fit, makeFutureTimestamps, predict, prophetFittingBackendLayer } from "effect-prophet";

// 1. Your history: one row per day, each with a timestamp and a value.
const history = Array.from({ length: 90 }, (_, day) => ({
  timestamp: new Date(Date.UTC(2025, 0, 1 + day)).toISOString(),
  value: 100 + day * 0.5 + 10 * Math.sin((2 * Math.PI * day) / 7),
}));

// 2. Describe the work: fit a model to the history, list the next seven days, then predict.
const program = Effect.gen(function* () {
  const model = yield* fit(history);
  const nextWeek = yield* makeFutureTimestamps(history, { periods: 7, includeHistory: false });

  return yield* predict(model, nextWeek);
});

// 3. Run it. The layer plugs in the forecasting engine.
const forecast = await Effect.runPromise(program.pipe(Effect.provide(prophetFittingBackendLayer)));

for (const row of forecast) {
  console.log(new Date(row.timestamp).toISOString().slice(0, 10), row.value.toFixed(1));
}

```

Run it:

```sh
node forecast.ts
```

You should see a forecast for each of the next seven days:

```txt
2025-04-01 137.2
2025-04-02 145.5
2025-04-03 153.8
2025-04-04 156.2
2025-04-05 151.3
2025-04-06 143.2
2025-04-07 138.3
```

The numbers rise and fall through the week because the model found the weekly pattern in the
history on its own.

## What just happened?

1. **History.** Each row has a `timestamp` and a `value`. Timestamps are UTC strings in the exact
   format that `Date.prototype.toISOString()` produces.
2. **Fit, then predict.** `fit` learns the trend and patterns from your history.
   `makeFutureTimestamps` lists the seven days after the history's last timestamp, and `predict`
   uses the fitted model to forecast them. You can also pass `predict` any dates you choose, in
   the future or the past.
3. **Run.** Steps 1 and 2 only *describe* the work. `Effect.runPromise` runs it and gives you a
   normal `Promise`. `prophetFittingBackendLayer` supplies the forecasting engine that `fit` needs.

If steps 2 and 3 feel unfamiliar, read [Effect in five minutes](./effect-basics). It is short.

## Fit and predict in one call

When you only need the forecast, `forecast` fits and predicts in one call:

```ts
import { Effect } from "effect";
import { forecast, prophetFittingBackendLayer } from "effect-prophet";

const history = Array.from({ length: 90 }, (_, day) => ({
  timestamp: new Date(Date.UTC(2025, 0, 1 + day)).toISOString(),
  value: 100 + day * 0.5 + 10 * Math.sin((2 * Math.PI * day) / 7),
}));

const nextWeek = Array.from({ length: 7 }, (_, offset) =>
  new Date(Date.UTC(2025, 0, 91 + offset)).toISOString(),
);

// Fit the history and forecast next week in one call.
const rows = await Effect.runPromise(
  forecast(history, nextWeek).pipe(Effect.provide(prophetFittingBackendLayer)),
);

for (const row of rows) {
  console.log(new Date(row.timestamp).toISOString().slice(0, 10), row.value.toFixed(1));
}

```

```txt [Output]
2025-04-01 137.2
2025-04-02 145.5
2025-04-03 153.8
2025-04-04 156.2
2025-04-05 151.3
2025-04-06 143.2
2025-04-07 138.3
```

The result is exactly what `fit` and then `predict` return, in the order of your dates. Model
options go in an optional third argument, exactly as `fit` takes them:

```ts
forecast(history, nextWeek, { growth: "flat" });
```

`forecast` returns only the forecast, not the model. To forecast again from the same model, or to
[save it](../examples/saving-models), call `fit` and `predict` yourself. Like `predict`, it doesn't
guess anything about the future: you list the dates, and any capacities, floors, regressors or
conditions the model needs go on each row, as in
[this regressor example](../examples/regressors#in-one-call).

## Next steps

* [Prepare your own data](./your-data)
* [Understand what's in a forecast](./reading-forecasts)
* [Trace your forecasts](./tracing) in Jaeger or any OpenTelemetry backend
* Browse the [examples](../examples/trend)
