From e03d32db82b5a6df121a88646e6756e26f127ff5 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 12 Mar 2026 12:34:10 -0400 Subject: [PATCH 1/3] Add contributing guide and pr checklist --- .github/pull_request_template.md | 30 +++++++++--- CONTRIBUTING.md | 84 ++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 06bc4a75e7..fe7745cc12 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,13 +3,27 @@ Ensure your title is short, descriptive, and in the imperative mood (Fix X, Chan For a good inspiration of what to write in commit messages and PRs please review https://chris.beams.io/posts/git-commit/ and our https://jellyfin.org/docs/general/contributing/issues page. --> -**Changes** - +### Changes + -**Issues** - +### Issues + -**Code assistance** - +### Code assistance + + +--- + +* [ ] I have read and followed the [contributing guidelines](https://github.com/jellyfin/jellyfin-web/blob/master/CONTRIBUTING.md). +* [ ] I have tested these changes. +* [ ] I have verified that this is not duplicating changes in an existing PR. +* [ ] I have provided a *substantive* review of [another web PR](https://github.com/jellyfin/jellyfin-web/pulls?q=is%3Apr+is%3Aopen+-label%3Adependencies+-label%3Ablocked+-label%3Abackend+-label%3Ainvalid+-label%3A"merge+conflict"+-label%3Astale+-author%3A%40me). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..c96f60877d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,84 @@ +# Contributing to Jellyfin Web + +Thanks for taking the time to contribute! :purple_heart: +Jellyfin is an entirely volunteer-driven project, so without contributors like you it could not exist! + +Below are some general guidelines and information about this project. +If you have any questions, please join one of our [development chat rooms](https://jellyfin.org/contact/) to discuss them! + +## Contributor Guidelines + +### New Code + +* New files **MUST** be written in TypeScript. +* API interactions **MUST** be made using the Jellyfin TypeScript SDK. +* **SHOULD** be covered by unit tests when possible (legacy component/view code is deemed untestable). +* **SHOULD** avoid whitespace only changes in unchanged sections of code. +* **SHOULD NOT** overuse dynamic imports. We use dynamic imports at the page level; otherwise we should let our build tooling deal with code-splitting for the best bundle sizes. +* **SHOULD NOT** reference browser globals. Globals exist for plugins/legacy compatibility. Use direct imports for any dependencies instead. + +### Localization + +* Translation changes or additions **MUST** be made via the [Jellyfin Weblate instance](https://translate.jellyfin.org/) except for the source language (`en-us`). +* Existing translation keys **SHOULD NOT** be renamed without a significant reason. Weblate cannot track key name changes so a key name change requires retranslation in ALL languages. + +### Pull Requests + +* **MUST** follow [project guidelines](https://jellyfin.org/docs/general/contributing/development#pull-request-guidelines). + * **SHOULD NOT** use "Conventional Commits" for titles or commit messages. + * **SHOULD NOT** rebase once reviews are in progress. +* **MUST** follow the [LLM development policy](https://jellyfin.org/docs/general/contributing/llm-policies). +* **MUST** test that the change works as expected before marking a PR as ready for review. +* **SHOULD** represent a singular focus (i.e. a PR to fix a bug should not include unrelated refactoring). +* **SHOULD NOT** update from `master` needlessly once opened (only update if conflicts exist). + +## Application Architecture + +### Tech Stack + +* [Bulletproof React based structure](https://forum.jellyfin.org/t-proposed-update-to-the-structure-of-jellyfin-web) ([official reference](https://github.com/alan2207/bulletproof-react/blob/master/README.md)) — General file structure +* [TypeScript](https://www.typescriptlang.org/docs/handbook/intro.html) — Programming language +* [Jellyfin TypeScript SDK](https://typescript-sdk.jellyfin.org/) — Jellyfin API library +* [React](https://react.dev/reference/react) — User Interface library +* [React Router](https://reactrouter.com/) — Routing library +* [TanStack Query](https://tanstack.com/query/latest/docs/framework/react/overview) — State management library for server data +* [MUI](https://mui.com/material-ui/getting-started/) components (in Dashboard and Experimental layouts) — UI component library +* [Webpack](https://webpack.js.org/concepts/) — Bundler / build tooling +* [Vitest](https://vitest.dev/api/) — Test library + +#### Legacy Stack + +| Library | Replacement | +| --- | --- | +| [Emby WebComponents](https://github.com/jellyfin/jellyfin-web/tree/master/src/elements) | MUI components (Dashboard + Experimental apps ONLY; Untested on TVs) | +| [App Router](https://github.com/jellyfin/jellyfin-web/blob/master/src/components/router/appRouter.js) | React Router | +| [View Manager](https://github.com/jellyfin/jellyfin-web/tree/master/src/components/viewManager) | React Router | +| [Jellyfin ApiClient](https://github.com/jellyfin-archive/jellyfin-apiclient-javascript) | Jellyfin TypeScript SDK | +| [jQuery](https://api.jquery.com/) | None (use plain JavaScript/TypeScript) | + +#### Supported Browsers + +This codebase supports a wide variety of platforms including TVs that are stuck on ancient versions of browser engines. +As a result, we can only use JavaScript and CSS features that are either directly supported by these browser versions or can be otherwise compiled or polyfilled for compatibility. +The official list of supported browser versions can be found in the `browserlist` section of the [package.json file](https://github.com/jellyfin/jellyfin-web/blob/master/package.json). + +## Application Components + +* Stable App `src/apps/stable` + * Main user application + * Supports TV layout +* Experimental App `src/apps/experimental` + * Ongoing rewrite of the Stable App using MUI components + * Currently reuses (most) pages from the Stable App to maintain parity + * Does not currently support TV layout! +* Dashboard App `src/apps/dashboard` + * Admin dashboard and metadata editor pages + * Almost completely rewritten using MUI components + * No TV support (dashboard pages are not available) +* Wizard App `src/apps/wizard` + * First time setup wizard +* Plugins `src/plugins` + * This is a terrible name as it has nothing to do with server plugins + * Modular functionality that is loaded dynamically at runtime + * ALL media player implementations are plugins + * Allows native wrapper overrides From a85e5a1ef69472bdd2e1903595efdcc2205cc484 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 17 Mar 2026 14:22:31 -0400 Subject: [PATCH 2/3] Remove trailing slash from contact url Co-authored-by: Niels van Velzen --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c96f60877d..5dc4c38457 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ Thanks for taking the time to contribute! :purple_heart: Jellyfin is an entirely volunteer-driven project, so without contributors like you it could not exist! Below are some general guidelines and information about this project. -If you have any questions, please join one of our [development chat rooms](https://jellyfin.org/contact/) to discuss them! +If you have any questions, please join one of our [development chat rooms](https://jellyfin.org/contact) to discuss them! ## Contributor Guidelines From 1c6faa10a6c6d0038e4fd618632d445d38ce1c59 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Fri, 20 Mar 2026 08:47:44 -0400 Subject: [PATCH 3/3] Move directory structure and add rebase instructions --- CONTRIBUTING.md | 56 +++++++++++++++++++++++++++++++++++++++++++++---- README.md | 39 +--------------------------------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5dc4c38457..0cba5d5b0a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,6 +16,7 @@ If you have any questions, please join one of our [development chat rooms](https * **SHOULD** avoid whitespace only changes in unchanged sections of code. * **SHOULD NOT** overuse dynamic imports. We use dynamic imports at the page level; otherwise we should let our build tooling deal with code-splitting for the best bundle sizes. * **SHOULD NOT** reference browser globals. Globals exist for plugins/legacy compatibility. Use direct imports for any dependencies instead. +* You **MAY** add your GitHub username to the list of contributors in [CONTRIBUTORS.md](./CONTRIBUTORS.md). ### Localization @@ -32,6 +33,14 @@ If you have any questions, please join one of our [development chat rooms](https * **SHOULD** represent a singular focus (i.e. a PR to fix a bug should not include unrelated refactoring). * **SHOULD NOT** update from `master` needlessly once opened (only update if conflicts exist). +#### Targeting a Release Branch + +You may be asked to update your Pull Request to target a release branch as part of our patch / bug-fix release process. Follow these steps to properly update your PR. + +1. `git rebase --onto release-X.Y.Z master` (Fetch the release branch if it does not exist in your local copy and replace `release-X.Y.Z` with the latest release branch.) +2. Force push your branch. +3. Update the target branch on Github by clicking "Edit" -> Change base branch to point to the release branch. + ## Application Architecture ### Tech Stack @@ -50,9 +59,9 @@ If you have any questions, please join one of our [development chat rooms](https | Library | Replacement | | --- | --- | -| [Emby WebComponents](https://github.com/jellyfin/jellyfin-web/tree/master/src/elements) | MUI components (Dashboard + Experimental apps ONLY; Untested on TVs) | -| [App Router](https://github.com/jellyfin/jellyfin-web/blob/master/src/components/router/appRouter.js) | React Router | -| [View Manager](https://github.com/jellyfin/jellyfin-web/tree/master/src/components/viewManager) | React Router | +| [Emby WebComponents](./src/elements) | MUI components (Dashboard + Experimental apps ONLY; Untested on TVs) | +| [App Router](./src/components/router/appRouter.js) | React Router | +| [View Manager](./src/components/viewManager) | React Router | | [Jellyfin ApiClient](https://github.com/jellyfin-archive/jellyfin-apiclient-javascript) | Jellyfin TypeScript SDK | | [jQuery](https://api.jquery.com/) | None (use plain JavaScript/TypeScript) | @@ -60,7 +69,7 @@ If you have any questions, please join one of our [development chat rooms](https This codebase supports a wide variety of platforms including TVs that are stuck on ancient versions of browser engines. As a result, we can only use JavaScript and CSS features that are either directly supported by these browser versions or can be otherwise compiled or polyfilled for compatibility. -The official list of supported browser versions can be found in the `browserlist` section of the [package.json file](https://github.com/jellyfin/jellyfin-web/blob/master/package.json). +The official list of supported browser versions can be found in the `browserlist` section of the [package.json file](./package.json). ## Application Components @@ -82,3 +91,42 @@ The official list of supported browser versions can be found in the `browserlist * Modular functionality that is loaded dynamically at runtime * ALL media player implementations are plugins * Allows native wrapper overrides + +## Directory Structure + +> [!NOTE] +> We are in the process of refactoring to a [new structure](https://forum.jellyfin.org/t-proposed-update-to-the-structure-of-jellyfin-web) based on [Bulletproof React](https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md) architecture guidelines. +> Most new code should be organized under the appropriate app directory unless it is common/shared. + +``` +. +└── src + ├── apps + │   ├── dashboard # Admin dashboard app + │   ├── experimental # New experimental app + │   ├── stable # Classic (stable) app + │   └── wizard # Startup wizard app + ├── assets # Static assets + ├── components # Higher order visual components and React components + ├── constants # Common constant values + ├── controllers # Legacy page views and controllers 🧹 ❌ + ├── elements # Basic webcomponents and React equivalents 🧹 + ├── hooks # Custom React hooks + ├── lib # Reusable libraries + │   ├── globalize # Custom localization library + │   ├── jellyfin-apiclient # Supporting code for the deprecated apiclient package + │   ├── legacy # Polyfills for legacy browsers + │   ├── navdrawer # Navigation drawer library for classic layout + │   └── scroller # Content scrolling library + ├── plugins # Client plugins (features dynamically loaded at runtime) + ├── scripts # Random assortment of visual components and utilities 🐉 ❌ + ├── strings # Translation files (only commit changes to en-us.json) + ├── styles # Common app Sass stylesheets + ├── themes # Sass and MUI themes + ├── types # Common TypeScript interfaces/types + └── utils # Utility functions +``` + +* ❌ — Deprecated, do **not** create new files here +* 🧹 — Needs cleanup +* 🐉 — Serious mess (Here be dragons) diff --git a/README.md b/README.md index 4d054ac376..f5107353d3 100644 --- a/README.md +++ b/README.md @@ -71,41 +71,4 @@ Jellyfin Web is the frontend used for most of the clients available for end user npm run build:development ``` -## Directory Structure - -> [!NOTE] -> We are in the process of refactoring to a [new structure](https://forum.jellyfin.org/t-proposed-update-to-the-structure-of-jellyfin-web) based on [Bulletproof React](https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md) architecture guidelines. -> Most new code should be organized under the appropriate app directory unless it is common/shared. - -``` -. -└── src - ├── apps - │   ├── dashboard # Admin dashboard app - │   ├── experimental # New experimental app - │   ├── stable # Classic (stable) app - │   └── wizard # Startup wizard app - ├── assets # Static assets - ├── components # Higher order visual components and React components - ├── constants # Common constant values - ├── controllers # Legacy page views and controllers 🧹 ❌ - ├── elements # Basic webcomponents and React equivalents 🧹 - ├── hooks # Custom React hooks - ├── lib # Reusable libraries - │   ├── globalize # Custom localization library - │   ├── jellyfin-apiclient # Supporting code for the deprecated apiclient package - │   ├── legacy # Polyfills for legacy browsers - │   ├── navdrawer # Navigation drawer library for classic layout - │   └── scroller # Content scrolling library - ├── plugins # Client plugins (features dynamically loaded at runtime) - ├── scripts # Random assortment of visual components and utilities 🐉 ❌ - ├── strings # Translation files (only commit changes to en-us.json) - ├── styles # Common app Sass stylesheets - ├── themes # Sass and MUI themes - ├── types # Common TypeScript interfaces/types - └── utils # Utility functions -``` - -- ❌ — Deprecated, do **not** create new files here -- 🧹 — Needs cleanup -- 🐉 — Serious mess (Here be dragons) +Review the [Contributing Guide](./CONTRIBUTING.md) for more information on our process and tech stack.