Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>SN Widget KitNew to Visual Studio Code? Get it now.
SN Widget Kit

SN Widget Kit

Guilherme Maziero

|
7 installs
| (2) | Free
Develop ServiceNow Service Portal widgets in VS Code: live preview, hot reload, IntelliSense from your instance, and safe push guards.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

SN Widget Kit

Develop ServiceNow Service Portal widgets directly from VS Code — with live preview, hot reload, IntelliSense from your own instance, and safe push guards.

A complementary workflow that speeds up widget development: pull a widget into a Git-versionable workspace, edit with real autocomplete, and use an instant local browser preview to iterate on layout and styling fast. It doesn't aim to replace the platform — it gives you a quick build-and-preview loop in the editor, then pushes your changes back safely.


Highlights

  • 🖥️ Local live preview that renders the widget (AngularJS + Bootstrap) and refreshes on save — no browser needed
  • ⚡ Hot reload — CSS swaps in-place (no flicker), template recompiles in Angular, scripts reload automatically
  • 🆕 Create widgets from VS Code — scaffold a new sp_widget and start editing locally, no platform UI needed
  • 🧠 Real IntelliSense — not just gs, GlideRecord, $sp, spUtil, but the Script Includes from YOUR instance, synced automatically
  • 🏃 server.js runs locally in a sandbox: gs, GlideRecord (with dot-walking), GlideAggregate, Script Include execution, and gs.getMessage/${} resolved from your instance
  • 📴 Offline mode — develop with no instance at all, feeding data via a per-widget fixtures.json
  • 🔒 Working Context guard — blocks push when the Update Set is Default or belongs to a different scope
  • 🧬 Conflict detection + visual diff before overwriting
  • 📦 Git-friendly — each widget becomes a folder of files
  • 🚫 No browser extension — everything via the REST API

Requirements

  • Node.js 20+
  • VS Code 1.85+
  • A ServiceNow instance (PDI or dev) you can edit
  • A user with read/write access to sp_widget (and admin or a role with read on sys_script_include for instance IntelliSense)

Installation

  1. In VS Code, open the Extensions tab (Ctrl/Cmd+Shift+X)
  2. Search for SN Widget Kit
  3. Click Install

Then open your widget project folder and run SN Widget: Login to Instance.

Build-from-source instructions are in Development at the bottom.


Basic workflow

Login → Pull widget → Open Live Preview → edit + save (hot reload) → Push
  1. Login: SN Widget: Login to Instance
  2. Pull: SN Widget: Pull Widget → pick from the list → downloads to widgets/<id>/
  3. Preview: SN Widget: Open Live Preview → opens in the browser, connected over WebSocket
  4. Edit: save any file → the preview updates instantly
  5. Push: SN Widget: Push Current Widget (or enable auto-sync)

Each widget is pulled as a folder:

<workspace>/widgets/<widget-id>/
├── template.html       → template field
├── client.js           → client_script field
├── server.js           → script field (server script)
├── styles.scss         → css field (SCSS, compiled in the preview)
├── link.js             → link field
├── option-schema.json  → option_schema field
├── demo-data.json      → demo_data field
└── .widget-meta.json   → metadata (sys_id, scope, timestamp) — not pushed

Command reference

All available in the Command Palette (Ctrl/Cmd+Shift+P), prefix SN Widget.

Connection

Command What it does
Login to Instance Asks for URL, username and password. Validates via sys_user. Password stored in VS Code SecretStorage. Triggers a background Script Include sync
Logout Clears credentials and caches

Pull / Push

Command What it does
Pull Widget Lists instance widgets (QuickPick) and downloads the chosen one to widgets/
Pull All Widgets Downloads all (with progress, cancelable)
Create New Widget Asks for a name + id, creates the sp_widget on the instance, pulls it locally and opens it
Push Current Widget Reads the active editor's widget folder and pushes (PATCH). Runs through the Working Context guard and conflict detection
Toggle Auto-Sync Turns automatic push-on-save on/off

Update Set / Working Context

Command What it does
Show Active Update Set Shows the active Update Set (name, state, ⚠️ if Default)
Select Update Set Lists in progress Update Sets in the widget's scope and sets the chosen one as current (via sys_user_preference)
Working Context Menu Quick menu (triggered from the status bar): select update set, show, toggle auto-sync, login/logout

Preview / Hot Reload

