The most expensive line of SuiteScript is the one that should never have been written.
Every NetSuite consultant has inherited a system where a 400-line User Event script does something that a single workflow could have handled. The script works. It passed UAT. It is in production. And it will cost the client thousands in maintenance over the next three years because nobody asked the right question before writing it.
That question is simple: can native NetSuite configuration solve this problem?
Custom SuiteScript is not free. Beyond the initial development hours, every script in your account carries ongoing costs that are easy to underestimate.
First, there is the maintenance burden. NetSuite releases two major updates per year. Every custom script is a potential regression point. A workflow or saved search, by contrast, is maintained by Oracle as part of the platform. When the platform upgrades, native configuration upgrades with it.
Second, there is the knowledge dependency. When the original developer leaves, their scripts become a black box. Native configuration is visible to any NetSuite administrator through the standard interface. A workflow can be read and understood by a functional consultant. A Map/Reduce script cannot.
Third, there is the governance gap. Scripts that bypass standard record validation, override field sourcing, or manipulate transaction amounts outside of native flows create audit exposure. If your external auditors ask "why does this journal appear with no approval trail?" and the answer is "a scheduled script created it," you have a governance problem.
Before any SuiteScript development begins, we apply a three-tier evaluation. This is not a guideline in our practice. It is a mandatory gate in our consulting pipeline.
This covers saved searches, workflows (SuiteFlow), custom records, custom fields, form customisation, roles and permissions and approval routing. A surprising number of requirements that arrive as "we need a script for this" can be resolved here. Approval workflows, field validation, conditional mandatory fields, automated email alerts and record status management are all native capabilities that many teams underuse.
Sometimes the business logic is mostly achievable through configuration, but a small script is needed for the remaining edge case. A Client Script that hides a sublist column based on a custom field value. A User Event that sets a default on record creation. These are thin, low-risk scripts that complement configuration rather than replacing it.
Complex integrations, bulk data processing, custom portals, advanced PDF generation with conditional logic, real-time inventory clearing models. These are legitimate SuiteScript use cases. When we reach Tier 3, we proceed with full documentation: functional design, technical design, test scripts and deployment plan. The governance overhead is justified because the requirement genuinely demands it.
A manufacturing client needed multi-level rejection handling on purchase orders. If a line manager rejected a PO, it should return to the originator for edit. If finance rejected it, it should go back to the line manager for re-review. If procurement rejected it on vendor compliance grounds, it should bypass all approvers and go directly to the procurement team for vendor re-selection. Each rejection path required different notification templates, different SLA timers and different audit trail entries.
The previous vendor had scoped this as a Suitelet-driven approval engine with a custom record for routing configuration, User Event scripts for state transitions and scheduled scripts for SLA escalation. Roughly 1,200 lines of SuiteScript across eight script files. Quoted at six weeks.
We delivered it in SuiteFlow using three techniques most developers forget exist. First, the State Before Entry workflow action, which lets a single workflow branch to different states based on a field condition evaluated at the moment of transition, rather than requiring separate workflows for each rejection type. Second, the Go To Page action combined with a hidden status tracking field, which allowed us to route the originator back to the edit view with context about who rejected and why, without a custom Suitelet. Third, workflow-scheduled transitions using the native time-delay action for SLA escalation, replacing the scheduled script entirely.
The result: one workflow, 14 states, 23 transitions, zero lines of code. Four days to build, two days to UAT. The procurement manager can adjust the rejection routing logic herself by editing the workflow state transitions, without calling a developer.
The lesson is not that SuiteFlow is more powerful than anyone realises. It is that the cost of not knowing what SuiteFlow can do is paid by the client, in the form of custom code that never needed to exist.
The incentive structure in many consulting firms favours scripting. Development hours are billable. Configuration hours are fewer and harder to justify at the same rate. This creates a systemic bias toward custom solutions even when simpler alternatives exist.
The antidote is a governance framework that requires the evaluation to be documented before development begins. In our practice, the Functional Design Document must include a "Configuration Assessment" section that explicitly records what was considered and why it was ruled out. If that section is empty, the document is returned for revision.
Configuration before code is not about being conservative. It is about being responsible. Every unnecessary script is technical debt. Every native solution is a maintenance cost avoided. The best NetSuite consultants are not the ones who write the most elegant SuiteScript. They are the ones who know when not to write it at all.
Need a governance review of your NetSuite customisations?
Book a Free Consultation