mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2026-09-03 03:50:02 +03:00
134 lines
7.8 KiB
Markdown
134 lines
7.8 KiB
Markdown
# 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.
|
||
* New app pages **MUST** be written using React components using `src/components/Page.tsx` as the base component.
|
||
* **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.
|
||
* You **MAY** add your GitHub username to the list of contributors in [CONTRIBUTORS.md](./CONTRIBUTORS.md).
|
||
|
||
### 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.
|
||
* **MUST** fully complete the PR template. Failing to do so will result in the PR being closed as invalid without 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).
|
||
|
||
#### 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
|
||
|
||
* [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 Modern 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](./src/elements) | MUI components (Dashboard + Modern 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) |
|
||
|
||
#### 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](./package.json).
|
||
|
||
## Application Components
|
||
|
||
* Modern App `src/apps/modern`
|
||
* Ongoing rewrite of the main user interface using MUI components
|
||
* Currently reuses content from the Legacy App to maintain parity
|
||
* Does not currently support TV layout!
|
||
* Legacy App `src/apps/legacy`
|
||
* Main user application
|
||
* Supports 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
|
||
|
||
## 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
|
||
│ ├── legacy # Legacy app
|
||
│ ├── modern # New modern (React based) app
|
||
│ └── wizard # Startup wizard app
|
||
├── assets # Static assets
|
||
├── components # Higher order visual components and React components
|
||
├── constants # Common constant values
|
||
├── 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)
|