Building a SuiteCommerce Extension: A Practical Developer Guide
SuiteCommerce extension development does not start with a public npm package. You download Oracle NetSuite's Extension Developer Tools from your account, install their dependencies, and run the Gulp tasks included with the download.
This guide covers that workflow. It applies to SuiteCommerce and to SuiteCommerce Advanced (SCA) releases that support extensions. Older SCA releases use a different customization model, so check your site's release before copying code or choosing a Node.js version.
Check the live Oracle documentation before setup. Tool versions, supported Node.js versions, and File Cabinet paths change. The links in this guide point to the NetSuite Applications Suite help site.
Before you write an extension
First check whether NetSuite already provides the feature through a website record, Commerce configuration, Site Management Tools, or an existing supported extension. Oracle recommends configuration before custom code because configured features receive product support and updates.
Use an extension when you need behavior that configuration cannot provide. Use a theme for broad presentation changes. An extension can still contain templates and Sass when its UI belongs to the feature.
For SCA, release age matters:
- Aconcagua and later: extensions and the Extensibility API are available. Oracle recommends the API where it covers the requirement.
- Kilimanjaro and earlier: the Extensibility API is not available. Upgrade or use the SCA developer tools and the customization practices for that release.
- SCA source-level changes: use the SCA developer tools when the required object is not exposed by the Extensibility API.
See Oracle's Develop Your Extension and general extension practices.
1. Install the supported tools
Get the Extension Developer Tools from NetSuite
Your NetSuite account must have SuiteCommerce or SCA and SuiteCommerce Extension Manager installed. Then:
- Sign in to NetSuite.
- Go to Documents > Files > File Cabinet.
- Open SuiteBundles/Bundle 521562/.
- Download the newest
ExtensionDevelopmentTools-<version>.ziplisted for your account. - Extract the ZIP into its own top-level development directory.
At the time of writing, Oracle's help page names ExtensionDevelopmentTools-26.1.x.zip. Aconcagua and SCA 2018.2 require the older ExtensionDevelopmentTools-18.2.1.zip. Do not assume that the newest tools support an old SCA release.
Oracle documents the current download path and compatibility note in Set Up Extension Developer Tools.
Do not move or rename files inside the extracted directory. The developer tools expect their own folder structure.
Match Node.js to your Commerce release
Do not install an arbitrary current Node.js release. Oracle publishes a release-to-Node version table. Its current entry for SuiteCommerce, SuiteCommerce MyAccount, SCA 2025.2, and SCA 2026.a is Node.js 20.10.0; older SCA releases require older Node versions.
Check Install Node.js, then verify your installation:
node -v
npm -v
A version manager such as nvm can help when you maintain sites on different SCA releases, but the version must still match Oracle's table.
Install Gulp and the downloaded tool dependencies
Oracle's developer tools use Gulp, not an scc command:
npm install --global gulp
gulp -v
From the extracted Extension Developer Tools directory, install the dependencies packaged by Oracle:
npm install
Run all later gulp extension:* commands from this top-level directory, not from an individual module. See Install Gulp.js.
For account access, use a role with the required developer-tool permissions. The Administrator and SCDeployer roles have them by default. Oracle's current tools guide you through creating or choosing an authentication ID during fetch and deploy. Token-based authentication setup is also documented on the setup page.
2. Create a baseline extension
Start with Oracle's generator:
gulp extension:create
It asks for the display name, internal name, vendor, version, first module, supported product, target application, target version, and file types. Choose only the file types the feature needs.
For example, a shopping-page widget may need JavaScript, a template, and Sass. It does not need a SuiteScript service unless it must read or write NetSuite data that the frontend APIs do not expose.
The generated files live under Workspace/:
Workspace/
└── MyExtension/
├── assets/
│ ├── fonts/
│ ├── img/
│ └── services/
├── Modules/
│ └── MyModule/
│ ├── Configuration/
│ ├── JavaScript/
│ ├── Sass/
│ ├── SuiteScript/
│ ├── SuiteScript2/
│ └── Templates/
└── manifest.json
The exact folders depend on the file types selected. There is no ns.package.json in this extension structure. manifest.json records the extension metadata and the files loaded by the shopping, checkout, and My Account applications.
Read Create a Baseline Extension and Extension Development Files and Folders before changing the generated layout.
To add another module later, run:
gulp extension:create-module
A module should own one clear part of the feature. Keep unrelated behavior in separate modules rather than growing one entry point into a catch-all file.
3. Work with the supported APIs
SuiteCommerce JavaScript modules use named AMD modules. The extension entry point returns an object with mountToApp(container). The container gives the extension access to public components such as Layout, Cart, PDP, Environment, and UserProfile, subject to the site's Commerce release.
Prefer those public components over core-module imports or the SC global. Oracle warns against extending core modules, changing their prototypes, or wrapping their methods because those hooks can break after an update.
Views and models depend on the target release
For current SuiteCommerce releases:
- Use
SCViewfor views. It has been part of the Extensibility API since SuiteCommerce 2020.2. - Use
SCModelfor frontend models. It has been available since SuiteCommerce 2020.1. - Use the
Environmentcomponent to read configuration instead of importingSC.Configuration.
For older SCA releases, the supported base classes differ. SCA 2020.1 and earlier uses Backbone.View; SCA 2019.2 and earlier uses Backbone.Model.
This is why a generic Backbone example is not safe to paste into every SuiteCommerce site. Start with the generated module, set the extension's target version, and check the component against the Extensibility API reference.
Oracle provides version-specific examples in Views in an Extension and Models in an Extension.
Templates and events
Templates use .tpl files and Handlebars syntax. Pass values through a view's getContext() method. Register browser events through the view API and use the Extensibility API's component events for application behavior.
Treat values returned by a backend service as untrusted input. Escape displayed text, validate form data on the server, and check authorization before reading or changing NetSuite records.
Backend services
Add SuiteScript only when the browser needs a server endpoint. The generator can create SuiteScript 1.0 or SuiteScript 2.0 service examples. Keep request handling thin and put data access and business rules in a backend model or another focused module.
The service URL must use the extension asset path because its final account URL is not known during development. Follow the generated frontend model and Oracle's examples rather than hard-coding /services/... paths.
Oracle currently supports SuiteScript 1.0 and 2.0 for Commerce extension services. Its help page says SuiteScript 2.1 is not supported for Commerce website development. See Use SuiteScript With Your Extension.
4. Fetch the active site files
Before local testing or a normal deploy, fetch the active theme and any custom extensions needed for the selected domain:
gulp extension:fetch
For accounts that use account-specific domains, Oracle also documents the --account form:
gulp extension:fetch --account 123456
gulp extension:fetch --account 123456-sb1
The command stores active-theme files under Workspace/Extras/. They exist so the tools can compile your extension against the site. Do not edit them.
Commit or back up your work before fetching. Fetch can overwrite local files for a custom extension that is active on the selected domain. It cannot fetch source from a published extension.
See Fetch Active Theme and Extension Files.
5. Test the extension
Start the local build and watch task:
gulp extension:local
The command writes compiled files to LocalDistribution/, starts a local server, and watches JavaScript, template, and Sass files. Use the local shopping, My Account, or checkout URL printed or described by the tools.
Local testing has two limits that often surprise developers:
- SuiteScript services do not exist in the account until you deploy and activate them.
- Configuration JSON changes do not apply to a domain until you deploy and activate them.
For either case, deploy to a sandbox, activate the extension there, and then continue frontend testing against that account. Also restart the local server after a manifest change.
The official Gulp command reference does not list scc extension:test or a built-in coverage command. If your team has its own test harness, keep pure business rules in small modules that it can run without a browser. For the full extension, test at least:
- each target application: shopping, checkout, and/or My Account;
- signed-in and guest states where relevant;
- success, validation, empty, permission, and service-error paths;
- the site's supported browsers and mobile breakpoints;
- cart, checkout, and account flows touched by the extension;
- page weight, request count, and runtime errors before and after activation.
See Test an Extension on a Local Server.
6. Deploy, then activate
Deploy from the top-level tools directory:
gulp extension:deploy
For an account-specific domain:
gulp extension:deploy --account 123456-sb1
The first deploy prompts for the extension and account metadata. The command validates the extension and uploads its development files to the NetSuite File Cabinet. It does not make the extension live.
After deployment, open NetSuite's Manage Extensions wizard, choose the site and domain, select the deployed extension version, and activate it. Plan activation as a separate release step and verify the domain after it finishes.
Use a sandbox before production. Oracle also recommends separate extracted developer-tool directories for sandbox and production so that a saved authentication ID does not send a deployment to the wrong account.
Read Deploy an Extension to NetSuite and Manage Themes and Extensions.
Manifest warning
gulp extension:local and gulp extension:deploy update manifest.json. If you made a required manual edit, such as adding a Sass entry point, use the preserve flag:
gulp extension:local --preserve-manifest
gulp extension:deploy --preserve-manifest
Check the generated diff before committing. See Edit the Extension Manifest.
A short release checklist
Before production activation:
- Confirm the target SCA or SuiteCommerce version in
manifest.json. - Confirm the Node.js and Extension Developer Tools versions match the site.
- Fetch and compile against the active theme.
- Test SuiteScript and configuration changes in a sandbox after activation.
- Review the generated manifest and all build changes.
- Record the deployed extension version and the domains where it is active.
- Keep the prior working version available until post-release checks pass.
Command summary
# One-time setup in the extracted Oracle tools directory
npm install --global gulp
npm install
# Create source files
gulp extension:create
gulp extension:create-module
# Get the active theme and eligible custom extension files
gulp extension:fetch
# Compile, serve, and watch frontend files
gulp extension:local
# Validate and upload extension source to NetSuite
gulp extension:deploy
Run gulp to see the commands supported by the developer tools you downloaded. Treat that output and Oracle's Gulp command reference as the source of truth for flags. Commands copied from unrelated CLIs or old SCA guides may not apply to extension development.


