# How to Add Custom Themes to GPT Academic: A Complete Developer Guide

> Learn how to add custom themes to GPT Academic. Follow this developer guide to create Python modules, update config py, and register your theme for a personalized experience.

- Repository: [binary-husky/gpt_academic](https://github.com/binary-husky/gpt_academic)
- Tags: how-to-guide
- Published: 2026-03-02

---

**To add custom themes to GPT Academic, create a Python module in the `themes/` directory that implements the `adjust_theme()` function, add the theme name to the `AVAIL_THEMES` list in [`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py), and register the import path inside the `load_dynamic_theme()` dispatcher in [`themes/theme.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/theme.py).**

GPT Academic provides a modular theme system that allows developers to customize the visual appearance of the Gradio-based interface. Whether you want to adjust color schemes, inject custom CSS, or create entirely new visual layouts, the theme architecture in the `binary-husky/gpt_academic` repository provides a clean extension point without modifying core application code.

## Understanding the Theme Architecture

The theme system follows a dispatcher pattern that loads configurations dynamically at startup. When the application initializes, it reads the `THEME` variable from [`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py) (around line 93) to determine which visual style to apply. This value is passed to the `load_dynamic_theme()` function in [`themes/theme.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/theme.py) (lines 17-39), which acts as a central router importing the appropriate theme module based on the name provided.

Each theme module must expose two critical components: an `adjust_theme()` function that returns a Gradio theme object (`gr.themes.*`), and an `advanced_css` string containing additional stylesheet rules. The UI constructs the theme selection dropdown from the `AVAIL_THEMES` list defined in [`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py), as implemented in [`themes/gui_toolbar.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/gui_toolbar.py) (line 25).

## Step-by-Step Guide to Creating a Custom Theme

### Step 1: Create the Theme Module

Create a new Python file inside the `themes/` directory (e.g., [`themes/mytheme.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/mytheme.py)). This module must define the `adjust_theme()` function and expose the `advanced_css` variable:

```python

# themes/mytheme.py

import os
import gradio as gr
from toolbox import get_conf
from themes.common import get_common_html_javascript_code

theme_dir = os.path.dirname(__file__)

def adjust_theme():
    """
    Returns a Gradio theme object with custom color schemes.
    """
    # Initialize with a base theme and customize hues

    set_theme = gr.themes.Default(
        primary_hue=gr.themes.utils.colors.purple,
        secondary_hue=gr.themes.utils.colors.orange,
    )
    
    # Inject required JavaScript for GPT Academic functionality

    js = get_common_html_javascript_code()
    if not hasattr(gr, "RawTemplateResponse"):
        gr.RawTemplateResponse = gr.routes.templates.TemplateResponse
    orig_template = gr.RawTemplateResponse
    
    def wrapped_template(*args, **kwargs):
        res = orig_template(*args, **kwargs)
        res.body = res.body.replace(b"</html>", f"{js}</html>".encode())
        res.init_headers()
        return res
    
    gr.routes.templates.TemplateResponse = wrapped_template
    return set_theme

# Load accompanying CSS file

with open(os.path.join(theme_dir, "mytheme.css"), "r", encoding="utf-8") as f:
    advanced_css = f.read()

```

Place a corresponding CSS file at [`themes/mytheme.css`](https://github.com/binary-husky/gpt_academic/blob/main/themes/mytheme.css):

```css
/* themes/mytheme.css */
body {
    background-color: #fafafa;
}
.gradio-container {
    font-family: "Helvetica", sans-serif;
}

```

### Step 2: Register the Theme in config.py

Add your theme name to the `AVAIL_THEMES` list in [`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py) so it appears in the user interface dropdown:

```python

# config.py (around line 90)

AVAIL_THEMES = [
    "Default",
    "Chuanhu-Small-and-Beautiful", 
    "High-Contrast",
    "Gstaff/Xkcd",
    "NoCrypt/Miku",
    "MyCustomTheme",  # ← Your new theme

]

# Optionally set as default

THEME = "MyCustomTheme"

```

### Step 3: Wire the Theme Loader

Update the `load_dynamic_theme()` function in [`themes/theme.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/theme.py) to import your module when the theme name matches:

```python

# themes/theme.py - inside load_dynamic_theme()

elif THEME == "MyCustomTheme":
    from .mytheme import adjust_theme, advanced_css
    theme_declaration = ""  # Optional HTML banner

```

### Step 4: Add an Optional Banner

To display a custom header when your theme is active, set the `theme_declaration` variable in the same code block:

```python
theme_declaration = '<h2 align="center" class="small">My Custom Theme</h2>'

```

### Step 5: Restart the Application

Execute `python main.py` to reload the configuration. Your custom theme will now appear in the dropdown menu and apply your defined colors, fonts, and CSS rules when selected.

## Key Source Files and Implementation Details

- **[`themes/theme.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/theme.py)**: Central dispatcher containing `load_dynamic_theme()` that routes theme names to their respective modules based on the `THEME` configuration variable.
- **[`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py)**: Defines `AVAIL_THEMES` (the list populating the UI dropdown) and the default `THEME` variable read at startup.
- **[`themes/gui_toolbar.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/gui_toolbar.py)**: Builds the theme selection interface using the `AVAIL_THEMES` configuration.
- **[`themes/common.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/common.py)**: Provides `get_common_html_javascript_code()`, a utility function that returns the shared JavaScript required for core GPT Academic functionality.
- **[`themes/default.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/default.py)**, **[`themes/green.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/green.py)**: Reference implementations demonstrating standard theme structures.

## Summary

- **Create a module** in `themes/` implementing `adjust_theme()` returning a `gr.themes.*` object and exposing `advanced_css`.
- **Register the name** in [`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py)'s `AVAIL_THEMES` list to make it selectable in the UI.
- **Update the dispatcher** in [`themes/theme.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/theme.py) to import your module when the theme name matches.
- **Inject common JavaScript** via `get_common_html_javascript_code()` to ensure compatibility with GPT Academic's core features.
- **Restart the server** to load the new configuration and make the theme available to users.

## Frequently Asked Questions

### Where is the theme configuration stored in GPT Academic?

The active theme is controlled by the `THEME` variable defined in [`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py) (line 93), while the available options are listed in the `AVAIL_THEMES` array. The UI dropdown is constructed from this array in [`themes/gui_toolbar.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/gui_toolbar.py).

### What functions must a custom theme module implement?

Every theme module must expose an `adjust_theme()` function that returns a Gradio theme instance and an `advanced_css` string variable containing CSS rules. The `adjust_theme()` function should also inject required JavaScript using the pattern shown in [`themes/common.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/common.py).

### Can I use custom CSS and JavaScript in my theme?

Yes. Store CSS in a separate file (e.g., [`mytheme.css`](https://github.com/binary-husky/gpt_academic/blob/main/mytheme.css)) and load it into the `advanced_css` variable. For JavaScript, use the `get_common_html_javascript_code()` utility from [`themes/common.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/common.py) and inject it by wrapping `gr.routes.templates.TemplateResponse` as demonstrated in existing theme implementations.

### Why doesn't my new theme appear in the dropdown menu?

If your theme is missing from the dropdown, verify that you added the exact name to `AVAIL_THEMES` in [`config.py`](https://github.com/binary-husky/gpt_academic/blob/main/config.py) and included the corresponding `elif` branch in [`themes/theme.py`](https://github.com/binary-husky/gpt_academic/blob/main/themes/theme.py)'s `load_dynamic_theme()` function. Both steps are required for the theme to be recognized and displayed.