Command What it does
Open Live Preview Starts the local server (if needed) and opens the widget preview in the browser
Start Hot-Reload Server Starts the local HTTP+WebSocket server manually
Stop Hot-Reload Server Stops the server
Copy Portal Hot-Reload Bookmarklet Copies a bookmarklet to the clipboard — paste it in your browser bookmarks to enable hot reload on the real portal
Refresh Portal Assets (CSS/Theme) Re-fetches the portal CSS/theme for 1:1 visual fidelity in the preview
Snapshot Widget Data (for offline) Runs server.js live and saves the resulting data to snapshot.json for offline development

IntelliSense / Types

Command What it does
Reinstall IntelliSense Types Rewrites the ServiceNow API .d.ts (gs, GlideRecord, $sp, ...). Normally installed automatically
Sync Instance Types (Script Includes) Fetches all active Script Includes from the instance and generates .d.ts with declare class per scope
Diagnose Script Include Diagnostic: why didn't a Script Include show up? (active, scope, ACL, parse, presence in the .d.ts)

Quick UI (no Command Palette)

You don't have to live in Ctrl/Cmd+Shift+P:

  • Control Panel: click the SN Widget Kit icon in the Activity Bar (left sidebar) for a panel with connection status, one-click actions (Preview · Push · Create · Pull · Snapshot · Update Set · Sync Types · Login/Logout) and toggles for Auto-Sync, Offline mode and High-fidelity artifacts. This is the main UI.
  • Editor title bar: when you're in a widget file, Open Preview (◐) and Push (☁) icons appear top-right
  • Right-click in the editor: Push Current Widget · Open Live Preview
  • "ServiceNow Widgets" tree: per-widget inline actions — Preview · Push · Re-pull
  • Keyboard shortcuts: Ctrl/Cmd+Alt+U push · Ctrl/Cmd+Alt+P preview (only when focused in a widget file)

Live Preview (local)

Open Live Preview renders the widget on a local page (localhost:<previewPort>), loading AngularJS 1.8 and Bootstrap 3. When you save a file:

Changed file Behavior
styles.scss Compiles SCSS → CSS and swaps the <style> in-place, no flicker
template.html Recompiles the widget in AngularJS (keeps the c controller state)
client.js / server.js / link.js / schemas Page reload

Visual fidelity: if you're logged in, the preview fetches your real portal CSS (proxied via /sn-proxy) — it looks identical to the portal. Without login, it falls back to Bootstrap from a CDN. Enable includePortalScripts to also load sp-angular (opt-in, may conflict).


server.js running locally

The preview executes your Server Script in a Node sandbox, with faithful stubs of the ServiceNow API:

  • gs — getUser() (with getDisplayName, getEmail, getLocation, hasRole, ...), nowDateTime, info/warn/error, addInfoMessage/addErrorMessage, date helpers (beginningOfThisMonth, etc.), getProperty, and 80+ methods
  • GlideRecord — when logged in, runs real queries via the Table API: addQuery, addEncodedQuery, orderBy, get(sysId), getValue, getDisplayValue, and dot-walking (gr.caller_id.name.toString())
  • GlideAggregate — addAggregate('COUNT'|'SUM'|'AVG'|'MIN'|'MAX'), groupBy, orderBy(Desc) (live or from fixtures)
  • Script Includes — new global.MyScriptInclude().method() is loaded on demand from the instance, evaluated and executed
  • gs.getUser() returns your real user (name, email, roles) via the API
  • gs.getMessage(key, args) and ${key} tokens resolve against your instance's sys_ui_message (with {0}/{1} substitution)

gs.addInfoMessage(...) / spUtil.addInfoMessage(...) show up as banners at the top of the preview, just like the portal. There's a logs panel (gs.info/warn/error) in the preview's top bar.

Offline (without login, or with offlineMode on), gs and GlideRecord use stub/fixture data; the widget still renders, but without real data.

Offline development (fixtures.json)

To iterate with no instance connection, drop a fixtures.json in the widget folder and turn on snWidgetKit.offlineMode:

// widgets/<id>/fixtures.json — keyed by table name
{
  "sc_request": [
    { "sys_id": "1", "number": "REQ0010001", "active": "true", "sys_created_on": "2026-05-20 10:00:00" }
  ],
  "sc_req_item": [
    { "sys_id": "a", "request": "1", "short_description": "Adobe Creative Cloud" }
  ]
}

new GlideRecord('sc_request') then iterates these records offline. In offline mode the preview never calls the instance.

