Animora Architecture — Module Boundaries & Responsibilities
1. Package Structure Overview
Animora is organized into six top-level subpackages under the root animora namespace:
animora/
├── __init__.py # Public package exports and global theme/config convenience functions
├── core/ # Core abstraction layer: Component, Scene, Animation bridge, Registry
├── components/ # Concrete visual components (primitives, charts, data structures)
│ ├── primitives/ # Text, Shape, Arrow, Connector, Group, Panel
│ ├── dataviz/ # BarChart, LineChart, ScatterPlot, Histogram, Table
│ └── dsa/ # Array, LinkedList, Stack, Queue, Heap, Tree, Graph, HashTable
├── layout/ # Pure layout & geometric solver engine (no rendering code)
├── theme/ # Design token system, color palettes, typography, built-in themes
├── animations/ # Semantic animation primitives (traverse, highlight, swap, step)
└── cli/ # Command-line interface (new, preview, render, doctor)
2. Module Responsibility Statements
animora.core
Responsibility: Defines the foundational base classes and runtime lifecycle that connect Animora’s declarative world to Manim's rendering pipeline. It provides the base Component class (lifecycle, hierarchy, transformation, property observation, and the .manim_object escape hatch), the base Scene wrapper (camera, coordinate grid, and automatic layout anchoring), the AnimationBuilder interface, and the internal registry that manages plugin extensions and global engine configuration.
animora.components
Responsibility: Implements all user-facing domain components, providing intuitive construction, state representations, and semantic animation methods. It organizes components into three primary families: visual primitives (primitives/), data visualizations (dataviz/), and computer science data structures (dsa/). Each component translates high-level domain state into Manim vector objects while delegating spatial placement to animora.layout and visual styling to animora.theme.
animora.layout
Responsibility: Serves as a pure geometric solver engine responsible for computing spatial coordinates, bounding boxes, and alignment vectors for collections of visual elements. It contains mathematical algorithms for linear layouts (horizontal/vertical flex), grid matrices, circular arrangements, hierarchical tree layouts (e.g., Reingold-Tilford), and graph topologies (e.g., spring/force-directed, circular, planar). It contains zero rendering logic and operates strictly on geometric bounds and topological graphs.
animora.theme
Responsibility: Manages the complete design token and styling system, ensuring beautiful, accessible, and mathematically sound default aesthetics across all Animora scenes. It defines color palettes, typography tokens, stroke widths, opacity levels, and animation timing curves. It provides built-in theme definitions (e.g., ModernDark, PaperLight, Cyberpunk, Monokai) and allows users to define custom themes or modify individual tokens globally or per-component.
animora.animations
Responsibility: Implements semantic, high-level animation actions that represent domain-level transitions rather than raw geometric transforms. This includes operations such as highlighting nodes, swapping array indices, traversing tree paths, inserting/deleting elements, and step-by-step state transitions. It maps these domain intents to synchronized batches of Manim animation primitives (Transform, FadeToColor, Indicate, MoveAlongPath).
animora.cli
Responsibility: Provides the user-facing command-line tool (animora) for project scaffolding, interactive live previewing, headless batch rendering, and environment health checks. It manages project templates, integrates with local Manim installations and ffmpeg pipelines, and provides diagnostic tooling (animora doctor) to verify LaTeX, cairo/Pango, and hardware acceleration availability.
3. Dependency Hierarchy (Directed Acyclic Graph)
To maintain strict separation of concerns and prevent circular dependencies, imports between modules must strictly respect the following Directed Acyclic Graph (DAG):
graph TD
CLI["animora.cli"] --> Components["animora.components"]
CLI --> Core["animora.core"]
CLI --> Theme["animora.theme"]
Components --> Layout["animora.layout"]
Components --> Animations["animora.animations"]
Components --> Theme["animora.theme"]
Components --> Core["animora.core"]
Animations --> Core["animora.core"]
Animations --> Theme["animora.theme"]
Layout --> Core["animora.core (Geometry/Bounds protocols only)"]
Theme --> Core["animora.core (Token protocols only)"]
Core --> Manim["manim (External)"]
Layout --> NetworkX["networkx (External)"]
Core --> NumPy["numpy (External)"]
Import Rules & Invariants
animora.layoutis leaf-adjacent: It must NEVER import fromanimora.componentsoranimora.animations. It only consumes abstract bounding boxes and layout protocol interfaces fromanimora.core.animora.themeis standalone: It must NEVER import fromanimora.componentsoranimora.layout.animora.corehas no upward imports: It never imports fromcomponents,layout,theme,animations, orcli.animora.componentsis the integrator: It composescore,layout,theme, andanimationsto present the unified semantic API.
4. Extensibility Seams & Plugin Entry Points
To ensure the package architecture supports future expansion (such as domain-specific plugins like animora-physics or animora-circuits) without breaking changes, the following Python entry_points groups are reserved:
| Entry Point Group | Purpose | Target Interface |
|---|---|---|
animora.plugins |
Third-party extension packages registering custom components or features | animora.core.plugin.Plugin |
animora.themes |
Third-party theme packages contributing color palettes and style packs | animora.theme.Theme |
animora.layouts |
Custom layout algorithms (e.g. specialized physics/force solvers) | animora.layout.LayoutStrategy |
These hooks will be discovered dynamically at runtime via importlib.metadata.entry_points(group="animora.plugins") inside animora.core.registry.