There’s a module that gets loaded in almost every SuiteScript I write, and it’s not one that gets much attention in tutorials. It doesn’t search records or send emails β it just tells you where you are and who’s running the script. That’s N/runtime, and once you understand what it gives you, you’ll find yourself reaching for it constantly.
This guide covers everything the N/runtime module can do β from getting the current user and their role, to checking script parameters, reading environment information, and understanding how execution context works in SuiteScript 2.x.
What Is the N/runtime Module?
The N/runtime module provides information about the current SuiteScript execution environment. It tells you who is running the script, what account they’re in, what role they have, what script and deployment is executing, and what kind of NetSuite environment you’re in (production vs. sandbox).
Load it like any other module:
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/runtime'], (runtime) => {
// your code here
});
Getting the Current User
The most common use of N/runtime is getting the currently logged-in user. runtime.getCurrentUser() returns a User object with several useful properties:
const currentUser = runtime.getCurrentUser();
log.debug('User Info', {
id: currentUser.id, // Internal ID of the user
name: currentUser.name, // Full name
email: currentUser.email, // Email address
role: currentUser.role, // Role internal ID
roleName: currentUser.roleName, // Role display name
roleCenter: currentUser.roleCenter, // e.g. 'EMPLOYEE', 'ACCOUNTING'
contact: currentUser.contact, // Contact record ID (if applicable)
subsidiary: currentUser.subsidiary // Subsidiary ID (OneWorld accounts)
});
In practice, the most used properties are id, role, and roleCenter. For example, you might use currentUser.id as the author in an email.send() call, or check currentUser.role to conditionally show or hide fields based on who’s editing the record.
Checking the Current Script
runtime.getCurrentScript() returns the Script object representing the currently running script. This is most useful for reading script parameters β values you set on the script deployment that the script can read at runtime without hardcoding them.
const script = runtime.getCurrentScript();
// Read a script parameter (set in the script deployment record)
const fromEmail = script.getParameter({ name: 'custscript_from_email' });
const maxRecords = script.getParameter({ name: 'custscript_max_records' });
const isDebugMode = script.getParameter({ name: 'custscript_debug_mode' });
log.debug('Script Parameters', { fromEmail, maxRecords, isDebugMode });
Script parameters are a clean way to make your scripts configurable without touching the code. Instead of hardcoding an email address or a threshold value, you define it as a parameter on the script record and read it at runtime. Admins can change the value in NetSuite without needing a developer.
The Script object also exposes governance information:
const script = runtime.getCurrentScript();
log.debug('Governance', {
remaining: script.getRemainingUsage(), // How many governance units are left
});
This is useful in Map/Reduce scripts or Scheduled Scripts where you’re processing large datasets and want to bail out gracefully before hitting the limit:
if (script.getRemainingUsage() < 100) {
log.audit('Governance', 'Running low β stopping early');
return;
}
Getting the Current Session
runtime.getCurrentSession() returns the Session object, which lets you read and write session-level key/value pairs. These persist for the duration of the user’s session and are scoped to the current user.
const session = runtime.getCurrentSession();
// Store a value in the session
session.set({ name: 'last_processed_id', value: '12345' });
// Read it back later (in another script in the same session)
const lastId = session.get({ name: 'last_processed_id' });
log.debug('Last processed', lastId);
Session data is handy when you need to pass information between scripts that run in the same user session without using custom fields or records. Keep in mind it’s volatile β it doesn’t persist across sessions or logins.
Checking the Environment Type
One of the most practical uses of N/runtime is detecting whether your script is running in production or a sandbox. This lets you switch behavior β like skipping real emails in sandbox or pointing to a test API endpoint.
const envType = runtime.envType;
if (envType === runtime.EnvType.SANDBOX) {
log.audit('Environment', 'Running in Sandbox β skipping external API call');
return;
}
if (envType === runtime.EnvType.PRODUCTION) {
// Do the real thing
}
The available values are:
runtime.EnvType.PRODUCTIONβ live production accountruntime.EnvType.SANDBOXβ sandbox environmentruntime.EnvType.BETAβ NetSuite beta environmentruntime.EnvType.INTERNALβ internal NetSuite environment
Checking the Execution Context
The execution context tells you how the script was triggered. This is especially useful in User Event Scripts where you want different behavior depending on whether the record was saved via the UI, a CSV import, a web service call, or another script.
const execContext = runtime.executionContext;
if (execContext === runtime.ContextType.USER_INTERFACE) {
// Triggered by a user clicking Save in the browser
} else if (execContext === runtime.ContextType.SCHEDULED) {
// Triggered by a scheduled script
} else if (execContext === runtime.ContextType.WEBSTORE) {
// Triggered by a SuiteCommerce / web store action
} else if (execContext === runtime.ContextType.RESTLET) {
// Triggered via a RESTlet API call
} else if (execContext === runtime.ContextType.WEBSERVICES) {
// Triggered via SuiteTalk SOAP/REST web services
} else if (execContext === runtime.ContextType.CSV_IMPORT) {
// Triggered during a CSV import
}
A common pattern is to skip heavy processing when a record is being imported via CSV:
exports.beforeSubmit = (context) => {
// Skip during mass imports to avoid governance issues
if (runtime.executionContext === runtime.ContextType.CSV_IMPORT) return;
// Otherwise, run your validation logic
validateRecord(context.newRecord);
};
Real-World Example: Role-Based Field Visibility
Here’s a Client Script that shows a sensitive “Cost” field only to users with the Administrator role, hiding it from everyone else:
/**
* @NApiVersion 2.1
* @NScriptType ClientScript
*/
define(['N/runtime', 'N/currentRecord'], (runtime, currentRecord) => {
const exports = {};
exports.pageInit = (context) => {
const user = runtime.getCurrentUser();
const ADMIN_ROLE_ID = 3; // Administrator role internal ID
if (user.role !== ADMIN_ROLE_ID) {
// Hide cost field for non-admins
context.currentRecord.getField({ fieldId: 'custbody_cost' }).isDisplay = false;
}
};
return exports;
});
Real-World Example: Environment-Aware Script Parameters
Here’s a Scheduled Script that reads its API endpoint from a parameter and skips the real call in sandbox:
/**
* @NApiVersion 2.1
* @NScriptType ScheduledScript
*/
define(['N/runtime', 'N/https', 'N/log'], (runtime, https, log) => {
const exports = {};
exports.execute = (context) => {
const script = runtime.getCurrentScript();
const apiEndpoint = script.getParameter({ name: 'custscript_api_endpoint' });
const apiKey = script.getParameter({ name: 'custscript_api_key' });
// Skip real API call in sandbox
if (runtime.envType === runtime.EnvType.SANDBOX) {
log.audit('Sandbox', 'Skipping live API call in sandbox environment');
return;
}
const response = https.get({
url: apiEndpoint,
headers: { 'Authorization': `Bearer ${apiKey}` }
});
log.audit('API Response', response.code);
};
return exports;
});
Quick Reference
Here are the key N/runtime members you’ll use most often:
- runtime.getCurrentUser() β Returns current user with
id,name,email,role,roleName,roleCenter,subsidiary. - runtime.getCurrentScript() β Returns the running script with
getParameter()andgetRemainingUsage(). - runtime.getCurrentSession() β Returns the session object with
get()andset(). - runtime.envType β The current environment (
PRODUCTION,SANDBOX,BETA). - runtime.executionContext β How the script was triggered (
USER_INTERFACE,SCHEDULED,RESTLET,WEBSERVICES,CSV_IMPORT, etc.). - runtime.version β The SuiteScript version (e.g.,
2.1). - runtime.accountId β The NetSuite account ID.
- runtime.processorCount β Number of processors available for Map/Reduce scripts.
Wrapping Up
N/runtime is one of those quiet workhorses β it doesn’t do anything flashy, but you’ll use it in practically every script you write. Checking who the current user is, reading parameters from the deployment, detecting sandbox vs. production, skipping logic during CSV imports β these are the kinds of checks that make scripts robust and production-ready rather than brittle and hardcoded.
If you haven’t been using runtime.getCurrentScript().getRemainingUsage() in your longer-running scripts, add it. It’s one of the easiest ways to prevent governance limit errors before they hit you in production.
Discover more from The NetSuite Pro
Subscribe to get the latest posts sent to your email.
Leave a Reply