Skip to main content
We welcome contributions from the community! This guide explains the development workflow, coding standards, and how to submit changes to Jellyfin Server.

Before You Start

1

Read the Community Guidelines

2

Check Existing Issues

Browse GitHub Issues to see if your bug or feature is already reported.
3

Discuss Major Changes

For significant features or architectural changes, open a discussion or issue first to get feedback before investing time in development.
New to contributing? Check out the Jellyfin contribution guide to find where you can help.

Development Setup

Before contributing, set up your development environment:
1

Fork the Repository

  1. Go to github.com/jellyfin/jellyfin
  2. Click Fork in the top right
  3. Clone your fork:
    git clone https://github.com/YOUR-USERNAME/jellyfin.git
    cd jellyfin
    
2

Add Upstream Remote

Add the main repository as upstream:
git remote add upstream https://github.com/jellyfin/jellyfin.git
3

Set Up Development Environment

Follow the Building from Source guide to install prerequisites and build the project.

Development Workflow

1

Create a Feature Branch

Create a new branch for your work:
git checkout -b feature/my-awesome-feature
Branch naming conventions:
  • feature/description - New features
  • fix/description - Bug fixes
  • refactor/description - Code refactoring
  • docs/description - Documentation changes
2

Make Your Changes

Write your code following the coding standards below.
Make small, focused commits that do one thing well. This makes code review easier.
3

Write Tests

Add or update tests for your changes:
  • Unit tests in tests/ directory
  • Follow existing test patterns
  • Aim for good code coverage
Run tests locally:
dotnet test
4

Commit Your Changes

Write clear, descriptive commit messages:
git add .
git commit -m "Add feature: description of what you did"
Follow the commit message guidelines.
5

Keep Your Branch Updated

Regularly sync with upstream:
git fetch upstream
git rebase upstream/master
6

Push to Your Fork

git push origin feature/my-awesome-feature

Submitting a Pull Request

1

Create Pull Request

  1. Go to your fork on GitHub
  2. Click Pull Request
  3. Select your branch and the master branch of jellyfin/jellyfin
  4. Fill out the PR template
2

Write a Clear Description

