Ventoy Menu Class and Menu Alias Plugins: Customizing Boot Entries Without Rebuilding ISOs
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 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.
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, specialized parsers build linked lists in memory.
ventoy_plugin_menuclass_entry() (lines 1833–1909 in 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): 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): 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): Accepts a type and exact path, returning the alias string if defined.
Data Flow During Boot
- Plugin Load:
ventoy_cmd_load_pluginreads/ventoy/ventoy.jsonfrom the boot partition. - List Construction: The JSON parser invokes
ventoy_plugin_menuclass_entryandventoy_plugin_menualias_entryto populate static globalsg_menu_class_headandg_menu_alias_head. - Enumeration: As GRUB discovers ISO files,
ventoy_cmd.ccalls the lookup functions to determineimg->classandimg->alias. - 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 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:
{
"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:
{
"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 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 lines 2137–2148).
# 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.
# 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, 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 at lines 2137–2148. For each discovered image, the code executes:
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: Containsmenu_classandmenu_aliasstructure definitions at lines 993–1002 and 66–74.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: Applies plugin data to menu entries during enumeration at lines 2137–2148.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.jsonat boot time without requiring ISO rebuilds. - The system uses linked lists (
g_menu_class_head,g_menu_alias_head) defined inventoy_def.hand populated byventoy_plugin_menuclass_entryandventoy_plugin_menualias_entry. - Runtime lookups occur via
ventoy_plugin_get_menu_classandventoy_plugin_get_menu_alias, called fromventoy_cmd.cduring menu enumeration. - Configuration supports pattern matching on filenames (
key), parent directories (parent), and exact paths (dirorimage). - Custom themes access this data through the
VTOY_MENU_CLASSandVTOY_MENU_ALIASenvironment 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. 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →