qlik-extension-nebula-migration
Migrate a Qlik Sense extension to nebula.js
Turns a legacy visualization extension into a nebula.js extension packaged by nebula sense, in a new project folder. The original is never edited in place.
Designed for Qlik Cloud and Qlik Sense client-managed; test in the exact environment you run (references/host-differences.md). The scripts check source and build output statically and never run the extension in a Sense host, so any claim of "works" must come from host testing.
Usage
Ask for a migration in plain words, for example "migrate the extension in ~/ext/ShowHide to nebula.js" or "make a nebula version that can replace the old one". Give the path to the legacy extension folder (the one with the .qext). The skill inventories it, builds a side-by-side nebula project, runs the checks, and ends with a report and a rename recommendation. Follow the Workflow below in order, and stop at the points listed in "Stop and ask".
Rules that always apply
- No host-page APIs or frameworks. The migrated extension uses only
@nebula.js/stardusthooks, thegalaxyargument, and npm packages it bundles itself. Noqlikglobal ordefine(['qlik']), no AngularJS (template,controller,$scope,ng-*), noqvangularor other internal modules, no host jQuery/underscore throughrequire, no.qv-*orlui-*classes, no DOM or CSS outside the extension's own element. The only host objects allowed aregalaxy.anything.sense.themeand.navigation, guarded so the extension still renders without them,galaxy.hostConfigwhen present, plus a guarded fallback tohandler.appin property-panel callbacks. Calls to Qlik Cloud services other than the engine (users, spaces, items, automations, reloads) go through a bundled@qlik/api, not hand-written requests:references/service-calls.md. Details and replacements:references/host-isolation.md. - Side-by-side name first. Build and install the new extension under the original id plus
-nebula(derive it withscripts/nebula-id.mjs; for exampleWordCloudbecomesword-cloud-nebula) so old and new can be compared on the same tenant. The final step is to recommend renaming to the original name, so existing charts pick up the new code (silent drop-in), unlessscripts/check-compat.mjsshows property names, the data path or limits changed, or the drop-in otherwise cannot work. In that case keep the side-by-side name and say why. Seereferences/compatibility-and-rename.md. - Preserve behavior and saved data. Keep every property name and path,
supportflags, data limits, and selection behavior (instant vs modal) unless the user asks for a change. Read a property that old saved objects lack the way the legacy code treated it (often its own default); any other default is a change. Every change goes in the report. - Report what ran. Never write "compatible", "works" or "verified" for something you did not run in a host; write "no blocking difference found by static checks". Mark inferred mappings (tag
Iinreferences/api-mapping.md) as inferred. Limits, versions and statements about what Qlik Cloud supports are dated: where a reference gives one, confirm it on the linked Qlik page before relying on it (references/sources.md, "Facts that go stale"). - Ask before side effects.
npx,npm installand any upload to a tenant (POST /api/v1/extensions,qlik extension create, Management console) need the user's go-ahead. Never upload, delete or replace an extension on a tenant yourself. - Ship everything inside the extension. Bundle libraries (exact versions, lockfile committed) and inline fonts and images (data URIs or SVG); do not load scripts, styles, fonts or data from another origin at run time. Qlik Cloud blocks such a request unless the tenant admin adds a CSP entry, and the extension then fails without an error in the UI. It also keeps code you have not reviewed, from CDNs and other repositories, out of the user's signed-in session. List any origin you cannot avoid, with its directive, in the report (a tenant has only 256 CSP entries and a 6,144-character header, shared by everything on it) (
references/external-resources.md). - No secrets. Do not put tokens, tenant URLs with credentials or personal data in files. The scaffold fills
author(name and email) from git config andnebula sensecopies it into the.qext; show it to the user and set it deliberately.