Your PR description should:
  • Explain what changes you made
  • Explain why these changes were necessary
  • Reference any related issues (e.g., “Fixes #1234”)
  • Describe how to test the changes
  • Note any breaking changes
See the PR template for guidance.
3

Respond to Review Feedback

  • Address reviewer comments promptly
  • Make requested changes in new commits
  • Don’t force-push after review starts (squashing happens at merge)
  • Ask questions if feedback is unclear
4

Wait for CI Checks

Your PR will be automatically tested:
  • Build verification
  • Unit tests
  • Code analyzers
  • Style checks
All checks must pass before your PR can be merged.

Pull Request Template

Jellyfin uses a PR template (see .github/pull_request_template.md):
**Changes**
<!-- Describe your changes here in 1-5 sentences. -->

**Issues**
<!-- Tag any issues that this PR solves here.
ex. Fixes #123 -->
Write your PR title in the imperative mood: “Fix X”, “Add Y”, not “Fixed X” or “Added Y”. See How to Write a Git Commit Message for more guidance.

Coding Standards

Jellyfin follows strict coding standards enforced by analyzers:

C# Style Guidelines

Use Modern C# Features

  • Use nullable reference types (#nullable enable)
  • Use pattern matching where appropriate
  • Use expression-bodied members for simple properties/methods
  • Use var for obvious types

Follow .NET Conventions

  • PascalCase for public members
  • camelCase for private fields (with _ prefix)
  • Use meaningful, descriptive names
  • Avoid abbreviations

Add XML Documentation

Document public APIs:
/// <summary>
/// Gets system information.
/// </summary>
/// <returns>System info object.</returns>
public SystemInfo GetSystemInfo()

Use Code Analyzers

The project uses multiple analyzers:
  • StyleCop (style rules)
  • SerilogAnalyzer (logging)
  • IDisposableAnalyzers (resource management)
  • MultithreadingAnalyzer (concurrency)

EditorConfig

Jellyfin includes an .editorconfig file that defines formatting rules. Ensure your editor/IDE respects these settings:
Key Rules
[*.cs]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
Visual Studio, VS Code, and Rider all support EditorConfig automatically.

Dependency Injection

Jellyfin uses dependency injection extensively:
Good Example
public class MyController : BaseJellyfinApiController
{
    private readonly ILibraryManager _libraryManager;
    private readonly ILogger<MyController> _logger;
    
    public MyController(
        ILibraryManager libraryManager,
        ILogger<MyController> logger)
    {
        _libraryManager = libraryManager;
        _logger = logger;
    }
}
Avoid using static instances or service locators. Request dependencies through constructors.

Async/Await

Use async/await correctly:
// ✅ Good - async method with await
public async Task<string> GetDataAsync()
{
    return await _httpClient.GetStringAsync("http://example.com");
}

// ❌ Bad - async without await
public async Task<string> GetDataAsync()
{
    return _cache.GetValue("key");
}

// ✅ Good - no async needed
public Task<string> GetDataAsync()
{
    return Task.FromResult(_cache.GetValue("key"));
}

Exception Handling

try
{
    await ProcessItemAsync(item);
}
catch (HttpRequestException ex)
{
    _logger.LogError(ex, "Failed to fetch data for item {ItemId}", item.Id);
    // Handle specific exception
}
catch (Exception ex)
{
    _logger.LogError(ex, "Unexpected error processing item {ItemId}", item.Id);
    throw; // Re-throw if you can't handle it
}

Commit Message Guidelines

Write clear, descriptive commit messages following these rules:

Format

Short summary (50 chars or less)

More detailed explanation if needed. Wrap at 72 characters.
Explain the problem this commit solves and why this approach
was chosen.

Fixes #123

Rules

1

Use Imperative Mood

Write as if giving a command:
  • ✅ “Fix bug in user authentication”
  • ❌ “Fixed bug in user authentication”
  • ❌ “Fixes bug in user authentication”
2

Keep First Line Short

  • Maximum 50 characters
  • Capitalize first word
  • No period at the end
3

Provide Context in Body

  • Explain why not what (code shows what)
  • Wrap at 72 characters
  • Reference issues with Fixes #123 or Closes #456

Examples

Add pagination support to library API

The Items endpoint now supports startIndex and limit parameters
to enable client-side pagination. This reduces initial load time
for large libraries and improves performance.

Fixes #1234
Read How to Write a Git Commit Message for more detailed guidance.

Testing Guidelines

All code changes should include appropriate tests:

Unit Tests

Write unit tests in the corresponding test project:
tests/Jellyfin.Api.Tests/Controllers/SystemControllerTests.cs
using Xunit;
using Jellyfin.Api.Controllers;

public class SystemControllerTests
{
    [Fact]
    public void GetSystemInfo_ReturnsValidInfo()
    {
        // Arrange
        var controller = CreateController();
        
        // Act
        var result = controller.GetSystemInfo();
        
        // Assert
        Assert.NotNull(result);
        Assert.NotNull(result.Value);
    }
}

Integration Tests

For API endpoint tests, use the integration test project:
dotnet test tests/Jellyfin.Server.Integration.Tests

Test Structure

Follow the Arrange-Act-Assert pattern:
[Fact]
public async Task GetItem_WithValidId_ReturnsItem()
{
    // Arrange - Set up test data and mocks
    var itemId = Guid.NewGuid();
    var expectedItem = new Movie { Id = itemId };
    
    // Act - Execute the code being tested
    var result = await _controller.GetItem(itemId);
    
    // Assert - Verify the results
    Assert.NotNull(result);
    Assert.Equal(itemId, result.Id);
}

Code Review Process

All pull requests go through code review:
1

Automated Checks

  • CI builds and tests your code
  • Code analyzers check style and quality
  • All checks must pass
2

Maintainer Review

  • At least one maintainer reviews your code
  • They may request changes or ask questions
  • Address feedback in new commits
3

Approval and Merge

  • Once approved, a maintainer will merge your PR
  • Commits may be squashed into one
  • Your contribution will be in the next release!

What Reviewers Look For

Code Quality

  • Follows coding standards
  • Well-structured and maintainable
  • Proper error handling
  • No code smells

Functionality

  • Solves the stated problem
  • No breaking changes (unless justified)
  • Edge cases handled
  • Performance considerations

Testing

  • Adequate test coverage
  • Tests actually verify functionality
  • Integration tests for new features

Documentation

  • XML docs for public APIs
  • Clear commit messages
  • Updated documentation if needed

Common Pitfalls to Avoid

Don’t:
  • Submit large PRs that change many unrelated things
  • Force-push after review has started
  • Ignore CI failures
  • Skip writing tests
  • Make style-only changes without discussing first
  • Add dependencies without justification
Do:
  • Keep PRs focused on one issue/feature
  • Write clear commit messages
  • Respond to review feedback promptly
  • Ask questions if unsure
  • Test your changes thoroughly
  • Update documentation

Getting Help

If you need help contributing:

Matrix Chat

Join the community chat for real-time help

GitHub Discussions

Ask questions and discuss ideas

Contributing Docs

Read the full contributing documentation

Issue Tracker

Report bugs and track feature requests

Recognition

Your contributions are valued! Contributors are:
  • Listed in the CONTRIBUTORS.md file
  • Mentioned in release notes
  • Part of the Jellyfin community
Check out the Jellyfin Contributor Graph to see all contributors.

Additional Resources

Building from Source

Set up your development environment

API Overview

Learn about the Jellyfin API architecture

Plugin Development

Extend Jellyfin with plugins

Feature Requests

Vote on and suggest new features

Thank You!

Thank you for contributing to Jellyfin! Every contribution, no matter how small, helps make Jellyfin better for everyone.

Build docs developers (and LLMs) love