From ui5-modernization
Fixes Library.init() apiVersion issues and modernizes enum definitions to DataType.registerEnum in UI5 library.js files.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ui5-modernization:fix-library-initThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill fixes `Library.init()` / `Lib.init()` calls that the UI5 linter detects as missing `apiVersion: 2`, and modernizes enum definitions to use `DataType.registerEnum` — which is required when using `apiVersion: 2`.
This skill fixes Library.init() / Lib.init() calls that the UI5 linter detects as missing apiVersion: 2, and modernizes enum definitions to use DataType.registerEnum — which is required when using apiVersion: 2.
| Rule ID | Message Pattern | This Skill's Action |
|---|---|---|
no-deprecated-api | Deprecated call to Library.init(). Use the {apiVersion: 2} parameter instead | Add apiVersion: 2 to the init call |
no-deprecated-api | Deprecated call to Lib.init(). Use the {apiVersion: 2} parameter instead | Add apiVersion: 2 to the init call |
no-deprecated-api | Deprecated call to init(). Use the {apiVersion: 2} parameter instead | Add apiVersion: 2 (destructured init) |
Apply this skill when you see linter output like:
library.js:9:2 error Deprecated call to Library.init(). Use the {apiVersion: 2} parameter instead no-deprecated-api
library.js:11:2 error Deprecated call to Lib.init(). Use the {apiVersion: 2} parameter instead no-deprecated-api
library.js:51:2 error Deprecated call to init(). Use the {apiVersion: 2} parameter instead no-deprecated-api
sap/ui/core/Lib.init() registers a UI5 library with the framework, declaring its metadata: name, dependencies, controls, elements, types (enums), and interfaces. The apiVersion: 2 parameter signals that the library uses the modern initialization pattern.
Important: Only apiVersion: 2 is valid for Lib.init(). Unlike control renderers where apiVersion: 4 is also valid, library initialization only accepts 2.
Problem: Lib.init() called with no arguments at all.
// Before — triggers no-deprecated-api
sap.ui.define([
"sap/ui/core/Lib"
], function(Library) {
"use strict";
Library.init();
});
Fix: Add an object argument with apiVersion: 2.
// After
sap.ui.define([
"sap/ui/core/Lib"
], function(Library) {
"use strict";
Library.init({
apiVersion: 2
});
});
Problem: Lib.init() receives an object but it has no apiVersion property.
// Before — triggers no-deprecated-api
Library.init({
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"]
});
Fix: Add apiVersion: 2 as the first property in the object.
// After
Library.init({
apiVersion: 2,
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"]
});
Problem: apiVersion is a string instead of a numeric literal.
// Before — triggers no-deprecated-api
Library.init({
apiVersion: "2"
});
Fix: Change to numeric literal 2.
// After
Library.init({
apiVersion: 2
});
Problem: apiVersion is a number but not 2.
// Before — triggers no-deprecated-api
Library.init({
apiVersion: 1
});
Fix: Change to 2.
// After
Library.init({
apiVersion: 2
});
The same patterns apply when init is called via bracket notation:
// Before
Library["init"]({
apiVersion: 1,
dependencies: ["sap.ui.core"]
});
// After
Library["init"]({
apiVersion: 2,
dependencies: ["sap.ui.core"]
});
The linter also detects these patterns:
// Assignment
const LibInit = Library.init;
LibInit({ apiVersion: 1 });
// Destructuring
const {init} = Library;
init({ apiVersion: 1 });
// Destructuring with rename
const {init: libInit} = Library;
libInit({ apiVersion: 1 });
Fix: Same — change apiVersion to 2 in each call.
When upgrading Lib.init() to apiVersion: 2, the old approach of defining enums on the global namespace no longer works. The framework cannot resolve type strings used in control metadata without explicit registration, which can lead to XSS vulnerabilities because type checking is silently skipped.
This skill must find existing enum definitions in the library.js and modernize them to use DataType.registerEnum.
types array in the Lib.init() call — it lists the fully qualified names of all types (enums) defined by the librarymy.lib.ValueColor = { ... } where my.lib is the library namespaceCapture the return value of Lib.init() in a variable if not already done:
// Before
Library.init({ name: "my.lib", apiVersion: 2, types: ["my.lib.ValueColor"] });
// After
var oThisLibrary = Library.init({ name: "my.lib", apiVersion: 2, types: ["my.lib.ValueColor"] });
Move enum definitions from the global namespace to the library object:
// Before — global namespace
my.lib.ValueColor = { Color1: "Color1", Color2: "Color2" };
// After — on library object
oThisLibrary.ValueColor = { Color1: "Color1", Color2: "Color2" };
Add DataType.registerEnum call immediately after each enum definition:
oThisLibrary.ValueColor = { Color1: "Color1", Color2: "Color2" };
DataType.registerEnum("my.lib.ValueColor", oThisLibrary.ValueColor);
Add sap/ui/base/DataType to the sap.ui.define dependency list if not already present:
sap.ui.define([
"sap/ui/base/DataType", // Add this
"sap/ui/core/Lib"
], function(DataType, Library) {
registerEnum must exactly match the string used as type in control metadata (e.g. "my.lib.ValueColor")library.js for library preload compatibilitytypes array needs its own registerEnum call/*!
* ${copyright}
*/
sap.ui.define([
"sap/ui/core/Lib"
], function(Library) {
"use strict";
Library.init({
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"],
types: [
"my.lib.ValueColor",
"my.lib.StatusType"
],
controls: [
"my.lib.MyControl"
]
});
// Enums defined on global namespace
my.lib.ValueColor = {
Good: "Good",
Critical: "Critical",
Error: "Error",
Neutral: "Neutral"
};
my.lib.StatusType = {
Active: "Active",
Inactive: "Inactive"
};
});
/*!
* ${copyright}
*/
sap.ui.define([
"sap/ui/base/DataType",
"sap/ui/core/Lib"
], function(DataType, Library) {
"use strict";
var oThisLibrary = Library.init({
apiVersion: 2,
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"],
types: [
"my.lib.ValueColor",
"my.lib.StatusType"
],
controls: [
"my.lib.MyControl"
]
});
oThisLibrary.ValueColor = {
Good: "Good",
Critical: "Critical",
Error: "Error",
Neutral: "Neutral"
};
DataType.registerEnum("my.lib.ValueColor", oThisLibrary.ValueColor);
oThisLibrary.StatusType = {
Active: "Active",
Inactive: "Inactive"
};
DataType.registerEnum("my.lib.StatusType", oThisLibrary.StatusType);
return oThisLibrary;
});
Run linter with --details to get additional context:
npx @ui5/linter --details
Read the library.js file and identify:
Lib.init() / Library.init() call and its current argumentstypes array and global namespace assignments)Fix the apiVersion:
{ apiVersion: 2 }apiVersion: 2 as the first property2Modernize enums (if any exist):
Lib.init() return value in a variable if not already doneDataType.registerEnum call for each enumsap/ui/base/DataType to the dependency listEnsure the module returns the library object (return oThisLibrary;)
Verify the fix by re-running the linter
apiVersion: 2 is valid for Lib.init() — apiVersion: 4 is NOT valid (that is for renderers only)apiVersion must be a numeric literal, not a stringapiVersion: 2 fix (no DataType.registerEnum needed)types array in the init call is your guide to which enums need registerEnum callsapiVersion issues (missing apiVersion: 2 or 4 in renderer objects) — different from library init apiVersionsap.ui.require(["my/lib/ValueColor"])), use fix-pseudo-modules to convert them to library module importssap.ui.getCore()), use fix-js-globals for thoseclaude plugin install ui5-modernization@claude-plugins-officialFixes pseudo module access and implicit global issues that UI5 linter detects but cannot auto-fix. Provides guidance on proper module imports for enums, DataTypes, and OData expression addons.
Guides setup, configuration, and usage of @ui5/linter for static analysis of SAPUI5/OpenUI5 apps, detecting deprecated APIs, globals, CSP issues, and manifest problems with autofix and CI/CD integration.
Converts UI5 (SAPUI5/OpenUI5) projects to TypeScript with step-by-step guidance on setup, code conversion, and test migration. Preserves comments, avoids `any`, and uses proper UI5 types.