# Ventoy Menu Class and Menu Alias Plugins: Customizing Boot Entries Without Rebuilding ISOs

> Discover Ventoy menu class and menu alias plugins to categorize ISOs and rename boot entries dynamically. Customize your boot menu without rebuilding USB images easily.

- Repository: [longpanda/Ventoy](https://github.com/ventoy/Ventoy)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Ventoy's menu class and menu alias plugins let you categorize ISO files and rename menu entries dynamically by parsing JSON rules at boot time, eliminating the need to rebuild the USB image.**

The ventoy/Ventoy repository provides a lightweight plugin system that reads [`ventoy.json`](https://github.com/ventoy/Ventoy/blob/main/ventoy.json) from the boot partition to customize the GRUB-based menu. These two plugins attach **CSS-style classification tags** and **human-readable display names** to files or directories, enabling conditional theming and clearer navigation without touching the ISO files themselves.

## Architecture of the Menu Class and Menu Alias System

Ventoy implements these features as linked-list structures populated during plugin loading and queried while enumerating ISO files. The implementation resides entirely within the GRUB2 module source under `GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/`.

### Data Structures in ventoy_def.h

The core definitions live in [`ventoy_def.h`](https://github.com/ventoy/Ventoy/blob/main/ventoy_def.h).

**menu_class struct** (lines 993–1002): Stores a `type` field (file or directory), a `pattern` string supporting wildcards, a `parent` flag indicating whether to match the parent directory path, and the `class` string itself that will be attached to matching entries.

**menu_alias struct** (lines 66–74): Stores a `type` (image or directory), the exact `isopath` of the entry, and the `alias` string that replaces the displayed name in the boot menu.

### Plugin Initialization Functions

When Ventoy loads [`ventoy.json`](https://github.com/ventoy/Ventoy/blob/main/ventoy.json), specialized parsers build linked lists in memory.

**ventoy_plugin_menuclass_entry()** (lines 1833–1909 in [`ventoy_plugin.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_plugin.c)): Parses the `menu_class` JSON array, constructs `menu_class` nodes, and rebuilds the `g_menu_class_head` linked list, freeing any previous configuration.

**ventoy_plugin_menualias_entry()** (lines 1449–1506 in [`ventoy_plugin.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_plugin.c)): Performs the same operation for the `menu_alias` array, populating `g_menu_alias_head` with `menu_alias` objects.

### Runtime Lookup Functions

During menu construction, Ventoy queries these lists to retrieve metadata for each file.

**ventoy_plugin_get_menu_class()** (lines 2666–2675 in [`ventoy_plugin.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_plugin.c)): Accepts a file type, filename, and full path, returning the matching class string or NULL.

**ventoy_plugin_get_menu_alias()** (lines 2820–2839 in [`ventoy_plugin.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_plugin.c)): Accepts a type and exact path, returning the alias string if defined.

### Data Flow During Boot

1. **Plugin Load**: `ventoy_cmd_load_plugin` reads [`/ventoy/ventoy.json`](https://github.com/ventoy/Ventoy/blob/main//ventoy/ventoy.json) from the boot partition.
2. **List Construction**: The JSON parser invokes `ventoy_plugin_menuclass_entry` and `ventoy_plugin_menualias_entry` to populate static globals `g_menu_class_head` and `g_menu_alias_head`.
3. **Enumeration**: As GRUB discovers ISO files, [`ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_cmd.c) calls the lookup functions to determine `img->class` and `img->alias`.
4. **Rendering**: The bootloader exports these values as environment variables for themes and scripts.

## Configuring Menu Classes and Aliases in ventoy.json

You define these plugins in the root of your Ventoy partition inside the [`ventoy.json`](https://github.com/ventoy/Ventoy/blob/main/ventoy.json) file. No recompilation or ISO rebuilding is required.

### Defining CSS-Style Classes for Theming

Use the `menu_class` array to attach classification tags based on filename patterns or directory location:

```json
{
  "menu_class": [
    { "key": ".iso", "class": "iso" },
    { "parent": "/linux", "class": "linux_dir" },
    { "dir": "windows", "class": "win_dir" }
  ]
}

```

- **key**: Matches a substring or suffix in the filename (e.g., ".iso").
- **parent**: Matches the parent directory path; applies the class to all entries within.
- **dir**: Matches an exact directory name.
- **class**: An arbitrary string consumed by themes (e.g., "ubuntu", "red", "custom").

### Creating Human-Readable Display Names

Use the `menu_alias` array to override display names with readable labels:

```json
{
  "menu_alias": [
    { "image": "/ubuntu-20.04.iso", "alias": "Ubuntu 20.04 LTS" },
    { "dir": "/tools", "alias": "Utility Tools" }
  ]
}

```

- **image**: Absolute path to a specific ISO or IMG file (must start with `/`).
- **dir**: Absolute path to a directory.
- **alias**: The string displayed in the boot menu instead of the raw filename.

## Consuming Plugin Data in Custom GRUB Themes

Ventoy exposes the plugin data as environment variables that custom [`grub.cfg`](https://github.com/ventoy/Ventoy/blob/main/grub.cfg) files or themes can reference.

### Accessing VTOY_MENU_CLASS for Conditional Theming

Themes can switch layouts or icons based on the class assigned to the current entry. Ventoy sets `VTOY_MENU_CLASS` immediately before displaying each menu item (see [`ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_cmd.c) lines 2137–2148).

```grub

# In grub.cfg

if [ "$VTOY_MENU_CLASS" = "linux_dir" ]; then
    set theme=/boot/theme-linux.cfg
elif [ "$VTOY_MENU_CLASS" = "win_dir" ]; then
    set theme=/boot/theme-windows.cfg
fi

```

### Displaying VTOY_MENU_ALIAS Instead of File Names

Replace the default filename display with the friendly alias using the `VTOY_MENU_ALIAS` variable. If no alias exists, Ventoy automatically falls back to the original filename.

```grub

# theme.cfg

menuentry "${VTOY_MENU_ALIAS}" --class $VTOY_MENU_CLASS {
    chainloader /ventoy/ventoy.chain
}

```

## Implementation Details from the Ventoy Source Code

The integration between JSON parsing and menu rendering occurs in three critical files.

### The Linked List Implementation

Both plugins use global head pointers to store configuration in memory:

- `g_menu_class_head`: Tracks active menu class rules.
- `g_menu_alias_head`: Tracks active alias mappings.

These globals are defined and manipulated in [`ventoy_plugin.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_plugin.c), where the entry functions allocate nodes with `grub_zalloc` and insert them at the list head.

### Integration Point in ventoy_cmd.c

The actual assignment of class and alias data happens in [`ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_cmd.c) at lines 2137–2148. For each discovered image, the code executes:

```c
img->class = ventoy_plugin_get_menu_class(vtoy_class_image_file, 
                                          img->name, 
                                          img->path);

img->alias = ventoy_plugin_get_menu_alias(vtoy_alias_image_file, 
                                          img->path);

```

These values are later exported to the GRUB environment before the menu entry is rendered.

### Key Source Files for Reference

- **[`GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h`](https://github.com/ventoy/Ventoy/blob/main/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h)**: Contains `menu_class` and `menu_alias` structure definitions at lines 993–1002 and 66–74.
- **[`GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c`](https://github.com/ventoy/Ventoy/blob/main/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c)**: Implements JSON parsing, list construction, and lookup helpers.
- **[`GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c)**: Applies plugin data to menu entries during enumeration at lines 2137–2148.
- **[`Plugson/src/Web/ventoy_http.c`](https://github.com/ventoy/Ventoy/blob/main/Plugson/src/Web/ventoy_http.c)**: Provides web UI endpoints for managing these plugins via the Ventoy Plugson interface.

## Summary

- **Menu class** and **menu alias** plugins read rules from [`ventoy.json`](https://github.com/ventoy/Ventoy/blob/main/ventoy.json) at boot time without requiring ISO rebuilds.
- The system uses linked lists (`g_menu_class_head`, `g_menu_alias_head`) defined in [`ventoy_def.h`](https://github.com/ventoy/Ventoy/blob/main/ventoy_def.h) and populated by `ventoy_plugin_menuclass_entry` and `ventoy_plugin_menualias_entry`.
- Runtime lookups occur via `ventoy_plugin_get_menu_class` and `ventoy_plugin_get_menu_alias`, called from [`ventoy_cmd.c`](https://github.com/ventoy/Ventoy/blob/main/ventoy_cmd.c) during menu enumeration.
- Configuration supports pattern matching on filenames (`key`), parent directories (`parent`), and exact paths (`dir` or `image`).
- Custom themes access this data through the `VTOY_MENU_CLASS` and `VTOY_MENU_ALIAS` environment variables.

## Frequently Asked Questions

### How do I apply a class to all files in a specific directory?

Use the `parent` key in your `menu_class` entry. Set the value to the absolute directory path (e.g., `/linux`), and Ventoy will attach the specified class to every entry within that directory according to the logic in `ventoy_plugin_get_menu_class` at lines 2666–2675.

### Can I use wildcards in menu alias definitions?

No. The `menu_alias` plugin requires an exact `isopath` match as defined in the `menu_alias` struct at lines 66–74 of [`ventoy_def.h`](https://github.com/ventoy/Ventoy/blob/main/ventoy_def.h). Aliases use strict string comparison against the full path, unlike menu classes which support substring matching via the `key` field.

### What happens if both a directory alias and individual image aliases exist for the same path?

Ventoy checks for aliases at the individual entry level. The lookup function `ventoy_plugin_get_menu_alias` (lines 2820–2839) searches the `g_menu_alias_head` list for an exact path match. If an image-specific alias exists, it takes precedence; otherwise, the directory alias applies if configured.

### Do I need to restart Ventoy after editing ventoy.json?

Yes. The JSON file is parsed once during the initial plugin load phase when `ventoy_cmd_load_plugin` executes. Changes require a reboot to trigger re-parsing by `ventoy_plugin_menuclass_entry` and `ventoy_plugin_menualias_entry`, which rebuild the linked lists from scratch.