Introduction
As NetSuite projects grow, so does the codebase β and maintaining multiple scripts with duplicated logic quickly becomes painful.
A modular architecture lets you:
- Reuse business logic across multiple scripts.
- Maintain cleaner, testable code.
- Scale integrations and workflows without rewriting core logic.
In this guide, weβll cover:
- The principles of modular SuiteScript design.
- Creating reusable helper libraries.
- Structuring a multi-script project for enterprise use.
π§ 1. What Is Modular Script Design?
In NetSuite, modular design means separating your code into logical, reusable modules β rather than putting everything into one big script file.
Example:
Instead of one 1,000-line User Event script, split it like this:
/SuiteScripts/
/libs/
recordHelper.js
dateUtils.js
/scripts/
UE_CustomerValidation.js
MR_SalesOrderSync.js
β
Each module does one thing and can be imported anywhere using define([...])
.
βοΈ 2. Example of a Reusable Helper Module
/**
* @NApiVersion 2.1
* @NModuleScope Public
*/
define(['N/record', 'N/log'], (record, log) => {
const setFieldValue = (type, id, field, value) => {
try {
record.submitFields({
type,
id,
values: { [field]: value }
});
log.debug('Field Updated', `${type} #${id} β ${field}=${value}`);
} catch (e) {
log.error('setFieldValue Error', e.message);
}
};
const getFieldValue = (type, id, field) => {
try {
const rec = record.load({ type, id });
return rec.getValue(field);
} catch (e) {
log.error('getFieldValue Error', e.message);
return null;
}
};
return { setFieldValue, getFieldValue };
});
β
This recordHelper.js
can be imported into any User Event, Map/Reduce, or Scheduled Script.
π§© 3. Using the Helper Module in Another Script
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['./libs/recordHelper'], (helper) => {
const afterSubmit = (ctx) => {
const rec = ctx.newRecord;
if (rec.type === 'salesorder') {
helper.setFieldValue('salesorder', rec.id, 'custbody_verified', true);
}
};
return { afterSubmit };
});
β Cleaner code, less duplication, and easier maintenance.
π§± 4. Directory Structure for Modular SuiteScripts
/SuiteScripts/
/libs/
recordHelper.js
searchUtils.js
emailHelper.js
/scripts/
UE_Customer.js
MR_OrderSync.js
SS_Reconciliation.js
Suggested Naming Convention
Type | Prefix | Example |
---|---|---|
User Event | UE_ | UE_Customer.js |
Client | CS_ | CS_InvoiceForm.js |
Map/Reduce | MR_ | MR_OrderSync.js |
Library | LIB_ | LIB_RecordHelper.js |
π‘ 5. Using βPrivateβ vs βPublicβ Scope
When defining modules, you can control access with:
@NModuleScope Public
β available across scripts.@NModuleScope TargetAccount
β shared only within the same account.@NModuleScope Private
β used internally only.
β Use Public for reusable libraries and Private for internal helpers.
π 6. Versioning & Dependency Management
Keep libraries versioned for better control:
/**
* recordHelper.js v1.2.0
*/
If you enhance a library (e.g., add caching logic), create a new version and update dependent scripts gradually.
β Reduces risk of breaking production scripts.
π§© 7. Combining Libraries for Business Logic Layers
Layer | Purpose | Example |
---|---|---|
Core Utility Layer | Common functions | recordHelper.js, dateUtils.js |
Business Logic Layer | App-specific logic | invoiceProcessor.js |
Interface Layer | SuiteScript entry points | UE_Invoice.js, MR_Orders.js |
β This layered approach mimics enterprise application architecture β and works beautifully inside NetSuite.
π 8. Governance & Performance
- Avoid reloading modules inside loops.
- Cache heavy lookups inside helper functions.
- Keep libraries lightweight β no unnecessary imports.
- Reuse code instead of duplicating it in every script.
π 9. Benefits Summary
Benefit | Description |
---|---|
β Reusability | Shared logic across scripts |
β Maintainability | Cleaner updates and debugging |
β Scalability | Easier to extend new features |
β Collaboration | Multiple developers can work independently |
β Performance | Reduced redundancy in logic |
β 10. Best Practices
- Prefix reusable files with
LIB_
orUTIL_
. - Store shared code under
/SuiteScripts/libs/
. - Document every exported function.
- Keep functions short and pure β no external side effects.
- Create a
README.md
for your library folder explaining usage.
Conclusion
Modular SuiteScript design is the foundation for scalable, enterprise-grade NetSuite solutions.
It separates what your code does from how and where it runs, improving speed, reliability, and collaboration.
Once you start thinking in modules, your SuiteScript projects become flexible, maintainable, and future-proof β ready to grow with your business.
Discover more from The NetSuite Pro
Subscribe to get the latest posts sent to your email.
Leave a Reply