Unlocking the Power of NetSuite Customisation: Tips and Best Practices for Developers

Boost your NetSuite customisation skills with our expert tips and best practices for developers. Dive into our comprehensive guide and transform NetSuite!

Unlocking the Power of NetSuite Customisation: Tips and Best Practices for Developers

Table of Contents

The most useful thing a NetSuite developer can learn is when not to write code. The platform gives you enough rope to build almost anything, and a great deal of what gets built could have been configured, or should not exist at all.

That is not an argument against customisation. It is an argument for treating every script as a long term commitment, because that is what it is. Somebody will maintain it, test it against two releases a year, and eventually try to work out what it does without the person who wrote it.

This article covers the practices that separate customisation you can live with from customisation that becomes the constraint on everything the business wants to do next.

Exhaust configuration first

Before any script, work through what the platform already does.

Custom fields, custom records, custom forms and custom lists cover an enormous proportion of what businesses ask for, and they survive upgrades without attention.

Workflow handles routing, approvals, field updates, state transitions and scheduled actions without a line of code, and it is visible to somebody who is not a developer, which matters more than it sounds when the person who built it has left.

Saved searches with formula fields handle a surprising amount of what people ask for as a report or a dashboard.

The test is not whether you could build it faster in script. It usually is. The test is what it costs to own for the next decade, and configuration wins that comparison almost every time.

Choose the right script type

Picking the wrong entry point is the most common structural mistake and it is difficult to unwind later.

User event scripts run on the server when a record is created, updated or deleted, and they are the right place for validation and derived values that must hold regardless of how the record was created.

Client scripts run in the browser and are for immediate feedback during data entry. They do not enforce anything, because anything that bypasses the interface bypasses them.

Scheduled and map reduce scripts handle volume. Map reduce exists because governance limits make large jobs impossible any other way, and reaching for it early avoids a painful rewrite when volume grows.

Suitelets serve custom interfaces. RESTlets serve integrations. Using a Suitelet as an integration endpoint works and it makes authentication and error handling harder than they need to be.

Respect governance from the start

Governance units are the constraint that separates code which works in testing from code which works in production.

Every operation costs units, records searched, records loaded, records saved, and each script type has a budget. Exceed it and the script stops, usually in the middle of something.

The practical implications are consistent. Search rather than load where you only need a few fields, because a search result is dramatically cheaper than a record load. Use submitFields rather than load and save when you are changing one field. Avoid loading records inside a loop.

And for anything that might process more than a few hundred records, design for map reduce from the beginning and use the built in yield points rather than discovering the limit later.

The cost of getting this wrong is not a slow script. It is a script that silently processes half its input.

Write for the person who inherits it

Most NetSuite code outlives its author's involvement, which should shape how it is written.

Name things for what they mean in the business rather than for what they are technically. A variable called approvalThreshold is more useful than one called val2.

Comment the why rather than the what. The code says what it does. What it cannot say is that this rule exists because of a specific commercial arrangement agreed in a particular year, and that is exactly what the next person needs.

Keep functions small and single purpose, because a two hundred line entry point is where bugs hide.

And keep the business rules in one place rather than scattered, so that when the rule changes there is one thing to change.

Do not hardcode anything that can move

Internal IDs, account numbers, thresholds, email addresses and department references all change, and every one of them hardcoded in a script is a future support ticket.

Script parameters handle the simple cases and are visible to an administrator without a deployment.

Custom records handle the more structured cases, such as a rate table or a mapping, and give the business the ability to maintain their own configuration.

The benefit is not elegance. It is that a change which would otherwise require a developer, a sandbox and a deployment becomes something the administrator does in five minutes.

This single practice probably accounts for more of the difference between a maintainable customisation estate and an unmaintainable one than anything else.

Handle errors deliberately

Silent failure is the worst outcome in an ERP, because incorrect data that looks correct is more damaging than an obvious break.

Decide explicitly, for each failure mode, whether the right response is to stop, to continue and log, or to alert somebody.

Log meaningfully. A log entry that says error is useless. One that identifies the record, the operation and the specific condition lets somebody diagnose without reproducing.

For scheduled processing, make sure a failure is visible. A nightly job that has been failing for three weeks with nobody noticing is a common and entirely preventable situation.

And be careful about swallowing exceptions to keep a process moving, because the moving process is producing wrong data.

Design for the release cycle

NetSuite releases twice a year and your customisations are your responsibility to keep working.

Use the release preview account for what it is for, which is testing your customisations against the next version before it arrives.

Prefer documented APIs over undocumented behaviour, because undocumented behaviour is exactly what changes without notice.

Keep a register of what you have built, what it does and what it depends on, since the register is what makes release testing possible rather than exhaustive.

