Skip to main content
A Redmine theme is a directory that overrides the application’s default CSS (and optionally JavaScript) to change the visual appearance of the UI. Themes do not modify any Ruby or template code — they work purely through asset replacement.

Where themes live

Redmine looks for themes in two locations:
<redmine_root>/themes/          # User-installed themes
<redmine_root>/app/assets/themes/  # Themes bundled with the application
Each subdirectory inside these locations is treated as a potential theme. A directory is recognized as a valid theme only if it contains the file stylesheets/application.css:
# lib/redmine/themes.rb
def self.scan_themes
  dirs = Dir.glob([
    "#{Rails.root}/app/assets/themes/*",
    "#{Rails.root}/themes/*"
  ]).select do |f|
    File.directory?(f) && File.exist?("#{f}/stylesheets/application.css")
  end
  dirs.collect { |dir| Theme.new(dir) }.sort
end
The themes/ directory at the root of your Redmine installation ships with only a README file. This is the correct place to install third-party themes.

How Redmine loads themes

Redmine scans the theme directories once at startup (lazy-loaded on first access) and builds a list of Redmine::Themes::Theme objects. Each Theme object exposes:
Attribute/methodDescription
idDirectory name, used as the theme identifier
nameHuman-readable name (id.humanize)
pathAbsolute filesystem path to the theme directory
stylesheetsArray of CSS file names (without extension) in stylesheets/
javascriptsArray of JS file names (without extension) in javascripts/
imagesArray of image file names in images/
faviconFirst file found in the favicon/ directory, or nil
The current_theme helper (included in ApplicationHelper) reads the Setting.ui_theme value and returns the matching Theme object:
# lib/redmine/themes.rb
module Helper
  def current_theme
    unless instance_variable_defined?(:@current_theme)
      @current_theme = Redmine::Themes.theme(Setting.ui_theme)
    end
    @current_theme
  end
end
If the saved theme id does not match any installed theme (for example, after the theme is removed), Redmine falls back to the default appearance.

Asset paths

Theme assets are served from the path themes/<theme_dir>/. For example, a theme in themes/my_theme/ serves its stylesheet at:
/themes/my_theme/stylesheets/application.css
Redmine automatically includes the theme’s stylesheets/application.css in every page when the theme is active. If the theme directory contains a file javascripts/theme.js, it is also included automatically:
# lib/redmine/themes.rb
def heads_for_theme
  if current_theme && current_theme.javascripts.include?('theme')
    javascript_include_tag current_theme.javascript_path('theme')
  end
end

Switching themes

  1. Place your theme directory (containing stylesheets/application.css) inside <redmine_root>/themes/.
  2. Restart Redmine if it is running in production mode.
  3. Go to Administration > Settings > Display.
  4. Select your theme from the Theme dropdown.
  5. Click Save.
The change takes effect immediately for all users.
In development mode you can call Redmine::Themes.rescan from the Rails console to pick up newly added themes without restarting the server.

Default theme

When no theme is selected (the setting is blank), Redmine uses the styles compiled into app/assets/stylesheets/. Theme authors typically use the default theme’s application.css as a baseline and override only the rules they want to change.

Creating a custom theme

Learn how to create a theme directory, required files, and how to override styles.