Even easier — Snapshot: while logged in, run SN Widget: Snapshot Widget Data. It executes server.js live and saves the resulting data to snapshot.json. With Offline mode on, the preview renders straight from that snapshot (real data, zero instance calls) — no need to hand-write fixtures.

High-fidelity artifacts (opt-in)

Complex widgets that rely on Angular sp_ng_templates, sp_angular_providers or shared dependency CSS can enable snWidgetKit.highFidelityArtifacts. When on (and logged in), the preview fetches those related records and injects them. Off by default, since it runs widget-provided Angular code and adds instance calls.


Hot reload on the real portal (bookmarklet)

To see your changes on the actual portal without a manual refresh:

  1. Copy Portal Hot-Reload Bookmarklet → paste it as a new browser bookmark
  2. Open any Service Portal page and click the bookmark (a "🔌 SN Hot Reload" banner appears)
  3. Edit + push (or auto-sync): CSS swaps in-place, template recompiles, scripts reload

It works because the extension runs a local WebSocket server (bound to 127.0.0.1 only) and the bookmarklet injects a client that listens for push events.


IntelliSense

Installed automatically when you open a workspace with widgets. It generates files under .sn-widget-kit-types/ and configures jsconfig.json:

  • Static API (glide.d.ts, service-portal.d.ts, widget-globals.d.ts): gs, GlideRecord, GlideAggregate, GlideDateTime, GlideAjax, GlideUser, $sp, spUtil, spModal, i18n, $scope, c, data, options, input
  • From your instance (instance-script-includes.d.ts): all active Script Includes become declare class per scope → new global.YourScript() autocompletes with the real methods

Automatic Script Include sync: runs on login, re-checks when you focus the VS Code window (throttled) or periodically (fallback, configurable). Cheap watermark-based detection — it only re-syncs when something changes on the instance.


Working Context guard

Before every push, the extension resolves your active Update Set and compares it with the widget's scope. The push is blocked when:

  • The active Update Set is Default, or
  • The Update Set's scope differs from the widget's scope

The block message includes a "Select Update Set" button. The status bar (bottom-left) shows instance · scope · update set and turns red when there's risk.

Configurable via enforceWorkingContext (default true; false = warn only).


Conflict detection + visual diff

If the widget changed on the instance between your pull and push, you get a warning with:

  • Show Diff — opens vscode.diff (remote ↔ local) for each differing file
  • Overwrite — pushes anyway
  • Cancel — aborts

Nothing is overwritten silently.


Configuration

In your workspace .vscode/settings.json (or user settings):

Setting Default Description
snWidgetKit.workspaceFolder "widgets" Folder where widgets are stored locally
snWidgetKit.autoSync false Automatically push changes on save
snWidgetKit.autoSyncDebounceMs 500 Auto-sync debounce (ms)
snWidgetKit.confirmOnConflict true Ask for confirmation when the remote changed since pull
snWidgetKit.warnOnDefaultUpdateSet true Warn when pushing to the Default Update Set
snWidgetKit.enforceWorkingContext true Block push if Update Set = Default or scope differs. false = warn only
snWidgetKit.previewPort 7890 Local preview/hot-reload server port
snWidgetKit.hotReloadOnPush true Broadcast hot-reload to connected portal sessions after push
snWidgetKit.includePortalScripts false Include portal JS (sp-angular) in the preview. Opt-in; may conflict
snWidgetKit.offlineMode false Develop without the instance: use fixtures.json / demo-data.json instead of live data
snWidgetKit.highFidelityArtifacts false Fetch and inject the widget's Angular ng-templates, providers and dependency CSS into the preview
snWidgetKit.highFidelityServer false Run server.js on the instance (Scripted REST) for 100% server-side fidelity; falls back to the local sandbox
snWidgetKit.remoteEvalPath "" Path of the remote-eval Scripted REST resource (e.g. /api/x_scope/snwk_preview/eval). Empty disables it
snWidgetKit.manifestTtlMinutes 5 TTL for the portal CSS/theme cache. 0 disables the cache
snWidgetKit.instanceTypesSyncIntervalMinutes 15 Fallback interval for the periodic Script Include check. 0 disables it

Support

Questions or issues? Use the Q&A tab on this extension's Marketplace page.

License

Proprietary — © 2026 Guilherme Maziero. All rights reserved. Free to install and use; redistribution, modification and reverse engineering are not permitted. See the bundled LICENSE file.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft