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

# How a script runs

> The rules every script follows, what runs when, and what the compiler refuses.

Know what may go where in a script and the order its handlers run in. The editor enforces these rules as you type, each with a [diagnostic code](/terminal/reference/diagnostics).

## The shape of a script

A script is one TypeScript file with no imports. Its globals are the [API](/terminal/reference).

The top level runs once, when the script loads (setup). It may contain only:

* `indicator(name, options)`, first;
* `const` declarations whose values come from the API's constructors (`input.*`, `bars()`, `trades()` and the other streams, `state.*`, `series`, `tally`, `tallyBy`, `ta.*`, `plot.*`, `alert`, `draw.table`), from literals, or from other constants and helper functions;
* `plot.level(...)` calls;
* function declarations: pure helpers, or factories called at setup;
* handler registrations: `stream.onBar(fn)`, `stream.onClose(fn)`, `trades.onTrade(fn)`, `liquidations.onLiquidation(fn)`.

Handlers hold the logic and run per bar or per event. A local variable in a handler starts fresh on every run. Anything that persists is declared [state](/terminal/guides/state).

## What the compiler enforces

* Constructors only at the top level; handlers registered only at the top level, unconditionally.
* Each state object, series and indicator belongs to the one stream whose handler updates it.
* Event handlers (`onTrade`, `onLiquidation`) may change only tallies and live state.
* Tallies are filled only by event handlers.
* Plots, markers and drawings are set only in the chart's own `bars()` handlers.
* No `import` or `export`, `eval`, `with`, `async`, generators, classes, top-level `let` or `var`, top-level collections that change, dynamic indexing of API objects, `Date`, timers, `fetch` or other globals.
* `Math` is the engine's own: `exp`, `log`, `pow`, the trigonometric functions and the rest give the same bits in every browser, which can differ in the last bit from a browser console. There is no `Math.random`: use `random(seed)`.

## The order things run in

For chart bar `i`, in history:

1. Everything that happened before the bar closed, merged by time: trades and liquidations with a time before its close, and other bar streams' bars that close at or before it (their `onBar` with `confirmed` true, `onClose`, then their commit). At equal times a bar close comes first, and a longer interval before a shorter one.
2. The chart's `onBar`, with `confirmed` true, then its `onClose`.
3. The commit. Tallies empty for the next bar.

Live, the forming bar runs again from the last commit on every update, with `confirmed` false. Only the latest update matters, so updates can be skipped without changing the result.

<Note>
  Another stream read from a handler gives its last closed value, "as of" that moment: there is no lookahead. `.forming` on a stream reads its developing bar live, which repaints; on history it is the last closed bar. See [data and timeframes](/terminal/guides/data).
</Note>

An indicator advances only when `update` runs, so update it on every bar. Missing numbers are `na`: arithmetic with `na` is `na`, and comparisons with it are false. See [missing values](/terminal/guides/missing-values).

## When a script runs again

The script runs again from setup, over the whole history, when older history is loaded, the market or interval changes, or an input changes. That takes a few tens of milliseconds per 100,000 bars for a typical script. Values near the oldest loaded bar may change, as on TradingView.

## Next step

Keep values between bars with [state](/terminal/guides/state).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.