# Arrange nodes

::alert
This guide is based on the [Basic](https://retejs.org/docs/guides/basic) guide. It is recommended to review it for a comprehensive understanding of this guide.
::

::references
  :::ref-example{link="/examples/arrange" title="Arrange"}
  :::

  :::ref-guide{link="/docs/guides/scopes" title="Scopes"}
  :::

  :::ref-github
  ---
  link: https://github.com/retejs/auto-arrange-plugin
  title: Arrange plugin
  ---
  :::

  :::ref-external{link="https://github.com/kieler/elkjs" title="Elk.js"}
  :::
::

::diagram{caption="Architecture" name="guides/arrange/index"}
::

## Install dependencies

::kit
::

Prior to using this plugin, `elkjs` peer dependency must be installed separately.

```bash
npm i rete-auto-arrange-plugin elkjs
```

Additionally, it may be necessary to install `web-worker` if your bundler doesn't recognize this dependency by default

```bash
npm i web-worker
```

## Create the node base

The node's width and height need to be specified as `elkjs` requires these values, especially if the node sizes vary.

```ts
class Node extends ClassicPreset.Node {
  width = 180;
  height = 120;
}

class Connection<N extends Node> extends ClassicPreset.Connection<N, N> {}

type Schemes = GetSchemes<Node, Connection<Node>>;
```

## Plugin connection

```ts
import { AutoArrangePlugin, Presets as ArrangePresets } from "rete-auto-arrange-plugin";

const arrange = new AutoArrangePlugin<Schemes>();

arrange.addPreset(ArrangePresets.classic.setup());

area.use(arrange);
```

## Arrange added nodes

```ts
await arrange.layout();
```

## Arrange nested nodes

Any node that has the `parent` property will be considered as a nested node within its corresponding parent node, as indicated by the id specified in this field. There are no additional settings required. The [Scopes](https://retejs.org/docs/guides/scopes) guide includes an example of how to use it in practice.

## Animated arrange

If you prefer a seamless transition of nodes position, you can apply an animated `TransitionApplier` with configurable animation duration and timing function

```ts
import { ArrangeAppliers } from "rete-auto-arrange-plugin";

const applier = new ArrangeAppliers.TransitionApplier<Schemes, AreaExtra>({
  duration: 500,
  timingFunction: (t) => t,
  async onTick() {
    // called on every frame update
  }
});

await arrange.layout({ applier })
```

## Arrange options

Additionally, you can make use of [global options for elk.js](https://eclipse.dev/elk/reference/options.html){rel="nofollow"}. For instance, this empowers you to alter the spacing between nodes

```ts
await arrange.layout({
  options: {
    'elk.spacing.nodeNode': 100,
    'elk.layered.spacing.nodeNodeBetweenLayers': 100
  }
});
```

Check out the complete result on the [Arrange](https://retejs.org/examples/arrange) example page.