KefinTweaks is a comprehensive collection of enhancements and customizations for Jellyfin, focused on, but not limited to, filling gaps in functionality based on the community’s most desired Feature Requests. This includes things like a Watchlist, a customizable Home Screen, an improved search experience, and an Appearance Manager.
While working on these scripts to meet my personal needs, I noticed that there was a lot of overlap between the functionality I desire and many of the requested features by the community so I thought it would be a good idea to share this for anyone who may be interested.
Since I began working on this in August 2025, the scope of the project has grown and changed drastically. This began as a small set of tweaks to enhance my own personal server, but has evolved into a robust set of features that aim to compliment and enhance the native Jellyfin experience in a way that feels like it is native functionality.
In the future, we can hope that the majority of this plugin will become obsolete as we will see many of these changes implemented and included in the native Jellyfin experience, as the community has so long desired!
I think it’s also worth mentioning that before the 1.0 release, you can expect to potentially encounter some issues or bugs. I try to address these as quickly as I can, and I appreciate your time for raising the issues in the first place!
Note: The Slideshow at the top of the Home Screen in the video below is from the MediaBar plugin by IAmParadox27 and MakD.
const script = document.createElement("script");
script.src = `https://cdn.jsdelivr.net/gh/ranaldsgift/KefinTweaks@latest/kefinTweaks-plugin.js`;
script.async = true;
document.head.appendChild(script);
If you are hosting the script yourself, replace the https://cdn.jsdelivr.net/gh/ranaldsgift/KefinTweaks@latest/ with your hosted location + /KefinTweaks/. You should be able to include the scripts in your jelly-web folder and access it from /web/KefinTweaks if you like.
KefinTweaks includes a comprehensive configuration interface accessible to administrators. The configuration UI allows you to customize all aspects of KefinTweaks without editing code files.
The configuration interface can be accessed in multiple ways:
All configuration options for KefinTweaks can be managed directly from the UI.
On first load, KefinTweaks automatically:
KefinTweaks-Config script in the JavaScript Injector plugin with default settingsThese tasks only run for administrator users and happen automatically in the background.
KefinTweaks provides a modular system of enhancements that can be individually enabled or disabled based on your needs. Each script is designed to work independently while sharing common utilities and dependencies.
As mentioned above, most of the functionality included in KefinTweaks are features that have been requested by the community. Some of these requests have been pending for 5 years or more. I feel that a lot of the top requests have functionality that is essential to the Jellyfin experience but I have also included less requested features, as well as some things that I just personally needed or wanted.
One thing that I feel is worth pointing out is the way in which some of the data needed by KefinTweaks is handled. For most of the features, data is grabbed on demand as normal, same as any existing Jellyfin functionality. However there are specific features, or subsets of features which do use local device caching in order to either improve performance, or simply because it is not feasible to fetch the data each time. In the future if this ever becomes a plugin, the caching can be more intelligent and done on the server.
The features in KefinTweaks which use local data caching are listed below, along with accompanying explanations for why they are being cached. Everything is cached by default for 24h unless it is specified otherwise.
Tired of forgetting everything you wanted to watch? Add movies, series, seasons, and episodes to your Watchlist!
An overview of every series you’ve ever started watching with functionality to filter, sort and mark items as watched.
An overview of every movie you’ve ever watched with functionality to filter, sort and mark items as favorites.
A summary of your watched items by the numbers. See how many movies, shows or episodes you have watched.
Export your Watchlist to JSON which can later be imported using the Watchlist Import feature. You can use this feature to make bulk changes to your Watchlist if you need to. Additionally, you can Sync your Watchlist to any Playlist of your choice.
| Watchlist Export | Watchlist Import |
|---|---|
![]() |
![]() |
Auto-Remove:
Automatically removes watched items from your watchlist when playback completes.
Real-time Updates:
Cached watchlist updates when toggling watchlist status from card overlays
Custom Sections:
Add playlist or collection-based sections to your home screen
New & Trending:
Creates sections for movies and episodes released in the last 7 days (trending sections incomplete)
Infinite Discovery Sections:
Load discovery sections based on items you’ve watched and favorited, as well as from genres or top people in your library
HSS Support:
Full compatibility with Home Screen Sections plugin by IAmParadox27
Seasonal Content:
Seasonally-themed sections (Halloween, Christmas, etc.)
Performance Improvements:
Defaults to searching in Movies/TV/People as most searches are for these items. Options to search specific categories or all categories like the default Jellyfin search functionality.
Jellyseerr Support:
If you have JellyfinEnhanced installed, the Jellyseerr search results will appear in the KefinTweaks enhanced search. There is also a button that lets users search specifically for Requests.
Meilisearch Support:
Zero-config support for searching with the Meilisearch plugin
The Skin Manager adds the functionality for users to change the appearance of the Web UI from a button in the top header, or from their Display Preferences in their User Account.
| Top Header Button | User Display Preferences |
|---|---|
![]() |
![]() |
Skins
Select from a list of pre-defined Skins created by other Jellyfin community members. You may specify additional custom skins in the configuration options.
Color Schemes
Certain Skins either support or require a color scheme. This lets you change the UI colors within an individual Skin. These options are automatically available for the Skins which support them.
Optional CSS Modules
KefinTweaks also includes optional CSS modules from supported Skins, and even adds some of these as Global options for users to take advantage of with any Skin.
Search and download subtitles directly from the video OSD
Adds a card overlay button to remove items from Continue Watching for all resumable items
Adds the ability to sort collection items on the Collection page. Supports sorting by Title, Release Date, Date Added, Community Rating, Critic Rating.
Improved tab navigation and functionality, supports linking to specific tabs
Clear navigation paths for Movies, Series, Seasons, Episodes, Music Artists, Albums and Songs
Add custom menu links to the side navigation drawer menu
Updates the default playlist functionality to include a play button to start playback and make clicking an item go to the item detail page
Adds an Episodes section on the Series page which displays the episodes from the season with the Next Up item. Users can quickly switch between seasons to browse other episodes. Includes the option to “Flatten Single Season Shows” which will hide the Seasons container when only one season is present.
This shows an “Included In” section on the Item Details page which displays any Collections that the item is a part of.
Background Leak Fix:
Resolves an issue that causes backgrounds to be added to the DOM endlesslly when a tab is not focused and Backdrop images are enabled
Infinite Scroll:
Adds infinite scrolling to the Movies and TV library pages. Loads batches of 100 items at a time and supports filtering and sorting.
LocalStorage Caching:
Local caching for data related to Watchlist, Series Progress, Movie History and Top People
Dashboard Button Fix:
Fix to handle navigating back from the dashboard page to the homescreen instead of the “new tab” page of a browser
Exclusive Elsewhere:
Custom branding for items which aren’t available on any external streaming providers. Requires JellyfinEnhanced.
Ratings and Comments:
Coming soon…requires the Updoot backend script
| Script | Description |
|---|---|
utils.js |
Page view management and common utilities |
skinConfig.js |
Default skin configuration for KefinTweaks |
apiHelper.js |
API helper functions for common Jellyfin operations |
cardBuilder.js |
Core card building functionality (required by other scripts) |
localStorageCache.js |
localStorage-based caching layer with 24-hour TTL and manual refresh |
indexedDBCache.js |
IndexedDB-based caching layer for large datasets with TTL support |
modal.js |
Generic modal system for Jellyfin-style dialogs |
toaster.js |
Toast notification system using Jellyfin’s existing toast functionality |
| Script | Description | Dependencies |
|——–|————-|————–|
| skinManager.js | Skin selection and management (loads with priority) | utils, skinConfigLegacyDefaults, skinConfig, modal |
| watchlist.js | Adds watchlist functionality throughout Jellyfin interface | cardBuilder, localStorageCache, modal, utils |
| homeScreen.js | Adds custom home screen sections | cardBuilder, localStorageCache, utils |
| search.js | Enhanced search functionality | cardBuilder, utils |
| headerTabs.js | Header tab improvements | None |
| customMenuLinks.js | Load and add custom menu links from configuration | utils |
| exclusiveElsewhere.js | Modifies the behavior of the Jellyfin Enhanced Elsewhere functionality to add custom branding when items are not available on streaming services | None |
| updoot.js | Upvote functionality provided by https://github.com/BobHasNoSoul/jellyfin-updoot | None |
| backdropLeakFix.js | Fixes issue that causes backdrop images to be continuously added to the page if the tab isn’t focused | None |
| dashboardButtonFix.js | Fixes the dashboard button to redirect to the home page when the back button is clicked and there is no history to go back to | None |
| infiniteScroll.js | Adds infinite scroll functionality to media library pages | cardBuilder |
| removeContinue.js | Adds remove from continue watching functionality to cards with data-position-ticks | None |
| subtitleSearch.js | Adds subtitle search functionality to the video OSD, allowing users to search and download subtitles from remote sources | toaster |
| breadcrumbs.js | Adds breadcrumb navigation to item detail pages for Movies, Series, Seasons, Episodes, Music Artists, and Music Albums | utils |
| playlist.js | Modifies playlist view page behavior to navigate to item details instead of playing, adds play button to playlist items, and adds sorting functionality | cardBuilder, utils, modal |
| itemDetailsCollections.js | Adds related collections to item details pages showing which collections contain the current item | indexedDBCache, utils, cardBuilder |
| seriesEpisodes.js | Displays episodes directly on series page with season selection. Works for both single and multi-season shows when enabled. | cardBuilder, utils |
| seriesInfo.js | Adds series and season information (seasons count, episodes count, end time) to details pages | utils |
| collections.js | Adds sorting functionality to collection pages | utils, modal |
KefinTweaks automatically enables required dependencies when you enable a script that needs them. For example:
watchlist automatically enables cardBuilder, localStorageCache, modal, and utilsThis ensures all scripts have their required dependencies without manual configuration.
This section will detail any information relevant for other developers who wish to take advatange of KefinTweaks features in their own projects:
Currently the only functionality that can be very easily included by developers of other projects is the Watchlist functionality.
The KefinTweaks Watchlist leverages the existing Jellyfin Item UserData field: “Likes”. Here is how KefinTweaks handles the funcionality and how you can as well:
Filters=LikesEven if you only implement the first bullet point and add a section for Watchlist items, KefinTweaks will automatically handle Watchlist syncing whenever the user connects with a KefinTweaks supported client.
KefinTweaks is a front end plugin that relies on the Jellyfin Web UI to function. This means that it will function wherever the Jellyfin Web UI is used, and won’t function in any apps that don’t use the Web UI.
Here is a list of known supported clients:
A few things to note about KefinTweaks functionality in general and how it interacts with the default Jellyfin functionality:
The general design philosophy here is to utilize as much pre-existing Jellyfin functionality as possible in order to ensure long term compatibility, and also to potentially make it a bit easier for anyone interested in taking these ideas into the core Jellyfin projects. Even where functionality is being “overridden” we still typically utilize underlying Jellyfin functionality to achieve the results desired.
The only real Plugin dependency that KefinTweaks has is JS Injector which is being used to both load the KefinTweaks scripts, and save configuration data on the server. Loading the scripts without JS Injector is very simple, but without another way of storing configuration data on the server, JS Injector is absolutely required if you wish to override any of the default configuration options in the UI.
The main goal of this project is to push the limits of what is possible through a “front end plugin”. All of the code in this project is executed by the client. This is quite unusual in terms of the typical Jellyfin plugin, but I hope it may be inspiring for other future creations down the road. I would also be very happy if the changes included here helped push forward the progress to get these changes implemented in the core Jellyfin project so that everyone can take advantage of them without needing a third party plugin.
To preface this, I want to say that historically, all of the community oriented projects I have worked on in the past have been composed nearly entirely by code that I have written myself. As new development tools have been released, I have tried to take advantage of them as much as possible in order to improve my own learning and to make my projects better. I understand that everyone has different personal feelings regarding the use of AI, so I wanted to leave a statement to make it clear about how I have chosen to use AI for this project in particular.
I have started this project with a polar opposite approach from my past endeavors. With the rise of “vibe coding” I wanted to see what I could achieve using a similar philosophy. I understand the obvious short comings of using such a methodology, and I believe that in the majority of the situations it will be very detrimental in the long run. Where I can see this type of tool excelling, is the exact use case of KefinTweaks: mostly small self contained scripts which don’t rely on any external pieces of logic. This is one of the main motivating factors that led me to believe I could achieve what I desire purely through “vibe coding”.
As it stands right now, and how I expect to proceed going forward, is to act in a role of “Project Manager” instead of “coder/developer”. I don’t blindly include every bit of code that is provided by my prompts. I make very thorough prompts that essentially provide very detailed documentation of the features to be implemented, in the same way a real project manager might provide this documentation to their team. I am not doing this for practice as I no longer professionally work in the design industry and have no plans to, but moreso just for fun and to see what the results are.
The journey so far has been quite enjoyable. The scale of KefinTweaks has expanded a lot over time, so I do certainly have my concerns about the sustainability of this approach, but I plan to continue on like this unless I hit a roadblock. I hope that this choice will not deter you from trying this plugin, but I did want to make the use of AI clear as I understand that it is a hot issue in the industry and around the globe. My personal view is that AI should be used responsibly as a tool, just like any other tool. I think that AI has no place in replacing artists and other creative work that humans carry out.
This project is licensed under the MIT License - see the LICENSE file for details.
I saved the KefinTweaks Plugin script in JS Injector but I don’t see KefinTweaks in the Dashboard menu
You must complete the installation by clicking the KefinTweaks plugin and selecting the installation source (either GitHub or local) from the KefinTweaks plugin card at the very bottom of your Plugins page:
KefinTweaks Plugin never appears in the Plugins page even though I saved the KefinTweaks Plugin script in JS Injector
JavaScriptInjector\public.js is loaded by the client:
Issues:
KefinTweaks is not maintained by the Jellyfin team, and as a result you are encouraged to seek support from me directly. Sadly, there is no place suitable for discussion of plugins built by community members or fan-made projects in the official Jellyfin Discord, so please visit the Jellyfin Community Discord to find me (username: HighImKevin) and other users who would be happy to help you out. Please also feel free to report bugs and request features from the Issues page.
Documentation:
This README and the inline comments in kefinTweaks.js and the other scripts is the only real documentation available at this time