Expert knowledge for authoring ServiceNow Fluent (.now.ts) metadata and TypeScript/JavaScript modules using the ServiceNow SDK. Use this skill when developing full-stack React applications, creating tables, business rules, script includes, or other ServiceNow metadata using the Fluent API.
Resources
1Install
npx skillscat add danielmadsendk/nowdev-ai-toolbox/servicenow-fluent-development Install via the SkillsCat registry.
ServiceNow Fluent Development
Expert knowledge for authoring ServiceNow Fluent (.now.ts) metadata and TypeScript/JavaScript modules using the ServiceNow SDK.
Key Differences from Legacy ServiceNow
- Fluent = TypeScript DSL for metadata (
.now.tsfiles) - Use
now-sdkfor build/sync/install - Type definitions in
@types/servicenowvianow-sdk dependencies Now.include()references external scripts; SDK objects from@servicenow/sdk/core- Full-stack React apps via
UiPagewith client code insrc/client/ - Flow/workflow automation available via
@servicenow/sdk/automation - Service Catalog, Email Notifications, Workspaces, and SLAs all supported as Fluent metadata
Core Principles
- Verify APIs — use Context7 to confirm method signatures; never assume
- Match field names exactly to
@types/servicenow/schema/(prevents duplicates on install) - Use parent constant properties (
parent.$id,table.name) — neverNow.ID[...]for references - Script content is not TypeScript — ServiceNow JavaScript follows its own conventions; do not apply TypeScript validation to it
Critical Patterns
Parent-Child References
// CORRECT
export const menu = ApplicationMenu({ $id: Now.ID['menu'], title: 'App' })
export const module = Record({ table: 'sys_app_module', data: { application: menu.$id } })
export const table = Table({ name: 'x_app_table', schema: {...} })
export const rule = BusinessRule({ table: table.name })
// WRONG — creates a new ID reference instead of pointing to the constant
data: { application: Now.ID['menu'] }sys_app_module Field Rules
| Link Type | Required Fields | Notes |
|---|---|---|
| ALL | title, application, active, link_type, order, hint |
Base fields |
| LIST / NEW | + name (= target table name) |
name: 'x_app_mytable' |
| DIRECT | + query (= UI page endpoint) |
query: 'x_app_page.do', no name |
Script Patterns
// TypeScript module import (server-side) — compiled to .js
import { fn } from '../server/module.js'
BusinessRule({ script: fn })
// Now.include() for ServiceNow JavaScript — enables two-way sync
ClientScript({ script: Now.include('./script.client.js') })
// Inline ServiceNow JavaScript (NOT TypeScript)
ClientScript({ script: `function onLoad() { g_form.addInfoMessage('Hi'); }` })
// script tagged template literal
RestApi({ routes: [{ script: script`(function(req,res){ res.setBody({ok:true}) })(request,response)` }] })Sync directives: @fluent-ignore, @fluent-disable-sync, @fluent-disable-sync-for-file — use sparingly with a comment explaining why.
Full-Stack React Architecture
src/fluent/ui-pages/page.now.ts → UiPage({ html: htmlEntry, endpoint: 'x_app.do' })
src/fluent/script-includes/*.now.ts → ScriptInclude with clientCallable: true
src/fluent/script-includes/*.server.js → Class.create() with client-callable methods
src/client/index.html → <sdk:now-ux-globals>, <script src="./main.tsx" type="module">
src/client/main.tsx → ReactDOM.createRoot(root).render(<App />)
src/client/app.tsx → State, CRUD handlers, components
src/client/services/Service.ts → GlideAjax or REST service layer
src/client/components/*.tsx → UI components
src/client/global.d.ts → declare global { Window.g_ck, GlideAjax }Third-party npm libraries (component kits, icons, charts, etc.) are supported — install via npm, import normally in client code, and Rollup bundles them automatically. See references/third-party-libraries.md for the full setup guide including CSS imports, context providers, and build-warning suppression.
GlideAjax vs REST API — Decision Guide
| Requirement | GlideAjax | REST API |
|---|---|---|
| Internal ServiceNow app only | Recommended | Overkill |
| External system integration | Cannot | Required |
| Mobile app / non-React client | Cannot | Required |
| Simpler setup | Less code | More boilerplate |
| ServiceNow native security | Built-in | Manual |
| OpenAPI documentation | Limited | Supported |
Default: Use GlideAjax for internal ServiceNow apps. See references/client-server-patterns.md for full implementation examples.
Development Workflow
- Create Table in
src/fluent/tables/*.now.ts - Create ScriptInclude in
src/fluent/script-includes/*.now.ts(withclientCallable: truefor GlideAjax) - Create UiPage in
src/fluent/ui-pages/*.now.ts - Create
src/client/index.htmlwith<sdk:now-ux-globals> - Create
src/client/main.tsx(React bootstrap) andsrc/client/app.tsx(state, handlers) - Create service layer in
src/client/services/*.ts(GlideAjax or REST) - Create components in
src/client/components/*.tsx - Add navigation module (
link_type: 'DIRECT') - Build & deploy:
now-sdk build && now-sdk install --auth <alias>
Best Practices
- Naming:
x_[vendor]_[app]_[name]for tables,snake_casefields,PascalCaseexported constants - Security: Use roles not broad permissions;
gs.hasRole()in script-based ACLs; validate all input - Performance: Async business rules for non-blocking ops; index queried fields; cache expensive ops
- Error handling:
abortActionfor validation failures;isValidRecord()afterget();gs.error()for logging - Types: Use
GlideRecord<'tablename'>generics in server modules; runnow-sdk dependenciesfor schema files
References
Load these files when you need detailed guidance on specific topics:
- references/client-server-patterns.md — Full GlideAjax and REST implementation code, React entry patterns, navigation module
- references/api-reference.md — All Fluent API objects: Table, BusinessRule, ClientScript, ScriptInclude, RestApi, UiPage, SPWidget, ATF Test, UiPolicy, ImportSet, EmailNotification, Workspace, Sla, helpers; ApplicationMenu + sys_app_module navigation modules with full link-type field matrix and examples
- references/build-workflow.md — now-sdk commands,
now-sdk dependencies, tsconfig setup,#now:import alias,trustedModules, build behaviour, verification checklist - references/troubleshooting.md — Common issues, GlideAjax error diagnosis, instance verification steps
- references/advanced-patterns.md — Record() usage, cross-scope module pattern, server-side logging, common ServiceNow script APIs (GlideRecord, g_form, gs, GlideAggregate)
- references/flow-api.md — Flow API: triggers, actions, flow logic, data pills
- references/service-catalog.md — Service Catalog: CatalogItem, VariableSet, variable types, CatalogUIPolicy, CatalogClientScript, CatalogItemRecordProducer
- references/third-party-libraries.md — Adding npm packages to Fluent React apps:
package.jsonlayout, Rollup prebuild script, CSS imports, context providers, TypeScript declarations, build-warning suppression, and a full checklist