- PowerShell 55.5%
- C# 19.6%
- HTML 12.5%
- TypeScript 8.4%
- CSS 3.7%
- Other 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| assets/images | ||
| ci | ||
| dev/jellyfin | ||
| docs | ||
| forgejo | ||
| frontend | ||
| moonfin | ||
| repository | ||
| scripts | ||
| src/Jellyfin.Plugin.LibraryTree | ||
| tests/Jellyfin.Plugin.LibraryTree.Tests | ||
| .gitignore | ||
| AGENTS.md | ||
| AGENTS.override.md | ||
| LibraryTree.sln | ||
| LICENSE | ||
| NuGet.Config | ||
| package-lock.json | ||
| README.md | ||
Library Tree
A visual hierarchy and custom ordering layer for Jellyfin libraries.
Library Tree is a Jellyfin plugin that allows existing libraries to be arranged in a tree-like structure without changing Jellyfin's native library model.
Libraries remain normal, independent Jellyfin libraries. Library Tree only controls how they are organized and presented to supported clients.
🌳 The idea
Jellyfin normally presents libraries as a flat list:
Movies
International Movies
Swiss Movies
Anime Movies
TV Shows
International TV Shows
Library Tree adds a visual hierarchy:
Movies
├── International Movies
├── Swiss Movies
└── Anime Movies
TV Shows
└── International TV Shows
A parent library may still contain its own media.
Child libraries remain completely independent Jellyfin libraries.
✨ Features
Library Tree is designed to provide:
- Visual parent/child relationships between Jellyfin libraries
- Custom library ordering
- Multi-level library hierarchies
- Ordering of both root and child libraries
- Modular frontend integrations
- Independently configurable frontend adapters
- Safe fallback to Jellyfin's normal flat library view
The plugin does not replace Jellyfin's library system.
🧩 How it works
The hierarchy model is intentionally simple:
LibraryId
ParentId
SortOrder
LibraryId
The ID of an existing Jellyfin library.
ParentId
The optional ID of another Jellyfin library.
If no parent is assigned, the library appears on the root level.
SortOrder
Controls the order of libraries that share the same parent.
This allows arbitrary hierarchy depth without modifying the actual Jellyfin libraries.
🔌 Frontend adapters
Library Tree separates its hierarchy logic from individual clients.
Each supported frontend uses its own adapter while sharing the same server-side hierarchy.
| Client | Status |
|---|---|
| Jellyfin Web | 🚧 First adapter |
| Moonfin | 📋 Planned |
| Additional clients | 💡 Possible later |
Adapters are designed to be modular and may be enabled or disabled independently.
The core itself remains client-independent.
🎛️ Presentation tweaks and artwork
The Library Tree administration page keeps client presentation optional and separate from the stored hierarchy. Jellyfin Web and Moonfin can each be enabled or disabled independently; disabling an adapter or a tweak never changes Jellyfin libraries, permissions, ParentId values or SortOrder values.
Library Image Fix and visibility
The optional Library Image Fix applies only to Jellyfin Web library cards. It prefers a library Thumb image in the normal library presentation while leaving media items and Moonfin untouched. In Jellyfin administration it keeps an approximately 16:9 Primary image; if that ratio cannot be determined, the normal Jellyfin image is retained.
Library Visibility is independently configurable for Jellyfin Web and Moonfin on a per-library basis. It only hides a library already made available by Jellyfin to the signed-in user. Hiding a parent does not promote its children to the root level; reenabling visibility restores the saved hierarchy position.
Custom Library Artwork
Administrators may store Library Tree-owned artwork per Jellyfin user + library + slot. It never overwrites Jellyfin artwork or metadata. Supported slots are Backdrop (16:9), Poster (2:3), Square (1:1), Banner (3:1), Spine (1:3) and Logo (transparent, variable ratio). Each slot can be uploaded, replaced or removed independently in the administration page.
When a user has no custom image, an image fails to load or its API request fails, the client keeps its normal Jellyfin/Moonfin artwork and presentation. Other users' artwork settings are never exposed through the normal authenticated artwork endpoint.
Library Header Artwork
Jellyfin Web and Moonfin have separate optional header switches and modes: Standard, Banner Strip, Logo Top Right and Logo Centered. Banner Strip uses the current user's Banner slot; both logo modes use the Logo slot. The normal library content and navigation remain in place. Missing or unreadable custom artwork results in the unmodified standard header.
The Moonfin integration is supplied as a reproducible patch. Flutter/Dart is not available in this development environment, so native Moonfin runtime validation remains an explicit manual follow-up.
🛡️ Non-destructive by design
Library Tree does not:
- Move media files
- Change library paths
- Change Jellyfin metadata
- Modify Jellyfin's native library relationships
- Create real nested Jellyfin libraries
- Change Jellyfin's scanning behavior
If Library Tree is disabled or removed, Jellyfin simply returns to its normal flat library presentation.
No migration back is required.
🏗️ Architecture
Library Tree
│
Hierarchy Core
│
LibraryId / ParentId / Order
│
┌──────────┴──────────┐
│ │
Jellyfin Web Moonfin
Adapter Adapter
│ │
└──── future adapters ┘
Frontend-specific behavior stays outside of the hierarchy core.
This makes it possible to support additional Jellyfin clients without redesigning the underlying data model.
🚧 Project status
Library Tree is currently in early development.
Development is intentionally incremental.
The first goal is a minimal, loadable Jellyfin plugin. Hierarchy storage, configuration, frontend integration and additional client adapters are added step by step.
Library Tree is not yet intended for production use.
🤖 AI-assisted development & transparency
Library Tree is developed with the assistance of OpenAI Codex.
All implementation code in this project is written through Codex under direct human guidance.
This is not an autonomous or one-shot code generation process.
The human maintainer is responsible for:
- defining the project concept and requirements
- making architecture and design decisions
- defining implementation constraints and development phases
- reviewing generated changes
- building and testing the plugin
- verifying behavior against the intended design
- identifying bugs and regressions
- directing corrections and refinements
- deciding which changes are accepted into the repository
Codex is used as the implementation tool, while development direction, verification and final responsibility remain human-controlled.
Development is performed incrementally:
Concept / problem
↓
Architecture and requirements
↓
Define a limited implementation phase
↓
Codex implementation
↓
Review, build and testing
↓
Corrections if required
↓
Commit
↓
Next phase
This disclosure is included intentionally so users and contributors can clearly understand how the project is developed.
💜 Why Library Tree?
Large Jellyfin installations can quickly accumulate many libraries.
Library Tree aims to make those libraries easier to organize without changing the way Jellyfin itself manages media.
The project is deliberately designed as a presentation and organization layer, not as a replacement library system.
🖼️ Branding
The Library Tree logo represents media libraries arranged as branches of a shared hierarchy.
Additional project artwork is available under:
assets/images/
🧪 Development, CI & runtime testing
Library Tree currently targets the .NET 9 SDK and uses Corepack/pnpm for the Jellyfin Web adapter. The complete local verification is:
./ci/scripts/Invoke-ProjectChecks.ps1
./ci/scripts/Build-Release.ps1 -Version 0.1.0.1 -AssetVersion 0.1.0-beta1
additionally creates a verified plugin ZIP, Jellyfin repository manifest and
MD5/SHA-256 checksum data under the ignored artifacts/ directory. Jellyfin
uses four-part versions; Build values above zero are beta counters. The ZIP
contains only runtime files: the plugin DLL, its Jellyfin assembly whitelist
and the browser adapter. SQLite is supplied by the compatible Jellyfin server.
Forgejo Actions runs the same verification on pushes and pull requests, and
creates the package artifact for version tags or a manual release run. A
dedicated, Docker-isolated Forgejo Runner with the library-tree-ci label is
required; it is intentionally not installed or configured by this repository.
Detailed instructions are available in:
Real Jellyfin installation, updates, removal and server restarts are always manual administrator actions. The first runtime test remains pending until a maintainer installs a generated ZIP and supplies the resulting evidence.
📄 License
Library Tree is licensed under the MIT License.
See LICENSE for details.