And read the release notes for the areas you have customised, because functionality sometimes arrives that would replace something you are maintaining, and retiring a customisation is the only change that reduces ongoing cost permanently.

Use source control and a real deployment process

Editing scripts directly in the file cabinet in production is common and it is indefensible once a business depends on the system.

Keep the code in source control, so there is a history, a diff and a way back.

Use the SuiteCloud Development Framework for deployment, so that what moves between environments is a defined package rather than a collection of files somebody remembered to copy.

Maintain a sandbox that reflects production closely enough to be a genuine test, and test there rather than reasoning about what should happen.

None of this is heavy for a small estate and all of it becomes essential the moment more than one person is making changes.

Testing that actually catches things

Testing customisations well is mostly about testing the cases nobody thinks of.

Test the volume case, because a script that works on ten records may fail on ten thousand for governance reasons that do not appear at small scale.

Test the interaction case, since a user event script fires regardless of how the record was created, which includes CSV import, integration and other scripts.

Test the permission case, because a script running in the context of a restricted role behaves differently from one running as an administrator.

And test the failure case deliberately, by making something fail, and confirming that the failure is visible and the data is left in a defensible state.

Know when a customisation is the wrong answer

Some requests should be declined, and a developer who never declines one is expensive over time.

Where the request encodes a process that exists only because a previous system could not do it better, the right answer is to change the process.

Where the request is one person's preference rather than a business requirement, the cost of ownership rarely justifies it.

Where standard functionality does the job in a slightly different way, adapting is almost always cheaper than replicating the old way in code.

And where a request would need to be rebuilt every time the business changes, it is a sign that the underlying design is wrong rather than that more code is needed.

Specifying work properly

A large proportion of poor customisation traces back to a specification that described a solution rather than a problem.

A useful specification states what the business is trying to achieve, what happens today, how often the situation arises, and what the consequence is of getting it wrong.

It should also state the exceptions explicitly, because the exceptions are where the design decisions live and discovering them during build is expensive.

And it should say who will test it and against what, since work with no defined acceptance criteria gets accepted on the basis that it appears to work.

Developers who insist on this are occasionally seen as obstructive and are consistently cheaper over the life of the system, because the alternative is building the wrong thing efficiently.

Managing the estate as a portfolio

Individual customisations are decided one at a time and their collective weight is what constrains the business.

Keep a register of everything built, what it does, why, who asked for it and what it depends on. Most organisations cannot produce this after two years, which is the problem in itself.

Review it annually against two questions. Is this still needed, since processes change and some customisations outlive their purpose. And has standard functionality caught up, since it frequently has.

Retire what fails either test. Removing a script is one of the few actions that reduces cost permanently and it is almost never on anybody's list.

The integration boundary

Integrations are customisations with an extra failure mode, which is that the other side is not under your control.

Design for the other system being unavailable, which it will be, and decide whether the right behaviour is to retry, to queue or to fail loudly.

Make the integration idempotent where possible, so that reprocessing the same message does not create duplicates, because reprocessing will happen.

Log both sides of every exchange, since diagnosing an integration failure without a record of what was sent is guesswork.

And monitor it actively rather than waiting for somebody to notice missing data, because integrations fail quietly and the gap is usually discovered at month end.

Working with the business

The technical practices matter and the largest determinant of whether a customisation is worth having is the conversation before it is built.

Ask what problem this solves rather than what they want built, because the stated requirement is frequently a solution somebody has already designed.

Ask what happens today, since understanding the current workaround usually reveals a simpler answer.

Ask how often this occurs, because a monthly exception rarely justifies permanent code.

And be willing to propose something different, since the person asking knows their process and not what the platform can do, and the gap between those two is where the good solutions live.

Building the capability internally

Where all customisation goes outside, the business becomes dependent in a way that limits it.

The most useful internal capability is not a developer. It is an administrator who understands the configuration, can build a saved search and a workflow, and can judge whether a request needs code at all.

That person filters most requests before they become development work, which is where the saving is.

Where genuine development is needed, having somebody internal who can specify it properly and review what comes back is worth considerably more than the specification itself. Our customisation and development service is structured to build that rather than replace it.

Where to go from here

Good NetSuite customisation is mostly restraint, structure and documentation rather than technical sophistication. The estates that cause problems are rarely badly coded. They are undocumented, hardcoded, and larger than they needed to be.

If you are looking at an existing estate, the highest value thing available is the register. Write down what exists and why, and the retirement candidates identify themselves.

Our pieces on customising NetSuite to fit your business and the NetSuite development platform cover the wider ground, and becoming a NetSuite developer covers the path in.

If you would like a review of your customisation estate, get in touch.