Skip to main content
Version: Latest (4.6.0)

Developing ServiceNow Apps with the Now SDK

Guide for ServiceNow app development using the Now SDK: project setup, fluent authoring, build/deploy workflow, and CLI reference. Load this skill first when starting any ServiceNow application project or working with the Now SDK, before loading artifact-specific skills.

When to Use

  • Setting up a new ServiceNow application project from scratch
  • Working with the ServiceNow SDK (@servicenow/sdk) CLI commands
  • Scaffolding project structure, modules, or fluent definitions
  • Building, deploying, or iterating on a ServiceNow app locally
  • Authenticating the SDK against a ServiceNow instance
  • Answering questions about SDK capabilities, fluent language, or project configuration

Prerequisites

  • Node.js 20 or later (LTS recommended)
  • npm (bundled with Node.js)
  • Access to a ServiceNow instance (PDI or enterprise) with admin or developer credentials

Installation

Create a new application:

npx @servicenow/sdk init \
--appName "My App" \
--packageName "my-app" \
--scopeName "x_my_app" \
--template "base"

Important: You must have the scope name formatted as x_<company_code>_<app_name> (if they do not have maint access). Ask the user to choose one of these options:

  • Provide the company code found under the sys_property glide.appcreator.company.code.
  • Use the generated name you provide at their own risk.

Convert an existing application from an instance:

npx @servicenow/sdk init \
--from <sys_id_of_sys_app_record>

init creates files in the current working directory. It does not create a subdirectory.

After scaffolding:

npm install

Interactive Scaffolding

npx @servicenow/sdk init

Prompts for app scope, name, and target instance. Run npm install after completion.

CLI Commands Reference

CommandPurpose
initScaffold a new project. Flags: --appName, --packageName, --scopeName, --template.
authAuthenticate. --add <url> --type basic|oauth to add, --list to check, --use <alias> to set default.
buildCompile fluent source files. Validates syntax and reports errors.
installPush built artifacts to the instance. Requires prior auth.
transformConvert existing instance artifacts into fluent source files.
downloadDownload specific records or update sets from an instance.
dependenciesFetch TypeScript type definitions for platform APIs.
cleanRemove build output and cached artifacts.
packPackage the app into an update set XML.

Project Structure

src/
fluent/
index.now.ts # Main fluent entry point
example.now.ts # Example fluent definition
tsconfig.json # Fluent TypeScript config
server/
script.ts # Example server-side script
tsconfig.json # Server TypeScript config
now.config.json # App metadata: scope, scopeId, name
package.json

Organize artifacts by type using kebab-case naming:

src/fluent/
business-rules/
my-rule.now.ts
client-scripts/
my-script.now.ts

now.config.json

{
"scope": "x_my_app",
"scopeId": "26571502d0a642339adf60a7edf6fab9",
"name": "My App",
"tsconfigPath": "./src/server/tsconfig.json"
}

Does not contain instance connection info -- that is managed via auth.

Development Workflow

  1. init -- Scaffold the project (one-time).
  2. npm install -- Install SDK and dependencies (one-time).
  3. auth -- Authenticate against your instance (or verify existing auth with --list).
  4. Write fluent -- Create .now.ts files under src/fluent/. Write server scripts in src/server/.
  5. build -- Compile and validate fluent definitions.
  6. install -- Install compiled artifacts on the instance.
  7. Iterate -- Repeat steps 4-6.

For brownfield projects, use transform to pull instance artifacts into fluent source first (see below).

Converting Existing Applications

From an Instance

Convert a scoped application already installed on an instance:

npx @servicenow/sdk init --from <sys_id_of_application>

Use --auth <alias> to specify which instance credentials to use. Without it, the default alias is used. Run npm install after.

From an Existing Repository

If the app already has a git repo with XML metadata:

npx @servicenow/sdk init --from <path_to_repo>

Existing metadata XML and supporting files are placed inside the metadata folder, and fluent configuration files are added alongside them.

Converting XML to Fluent DSL

After initializing from an instance or repo, application metadata will be in the metadata folder in its original XML form. Use transform to convert XML files into Fluent code:

# Transform a single file
npx @servicenow/sdk transform --from metadata/update/sys_script_<sys_id>.xml

# Transform the whole app at once
npx @servicenow/sdk transform --from .

# Transform a specific directory
npx @servicenow/sdk transform --from metadata/update

Transformed files are scaffolded into the generated directory (configurable in now.config.json) and removed from metadata upon successful conversion.

Note: Records that exist as both a fluent entity (.now.ts file) and an XML file in metadata will use the XML version on build. Remove converted XML files to avoid conflicts.

Run npx @servicenow/sdk transform --help for the full list of options.

Authentication

Checking Existing Credentials

npx now-sdk auth --list

Adding Credentials (Interactive)

npx now-sdk auth --add <instance-url> --type <basic|oauth>
  • basic: Username and password. Suitable for local development and PDIs.
  • oauth: OAuth-based. Suitable for enterprise instances.

Prompts for alias, username, and password. Credentials stored in .now-sdk/ (gitignored).

Setting a Default

npx now-sdk auth --use <alias>

Non-Interactive (CI/CD)

export SN_SDK_INSTANCE_URL=https://myinstance.service-now.com
export SN_SDK_USER=admin
export SN_SDK_USER_PWD=password

Environment variables take precedence over stored credentials.

Key Concepts

Fluent Language (SDK 4.x Object-Based API)

TypeScript-based DSL for defining ServiceNow artifacts:

import '@servicenow/sdk/global'
import { BusinessRule } from '@servicenow/sdk/core'
import { myScriptFunction } from '../server/script'

BusinessRule({
$id: Now.ID['my-rule'],
name: 'Uppercase Short Description',
table: 'incident',
when: 'after',
action: ['insert', 'update'],
order: 100,
script: myScriptFunction,
})
  • Import @servicenow/sdk/global to make the Now global available.
  • Import artifact types from @servicenow/sdk/core.
  • Server-side logic is written as functions in src/server/ and passed via the script property.

TypeScript Types

Run npx now-sdk dependencies to fetch type definitions for platform APIs and tables on the connected ServiceNow instance, enabling IDE autocompletion.

SDK Version Notes

  • 3.0: Initial release. Fluent language, init/build/install, transform.
  • 4.0: Breaking changes. Object-based API, new now.config.json, download and pack commands.
  • 4.1: Flow Designer support.
  • 4.2: Service Catalog items, UI Pages (including React), Import Set API.
  • 4.3: UI Policy support, stability improvements, enhanced transform.