Skip to content

Building from Source

RadicalMuffinMan edited this page Jul 15, 2026 · 1 revision

Building from Source

This repo is a monorepo with two independent plugins:

  • Jellyfin/ the Jellyfin plugin (.NET 8)
  • Emby/ the Emby plugin (.NET Standard 2.1)

Both share the manifest.json, README.md, and LICENSE at the repo root (even though Emby doesn't use the manifest.json).

Prerequisites

  • Jellyfin plugin: the .NET 8 SDK. The build scripts also use zip, jq, and an MD5 tool (md5sum, md5, or certutil).
  • Emby plugin: a .NET SDK that can target netstandard2.1.
  • Frontend: Flutter with web support, only if you want to rebuild the web app. The Flutter app lives in the separate Moonfin-Core repo, not here.

The plugins reference their host packages (Jellyfin 10.10.0, Emby 4.9.1.90) at compile time only, so you do not need a running server to build.

Project structure

Plugin/
├── manifest.json              shared Jellyfin plugin repository manifest
├── README.md, LICENSE
├── Jellyfin/                  .NET 8 Jellyfin plugin
│   ├── build.sh, build.ps1
│   ├── backend/
│   │   ├── Moonfin.Server.csproj
│   │   ├── Api/               controllers
│   │   ├── Services/          settings, games, caches, sync tasks
│   │   ├── Models/
│   │   ├── Helpers/           File Transformation patches
│   │   ├── Pages/             admin config page
│   │   ├── Web/               loader.js and inject.html
│   │   ├── EmulatorJS/        in-browser player shell
│   │   └── assets/
│   ├── frontend/              built Flutter web bundle, synced in
│   └── tools/verify-plugin/   build-time DLL verifier
└── Emby/                      netstandard2.1 Emby plugin
    ├── build.sh, build.ps1
    ├── Emby.Plugins.Moonfin/
    │   ├── Emby.Plugins.Moonfin.csproj
    │   ├── Api/               services, requests, and game logic
    │   ├── Services/
    │   ├── Models/
    │   ├── Pages/             config page and moonfin.js
    │   ├── Web/, EmulatorJS/, assets/
    ├── web/                   Flutter web assets for Emby
    └── release/               build output staging

Step 1: build the web frontend (optional)

Both plugins serve the Moonfin web app: Jellyfin from Jellyfin/frontend/ and Emby from Emby/web/. If you only change backend code, the existing bundles are fine and you can skip this. To rebuild them, run the sync script from the Moonfin-Core repo:

cd /path/to/Moonfin-Core
./build-web-plugin.sh

With no arguments it builds once and syncs into both plugin frontends, assuming the Plugin repo is checked out next to Moonfin-Core. Both plugins serve the app at /Moonfin/Web/, so a single build works for both.

If your repos live elsewhere, pass the targets explicitly:

./build-web-plugin.sh /path/to/Plugin/Jellyfin/frontend /path/to/Plugin/Emby/web

You can also set MOONFIN_PLUGIN_FRONTEND_DIR and MOONFIN_EMBY_WEB_DIR to override either target.

The script runs flutter build web --wasm --release and copies the output into each target. It leaves config.json out (the plugins serve that at runtime) and syncs the theme editor assets separately.

Step 2: build the Jellyfin plugin

cd Plugin/Jellyfin
./build.sh                         # or: pwsh ./build.ps1

Both scripts accept optional parameters:

./build.sh [VERSION] [TARGET_ABI]
pwsh ./build.ps1 -Version "1.9.1.0" -TargetAbi "10.10.0"

The build compiles the plugin, runs the verify tool as a gate, bundles frontend/ next to the DLL, packages everything into a zip, and updates the manifest checksum.

Output: Jellyfin/Moonfin.Server-<version>.zip, containing Moonfin.Server.dll, SharpCompress.dll, meta.json, and frontend/.

Step 3: build the Emby plugin

cd Plugin/Emby
./build.sh                         # or: pwsh ./build.ps1

Parameters:

./build.sh [VERSION] [TARGET_ABI]

The build compiles the plugin, copies the DLL and SharpCompress.dll (SharpCompress ships with the plugin because Emby does not provide it, and it is needed for .7z ROM extraction), bundles the web assets if present, and zips them.

Output: Emby/Emby.Plugins.Moonfin-<version>.zip, containing Emby.Plugins.Moonfin.dll, SharpCompress.dll, and the web folder. The Emby build does not touch manifest.json, since the Emby plugin installs as a drop-in zip rather than through a catalog.

Installing your build

See the Installation section of the README for where to drop each plugin.

Clone this wiki locally