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 project, adapting its principles specifically for Lottie JSON.
1. unified: The Engine
What it is:
unifiedis a powerful engine for processing content through Abstract Syntax Trees (ASTs) using a plugin-based architecture.How relottie uses it: relottie is essentially
unifiedconfigured with specific knowledge about the Lottie format. It usesunified'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: Lottie Abstract Syntax Tree (
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/lastpackage provides these definitions.Key Features:
Based on
unist:lastextends theunistspecification, a universal standard for syntax trees. This brings compatibility with a wide range of tree traversal and manipulation utilities.Semantic
titleProperty: Unlike generic JSON ASTs,lastnodes (especiallyParentnodes) feature atitleproperty. 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 theTITLESexport from@lottiefiles/last.positionProperty: Most nodes carrypositioninformation (line, column, offset) detailing their origin in the source Lottie JSON, essential for error reporting and source mapping.hasExpressionsFlag: TheRootnode includes ahasExpressionsboolean, 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
customtitles, and more, see the detailed Guide: Working with LAST and the LAST Specification API Reference.
Example last Structure
Input Lottie JSON:
{ "v": "6.0.0" }Corresponding last Tree (simplified):
{
"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:
Parse: The input Lottie JSON string is parsed into a
lasttree using the bundled@lottiefiles/relottie-parseplugin. This plugin is built upon themomoaJSON parser and then transforms its output into the Lottie-specificlaststructure.Transform: One or more transformer plugins run sequentially. Each plugin receives the
lasttree (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-metadataor@lottiefiles/relottie-extract-features.Stringify: The final (potentially modified)
lasttree is converted back into a Lottie JSON string using the bundled@lottiefiles/relottie-stringifyplugin (also known as a compiler).
Key Processor Methods:
relottie():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.// 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 aPromisethat resolves to aVFileobject.// 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
unifiedmethods 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 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
dataproperty.Why it's used:
Passing Data: Plugins can attach data they extract or generate (like metadata from
relottie-metadataor feature lists fromrelottie-extract-features) tovfile.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)orvfile.value.
See the 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 from the unist ecosystem.
How it works:
visittraverses the tree and calls avisitorfunction for each node that matches a specifiedtype(or for all nodes if no type is given).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 currentnodein itsparent'schildrenarray.undefinedif 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 currentnode.undefinedif 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) orCONTINUE(explicitly continue, often default), orfalse(to skip children of the current node). Seeunist-util-visitdocumentation for more advanced controls.
Refer to the Modifying Lottie Files Guide for practical examples of using visit.
7. Plugins
What they are: Reusable modules (functions) that tap into the
unifiedpipeline to perform specific tasks on thelasttree. They are the workhorses of the relottie ecosystem.Types of Plugins:
Parsers: Convert input (Lottie JSON) into an AST (
last). Example:@lottiefiles/relottie-parse(bundled withrelottie).Transformers: Modify the AST. This is where you implement custom logic like updating values, removing nodes, or analyzing content. Examples:
@lottiefiles/relottie-extract-features,@lottiefiles/relottie-metadata, and any custom plugins you write.Compilers/Stringifiers: Convert the AST (
last) back into output (Lottie JSON). Example:@lottiefiles/relottie-stringify(bundled withrelottie).
Learn more: See Ecosystem: Plugins and the Creating Plugins Guide.
With these core concepts in mind, you're well-equipped to explore the specific Guides and detailed API references for individual packages.