# Core Concepts of relottie
Understand the core concepts of relottie, including unified, ASTs, the LAST specification, plugins, and the processing pipeline for Lottie animations.

# relottie Core Concepts

Understanding a few core concepts is key to effectively using the relottie ecosystem. relottie builds upon the foundation laid by the [`unified`](https://unifiedjs.com/) project, adapting its principles specifically for Lottie JSON.

## 1. `unified`: The Engine

- **What it is:** `unified` is a powerful engine for processing content through Abstract Syntax Trees (ASTs) using a plugin-based architecture.
- **How relottie uses it:** relottie is essentially `unified` configured with specific knowledge about the Lottie format. It uses `unified`'s core processing pipeline (parse -> transform -> stringify) but plugs in Lottie-specific components.

## 2. Abstract Syntax Trees (ASTs)

- **What they are:** Instead of working directly with raw Lottie JSON strings, relottie converts the JSON into a structured tree representation called an AST. This tree reflects the logical structure of the Lottie animation.
- **Why they matter:** ASTs make it much easier for programs (plugins) to reliably inspect, analyze, and modify the content of an animation. Operations are performed on the tree structure, not on potentially fragile string patterns or complex nested JSON objects.

## 3. `last`: The Lottie AST Specification

- **What it is:** **L**ottie **A**bstract **S**yntax **T**ree (`last`) is the specific AST specification relottie uses to represent Lottie JSON. It's the backbone of the entire relottie ecosystem, defining the vocabulary and structure for programmatic interaction with Lottie animations. The `@lottiefiles/last` package provides these definitions.
- **Key Features:**
  - **Based on `unist`:** `last` extends the [`unist`](https://github.com/syntax-tree/unist) specification, a universal standard for syntax trees. This brings compatibility with a wide range of tree traversal and manipulation utilities.
  - **Semantic `title` Property:** Unlike generic JSON ASTs, `last` nodes (especially `Parent` nodes) feature a `title` property. This property provides the Lottie-specific semantic meaning of a node (e.g., `version`, `layer-image`, `transform-opacity`), which is crucial for accurately targeting and understanding parts of the animation. These titles are available via the `TITLES` export from `@lottiefiles/last`.
  - **`position` Property:** Most nodes carry `position` information (line, column, offset) detailing their origin in the source Lottie JSON, essential for error reporting and source mapping.
  - **`hasExpressions` Flag:** The `Root` node includes a `hasExpressions` boolean, vital for security awareness by indicating the potential presence of executable JavaScript within the Lottie.
- **Learn more:** For a comprehensive understanding of node types, properties like `custom` titles, and more, see the detailed [Guide: Working with LAST](/docs/tools/relottie/guides/working-with-last) and the [LAST Specification API Reference](/docs/tools/relottie/guides/working-with-last).

### Example `last` Structure

**Input Lottie JSON:**

```json
{ "v": "6.0.0" }
```

**Corresponding `last` Tree (simplified):**

```json
{
  "type": "root",
  "title": "animation",
  "hasExpressions": false,
  "children": [
    {
      "type": "attribute",
      "key": "v", // The JSON key
      "title": "version", // The Lottie semantic meaning (from TITLES.string.version)
      "children": [
        {
          "type": "primitive",
          "value": "6.0.0",
          "valueType": "string"
        }
      ]
      // "position": { ... } // Position in source JSON
    }
  ]
  // "position": { ... }
}
```

_(Note: Actual `last` nodes include `position` information by default unless disabled by parser options.)_

## 4. The `relottie` Processor & Processing Pipeline

The `@lottiefiles/relottie` package is the main entry point to the relottie ecosystem. It exports the `relottie()` function, which creates a pre-configured `unified` **processor** tailored for Lottie JSON.

This processor manages the fundamental pipeline:

1. **Parse:** The input Lottie JSON string is parsed into a `last` tree using the bundled [`@lottiefiles/relottie-parse`](/docs/tools/relottie/api/relottie-parse) plugin. This plugin is built upon the `momoa` JSON parser and then transforms its output into the Lottie-specific `last` structure.
2. **Transform:** One or more **transformer plugins** run sequentially. Each plugin receives the `last` tree (potentially modified by previous plugins) and can inspect, analyze, or further modify it. This is where you apply custom logic or use utility plugins like [`@lottiefiles/relottie-metadata`](/docs/tools/relottie/api/relottie-metadata) or [`@lottiefiles/relottie-extract-features`](/docs/tools/relottie/api/relottie-extract-features).
3. **Stringify:** The final (potentially modified) `last` tree is converted back into a Lottie JSON string using the bundled [`@lottiefiles/relottie-stringify`](/docs/tools/relottie/api/relottie-stringify) plugin (also known as a compiler).

### Key Processor Methods:

- **`relottie()`**:
  ```typescript
  import { relottie } from "@lottiefiles/relottie";
  const processor = relottie(); // Creates a new processor instance
  ```
- **`.use(plugin, [options])`**: Adds a plugin to the processor's pipeline. Plugins run in the order they are added.
  ```typescript
  // processor.use(myCustomPlugin, { setting: true }).use(anotherPlugin);
  ```
- **`.process(input)`**: Asynchronously processes the input (Lottie string, Buffer, or VFile) through the full parse -> transform -> stringify pipeline. It returns a `Promise` that resolves to a `VFile` object.
  ```typescript
  // async function example() {
  //   const lottieString = '{"v":"5.5.7", ...}';
  //   const vFileResult = await processor.process(lottieString);
  //   console.log(String(vFileResult)); // Output processed Lottie JSON
  //   console.log(vFileResult.data);    // Access data attached by plugins
  // }
  ```
- Other `unified` methods like `.parse(input)` (returns AST) and `.stringify(tree)` (returns string from AST) are also available for more granular control.

## 5. VFile: Virtual File Representation

Throughout the `unified` and `relottie` ecosystem, content is often handled using [VFile](https://github.com/vfile/vfile) objects.

- **What it is:** A VFile is a virtual file representation. It's an object that can store not only the file content (e.g., Lottie JSON string) but also its path, and importantly, arbitrary metadata via its `data` property.
- **Why it's used:**
  - **Passing Data:** Plugins can attach data they extract or generate (like metadata from `relottie-metadata` or feature lists from `relottie-extract-features`) to `vfile.data`. This data then becomes available to subsequent plugins in the pipeline or to the code that initiated the processing.
  - **Messages:** Plugins can add messages (warnings, errors) to `vfile.messages`, which can be reported to the user.
  - **Context:** It provides a consistent way to pass file-related information through the processing pipeline, even if the original input was just a string.
- **Accessing Content:** The processed Lottie JSON string is typically obtained by `String(vfile)` or `vfile.value`.

See the [Usage Guide](/docs/tools/relottie/getting-started/usage-guide) for examples of plugins interacting with `VFile.data`.

## 6. Traversing the Tree with `unist-util-visit`

To inspect or modify a `last` tree within a plugin, you need to navigate it. The most common utility for this is [`unist-util-visit`](https://github.com/syntax-tree/unist-util-visit) from the `unist` ecosystem.

- **How it works:** `visit` traverses the tree and calls a `visitor` function for each node that matches a specified `type` (or for all nodes if no type is given).

  ```typescript
  import { visit, EXIT, CONTINUE } from "unist-util-visit";
  import type { Parent } from "unist"; // Or specific LAST Parent type
  import type { Attribute } from "@lottiefiles/last"; // Example node type

  // Within a plugin's transformer function:
  // return (tree: Root, file: VFile) => {
  //   visit(tree, "attribute", (node: Attribute, index?: number, parent?: Parent) => {
  //     // This function is called for every 'Attribute' node.
  //     // 'node' is the current Attribute node.
  //     // 'index' is its position in the parent's 'children' array (if applicable).
  //     // 'parent' is its direct parent node (if it has one).

  //     console.log(`Visiting attribute: ${node.key}, title: ${node.title}`);

  //     // To stop visiting further nodes:
  //     // return EXIT;

  //     // To skip visiting children of this node (but continue with siblings):
  //     // return false; // Or use a specific action from visit like SKIP

  //     // To continue visiting (default behavior if nothing is returned):
  //     // return CONTINUE; or simply return;
  //   });
  // };
  ```

- **Key Arguments for Visitor Function:**
  - `node`: The current node being visited.
  - `index` (optional): The numerical index of the current `node` in its `parent`'s `children` array. `undefined` if the node has no parent or is not in a children list (e.g., the root node when directly visited without a parent).
  - `parent` (optional): The direct parent of the current `node`. `undefined` if the node is the root of the traversal or has no parent in the tree structure being traversed.

- **Controlling Traversal:** The visitor function can return values like `EXIT` (to stop all traversal) or `CONTINUE` (explicitly continue, often default), or `false` (to skip children of the current node). See `unist-util-visit` documentation for more advanced controls.

Refer to the [Modifying Lottie Files Guide](/docs/tools/relottie/guides/modifying-lottie-files) for practical examples of using `visit`.

## 7. Plugins

- **What they are:** Reusable modules (functions) that tap into the `unified` pipeline to perform specific tasks on the `last` tree. They are the workhorses of the relottie ecosystem.
- **Types of Plugins:**
  - **Parsers:** Convert input (Lottie JSON) into an AST (`last`). Example: [`@lottiefiles/relottie-parse`](/docs/tools/relottie/api/relottie-parse) (bundled with `relottie`).
  - **Transformers:** Modify the AST. This is where you implement custom logic like updating values, removing nodes, or analyzing content. Examples: [`@lottiefiles/relottie-extract-features`](/docs/tools/relottie/api/relottie-extract-features), [`@lottiefiles/relottie-metadata`](/docs/tools/relottie/api/relottie-metadata), and any custom plugins you write.
  - **Compilers/Stringifiers:** Convert the AST (`last`) back into output (Lottie JSON). Example: [`@lottiefiles/relottie-stringify`](/docs/tools/relottie/api/relottie-stringify) (bundled with `relottie`).
- **Learn more:** See [Ecosystem: Plugins](/docs/tools/relottie/ecosystem/plugins) and the [Creating Plugins Guide](/docs/tools/relottie/guides/creating-plugins).

With these core concepts in mind, you're well-equipped to explore the specific [Guides](/docs/tools/relottie/guides) and detailed API references for individual packages.
