When workflows and custom fields aren't enough, SuiteScript provides unlimited customization possibilities. SuiteScript is NetSuite's server-side and client-side scripting language based on JavaScript. It gives you programmatic access to every record, field, search, and feature in NetSuite.
SuiteScript Versions
NetSuite supports two versions of SuiteScript:
- SuiteScript 1.0 – The original API (legacy, still supported but not recommended for new development)
- SuiteScript 2.x – The modern, modular API using a define/require pattern similar to AMD. This is what you should use for all new scripts.
Script Types
Each script type runs at a different point in the application lifecycle:
| Script Type | Runs When | Common Uses |
|---|---|---|
| Client Script | In the browser when a user interacts with a form | Field validation, auto-populating fields, UI changes |
| User Event | When a record is loaded, submitted, or before/after save | Setting defaults, validation, cross-record updates |
| Scheduled | On a timer (hourly, daily, weekly, etc.) | Batch processing, data cleanup, report generation |
| Suitelet | On-demand via URL (custom pages) | Custom forms, dashboards, integration endpoints |
| RESTlet | Via HTTP request (REST API) | External integrations, custom API endpoints |
| Map/Reduce | For processing large data sets in parallel | Mass updates, complex data transformations |
| Portlet | On dashboard portlets | Custom dashboard widgets |
Your First Script: User Event
Let's create a User Event script that automatically sets a custom field value when a Sales Order is saved. This script runs on the server before the record is submitted.
Step 1: Write the Script
Create a file called yrk_ue_sales_order.js:
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
* @NModuleScope SameAccount
*/
define(['N/record', 'N/log'], (record, log) => {
function beforeSubmit(context) {
if (context.type === context.UserEventType.CREATE
|| context.type === context.UserEventType.EDIT) {
const salesOrder = context.newRecord;
const customerName = salesOrder.getText({
fieldId: 'entity'
});
// Set a custom field with a derived value
const orderLabel = customerName + ' - '
+ salesOrder.getValue({ fieldId: 'tranid' });
salesOrder.setValue({
fieldId: 'custbody_yrk_order_label',
value: orderLabel
});
log.debug('Order Label Set', orderLabel);
}
}
return { beforeSubmit };
});
Step 2: Upload the Script File
Go to Documents > Files > File Cabinet. Navigate to or create a folder (e.g., SuiteScripts > YRK). Upload your .js file.
Step 3: Create a Script Record
Go to Customization > Scripting > Scripts > New. Select your uploaded file. NetSuite will automatically detect the script type (User Event) and the entry points (beforeSubmit). Fill in:
- Name – "YRK - Sales Order Label"
- ID – customscript_yrk_so_label
Step 4: Deploy the Script
After saving the script record, click "Deploy Script." Configure:
- Applied To – Sales Order
- Status – Testing (for development) or Released (for production)
- Roles – Select which roles this script applies to (or leave blank for all roles)
- Log Level – Debug (for development) or Error (for production)
Key SuiteScript 2.x Modules
- N/record – Load, create, modify, and delete records
- N/search – Run and create saved searches programmatically
- N/email – Send emails
- N/log – Write to the execution log for debugging
- N/runtime – Get information about the current user, script, and session
- N/ui/serverWidget – Build custom forms and pages (for Suitelets)
- N/file – Read and write files in the File Cabinet
- N/http – Make HTTP requests to external services
Debugging SuiteScript
Use log.debug(), log.audit(), log.error(), and log.emergency() to write messages to the Execution Log. View logs at Customization > Scripting > Script Deployments, then click on the deployment and select the "Execution Log" tab. Use the SuiteScript Debugger in NetSuite for interactive breakpoint debugging on server-side scripts.
Best Practices
- Always use SuiteScript 2.x – Don't start new projects with 1.0
- Be mindful of governance – Each script has a usage limit. Avoid loading records in loops; use searches instead.
- Handle errors gracefully – Use try/catch blocks and log errors for troubleshooting
- Test in Sandbox – Always develop and test in a sandbox account before deploying to production
- Use JSDoc annotations – The @NApiVersion, @NScriptType, and @NModuleScope tags are required
- Follow a naming convention – Prefix script IDs and file names with your company abbreviation
Ready to build custom NetSuite solutions with SuiteScript? Contact YRK Consulting for professional development services.