Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Workflow for splitting an existing SettingRegistration into a SettingDescriptor (placed in the lowest layer where used: core/, models/, or ui/settings/) and SettingUIDescriptor (registered in a higher-level -meta.ts file, outside of core/ and models/).
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 117% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 97% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 151% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 56% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 168% | 0% |
This skill guide describes how to migrate an existing legacy SettingRegistration in DevTools by splitting it into a SettingDescriptor (non-UI descriptor) and a SettingUIDescriptor (UI descriptor).
SettingDescriptor Location ("Lowest Layer")SettingDescriptor MUST be placed in the lowest architectural layer where the setting is used.core/sdk (or models/), its SettingDescriptor should be located in core/sdk (or models/).panels/console/), its SettingDescriptor MUST GO INTO ui/settings/FooSettings.ts (e.g. ui/settings/ConsoleSettings.ts where Foo is the panel name).panels/:SettingDescriptor MUST NOT be placed inside a panels/ directory (e.g. panels/console/ConsoleSettings.ts).-meta.ts files (e.g. panels/console/console-meta.ts) need to import the SettingDescriptor to call SettingsUI.SettingUIRegistration.register(descriptor, uiDescriptor). -meta.ts files are loaded early and MUST NOT import from panels/ (which would break lazy-loading of panel bundles). Since ui/settings/ is in the ui/ layer below panels/, -meta.ts files can safely import from ui/settings/.-meta.ts FILE:SettingDescriptor MUST NOT be placed in a -meta.ts file.Settings.instance().resolve(descriptor). Preload -meta.ts files are meant for lazy-loaded extension registrations and must not be imported by runtime code to avoid circular dependencies and module boundary violations.SettingUIDescriptor Location (Higher-Level -meta.ts File)SettingUIDescriptor defines UI-specific properties (category, title, tags, options, reload requirement, etc.).-meta.ts FILE ON A HIGHER LEVEL (e.g., entrypoints/main/main-meta.ts, entrypoints/inspector_main/inspector_main-meta.ts, panels/settings/settings-meta.ts, or the specific panel's -meta.ts file).core/ OR models/:-meta.ts files under core/ or models/ (such as core/sdk/sdk-meta.ts or models/*/*-meta.ts).-meta.ts files in core/ and models/.moduleSetting(name)Settings.instance().moduleSetting('setting-name').moduleSetting('setting-name') with Settings.instance().resolve(settingDescriptor).Given a setting name (e.g., 'preserve-console-log' or 'network-messages'):
-meta.ts files to find its Common.Settings.registerSettingExtension block.'setting-name' or moduleSetting('setting-name') across the codebase to identify all use-sites.core/sdk -> Target directory is core/sdk/.models/ -> Target directory is models/<module>/.panels/foo) or UI -> Target directory is ui/settings/ (file: ui/settings/FooSettings.ts). NEVER place descriptors in panels/.SettingDescriptor in the Lowest LayerWhen placing a SettingDescriptor in the target directory, decide whether to create or update a file using these rules:
ui/settings/):ui/settings/FooSettings.ts already exists (e.g., ui/settings/ConsoleSettings.ts). If so, add and export the SettingDescriptor there.ui/settings/FooSettings.ts does not exist:ui/settings/FooSettings.ts.FooSettings.ts to sources in ui/settings/BUILD.gn.FooSettings.ts from ui/settings/settings.ts.core/ or models/):core/sdk/SDKSettings.ts, models/workspace/WorkspaceSettings.ts). If so, add and export the SettingDescriptor there.ResourceTreeModel.ts), update that .ts file by exporting the SettingDescriptor at the top.<Module>Settings.ts (e.g., core/sdk/SDKSettings.ts), add it to sources in BUILD.gn, and export it from the module's entrypoint (sdk.ts).Define and export the SettingDescriptor in the target file:
typescriptimport type * as Common from '../core/common/common.js'; export const preserveConsoleLogSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = { name: 'preserve-console-log', type: Common.Settings.SettingType.BOOLEAN, defaultValue: false, storageType: Common.Settings.SettingStorageType.SYNCED, };
Note: For conditional settings (dependent on hostConfig), use Common.Settings.ConditionalSettingDescriptor<ValueT, ReasonT> with an isAvailable function.
-meta.ts FileIf the original registration was in a core/ or models/ -meta.ts file (e.g., core/sdk/sdk-meta.ts), MOVE the UI registration to a higher-level -meta.ts file (e.g., entrypoints/main/main-meta.ts or panels/console/console-meta.ts).
In the higher-level -meta.ts file:
SettingsUI from ui/settings/settings.js (e.g., import * as SettingsUI from '../../ui/settings/settings.js';).SettingDescriptor (from core/sdk/, models/, or ui/settings/).SettingsUI.SettingUIRegistration.register(...):typescriptimport * as SettingsUI from '../../ui/settings/settings.js'; import * as SDK from '../../core/sdk/sdk.js'; SettingsUI.SettingUIRegistration.register(SDK.SDKSettings.preserveConsoleLogSettingDescriptor, { category: Common.Settings.SettingCategory.CONSOLE, title: i18nLazyString(UIStrings.preserveLogUponNavigation), options: [ { value: true, title: i18nLazyString(UIStrings.preserveLogUponNavigation), }, { value: false, title: i18nLazyString(UIStrings.doNotPreserveLogUponNavigation), }, ], });
Common.Settings.registerSettingExtension call from the core/ or models/ -meta.ts file. (If the -meta.ts file becomes empty, delete the file and clean up its build references).moduleSetting to resolve)Find all call sites referencing the setting via moduleSetting:
typescript// BEFORE: const setting = Common.Settings.Settings.instance().moduleSetting('preserve-console-log'); // AFTER: import { preserveConsoleLogSettingDescriptor } from './SDKSettings.js'; ... const setting = Common.Settings.Settings.instance().resolve(preserveConsoleLogSettingDescriptor);
For conditional settings, use Common.Settings.Settings.instance().maybeResolve(descriptor) instead of resolve(descriptor).
BUILD.gn Files and Module Entrypoints.ts file was created (e.g., SDKSettings.ts or ui/settings/ConsoleSettings.ts):sources in its module's BUILD.gn.sdk.ts, settings.ts, etc.).core/ or models/ -meta.ts file was deleted, remove it from BUILD.gn and devtools_grd_files.gni.devtools-imports skill).autoninja -C out/Default to check GN build.npm run lint to check style and formatting rules.preserve-console-log)Setting registered in front_end/core/sdk/sdk-meta.ts (Legacy core meta file):
typescriptCommon.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.CONSOLE, storageType: Common.Settings.SettingStorageType.SYNCED, title: i18nLazyString(UIStrings.preserveLogUponNavigation), settingName: 'preserve-console-log', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: false, options: [...], });
Setting used in front_end/core/sdk/ResourceTreeModel.ts:
typescriptconst setting = Common.Settings.Settings.instance().moduleSetting('preserve-console-log');
front_end/core/sdk/SDKSettings.ts (Lowest Layer in Core — NOT a `-meta.ts` file):typescriptimport type * as Common from '../common/common.js'; export const preserveConsoleLogSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = { name: 'preserve-console-log', type: Common.Settings.SettingType.BOOLEAN, defaultValue: false, storageType: Common.Settings.SettingStorageType.SYNCED, };
front_end/entrypoints/main/main-meta.ts (Higher-Level Meta File — NOT in `core/` or `models/`):typescriptimport * as SDK from '../../core/sdk/sdk.js'; import * as SettingsUI from '../../ui/settings/settings.js'; SettingsUI.SettingUIRegistration.register(SDK.SDKSettings.preserveConsoleLogSettingDescriptor, { category: Common.Settings.SettingCategory.CONSOLE, title: i18nLazyString(UIStrings.preserveLogUponNavigation), options: [...], });
front_end/core/sdk/ResourceTreeModel.ts (Call Site in `core/sdk`):typescriptimport { preserveConsoleLogSettingDescriptor } from './SDKSettings.js'; const setting = Common.Settings.Settings.instance().resolve(preserveConsoleLogSettingDescriptor);
front_end/core/sdk/sdk-meta.ts:Registration for 'preserve-console-log' removed.
network-messages)Setting registered in front_end/panels/console/console-meta.ts:
typescriptCommon.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.CONSOLE, storageType: Common.Settings.SettingStorageType.SYNCED, title: i18nLazyString(UIStrings.networkMessages), settingName: 'network-messages', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: true, options: [...], });
Setting used in front_end/panels/console/ConsoleView.ts:
typescriptconst setting = Common.Settings.Settings.instance().moduleSetting('network-messages');
front_end/ui/settings/ConsoleSettings.ts (Lowest Layer for UI/Panel Descriptor — NOT in `panels/console/`!):typescriptimport type * as Common from '../../core/common/common.js'; export const networkMessagesSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = { name: 'network-messages', type: Common.Settings.SettingType.BOOLEAN, defaultValue: true, storageType: Common.Settings.SettingStorageType.SYNCED, };
front_end/panels/console/console-meta.ts (Panel Meta File — Imports Descriptor from `ui/settings/`):typescriptimport * as SettingsUI from '../../ui/settings/settings.js'; SettingsUI.SettingUIRegistration.register(SettingsUI.ConsoleSettings.networkMessagesSettingDescriptor, { category: Common.Settings.SettingCategory.CONSOLE, title: i18nLazyString(UIStrings.networkMessages), options: [...], });
front_end/panels/console/ConsoleView.ts (Call Site in `panels/console`):typescriptimport * as SettingsUI from '../../ui/settings/settings.js'; const setting = Common.Settings.Settings.instance().resolve(SettingsUI.ConsoleSettings.networkMessagesSettingDescriptor);
SettingDescriptor<T>Defined in core/common/Settings.ts:
name: string: Unique setting name (kebab-case).type: SettingType: BOOLEAN, ENUM, ARRAY, or REGEX.defaultValue: ValueT | ((hostConfig: HostConfig) => ValueT): Default setting value.storageType?: SettingStorageType: SYNCED, LOCAL, GLOBAL, or SESSION.SettingUIDescriptorDefined in ui/settings/SettingUIRegistration.ts:
category?: SettingCategory: Category under which setting is listed in Settings UI.order?: number: Sorting order.title?: () => LocalizedString: Title string displayed in Settings UI.tags?: Array<() => LocalizedString>: Search tags for Command Menu.options?: SettingExtensionOption[]: Enum / boolean option descriptions.reloadRequired?: boolean: Whether setting change requires DevTools reload.deprecationNotice?: { disabled: boolean, warning: () => LocalizedString, experiment?: string }: Deprecation notice.learnMore?: LearnMore: Help link or tooltip info.Other measured skills in the registry, with their headline benchmark lift.