Hidden gadgets do not have associated user preferences and are only meant to be loaded as dependencies by other gadgets or user scripts.
However, mw.user.options on every page load, even for non-signed-in users, contains the preferences apparently associated to them.
Steps to reproduce
Run in the JS console:
let json = await $.getJSON('/w/api.php?action=query&format=json&list=gadgets&gaprop=id%7Cmetadata&formatversion=2'); let hiddenGadgets = json.query.gadgets.filter(g => g.metadata.settings.hidden).map(g => g.id); hiddenGadgets.forEach(g => console.log(mw.user.options.get('gadget-' + g)));
Expected result
undefined printed on console (22 times on enwiki as it has 22 hidden gadgets)
Actual result
0 printed on console 22 times
These options can't be changed. Running new mw.Api().saveOption('gadget-morebits', 1) and reloading the page still causes mw.user.options.get('gadget-morebits') to give 0.
They add page load costs and don't seem useful in any way. If some js wanted to find out whether a gadget exists (which seems like the only possible usecase) it could use mw.loader.moduleRegistry instead.