sachin_namjoshi
Kilo Patron
Kilo Patron
 
I have created this article based on my recent experiences with working with Fluent.
 
1. Purpose and Scope
 
Developers should use Fluent for tasks like generating ACLs, Business Rules, or Script Includes, and rely on traditional Script Includes for complex logic to maintain type safety and reusability. Avoid overusing Fluent for custom applications where standard ServiceNow UI or scripting methods are more efficient.
 

 

2. Keep Type Safety in VS Code
 
It's best to continue writing complex logic in Script Includes, which support full JavaScript/TypeScript functionality, and use Fluent for simpler operations like GlideRecord queries or artifact creation. For example, define Script Includes in VS Code with proper TypeScript types and call them from Fluent-based scripts. 

 

Sample Code:
 
 
// Script Include (TypeScript)
export class MyUtils {
  getUserDetails(userId: string): string {
    const gr = new GlideRecord('sys_user');
    gr.get(userId);
    return gr.getValue('name');
  }
}

// Fluent script to call Script Include
import { MyUtils } from './myUtils';
const utils = new MyUtils();
const userName = utils.getUserDetails('sys_id_here');
3. Always use Script Includes for Modularity
 
It's better to centralize reusable logic in Script Includes and use Fluent to calls these functions. This reduces code duplication and simplifies maintenance. For client-side calls, use GlideAjax to invoke Script Includes from Fluent scripts.

 

Sample Code:
 
 
// Script Include: DateUtils
var DateUtils = Class.create();
DateUtils.prototype = {
  formatDate: function(date) {
    return new GlideDateTime(date).getDisplayValue();
  },
  type: 'DateUtils'
};

// Fluent script to call DateUtils
const dateUtils = new DateUtils();
const formattedDate = dateUtils.formatDate('2025-05-16');
 
4. Think of  Gen AI Use Case
 
Develop Fluent scripts with descriptive variable names and comments to improve AI interpretability. When using GenAI to generate Fluent code, validate the output in a sub prod instance to catch errors, such as incorrect field definitions.
 
Sample Code:
 
// Fluent script for creating a table (AI-generated, validated)
import { Table } from '@servicenow/fluent';

const myTable = new Table({
  name: 'u_my_custom_table',
  label: 'My Custom Table',
  fields: [
    { name: 'u_name', type: 'string', label: 'Name' },
    { name: 'u_created', type: 'datetime', label: 'Created' }
  ]
}).create();
 
5. Make ATF your friend
 
Test Fluent scripts manually in a development instance using background scripts or ATF tests. For Script Includes called by Fluent, use Jasmine or any other supported tool for unit testing where possible. Avoid deploying untested Fluent scripts to production, as string-based errors can be hard to debug.

 

Sample Code:
 
// Background script to test Fluent-generated Script Include
var utils = new MyUtils();
gs.print(utils.getUserDetails('sys_id_here')); // Validate output
6. Use Fluent for Scoped Applications
 
Use Fluent to create scoped applications and artifacts, and expose reusable functionality to other scopes via Script Includes. When deploying, use the “Publish to Update Set” UI Action or Now-SDK to export the application as XML.

 

Sample Code:
 
// Fluent script for scoped Business Rule
import { BusinessRule } from '@servicenow/fluent';

new BusinessRule({
  name: 'u_my_business_rule',
  table: 'u_my_custom_table',
  condition: 'active=true',
  script "!function() { gs.info('Rule triggered'); }()"
}).create();
 
7. Documentation is the key
 
Best Practice: Add comments to explain the purpose of each Fluent script and its interaction with other artifacts. Use JSDoc for Script Includes to document functions and parameters. Maintain external documentation for complex Fluent-based applications.
 

 

Sample Code:
 
 
/**
 * Creates a new ACL for read access to u_my_custom_table
 * @param {string} role - The role to grant access
 */
new ACL({
  name: 'u_my_custom_table.read',
  type: 'record',
  operation: 'read',
  role: 'u_my_role'
}).create();
 
 
 
Version history
Last update:
‎05-16-2025 09:20 AM
Updated by:
Contributors