New Relic's Node.js agent: load order is the installation
New Relic Node.js agent code base. Developers are welcome to create pull requests here, please see our contributing guidelines. For New Relic technical support, please go to http://support.newrelic.com.
At a glance
- What is it?
- The newrelic npm package instruments a Node.js application for New Relic monitoring, and almost every rough edge in it comes from one requirement: the agent has to be loaded before the code it observes. The repository also shows where ESM apps diverge, what v15 will remove, and why the test suite needs Docker.
- Who is it for?
- Adopt the newrelic package if you run long-lived Node.js services, can control the startup command, and already have a New Relic account. Do not adopt it for processes you cannot preload, or as a substitute for a metrics backend you host yourself.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The agent has to be loaded before your program does
The newrelic package instruments your application for performance monitoring with New Relic. The mechanism that trips people up is not the monitoring, it is the ordering. The documented way to start a program with the agent in place is to use node's -r/--require flag, so the agent is registered before the application module runs. If you cannot control how your program is run, the fallback is to load the newrelic module before any other module in your program. That requirement cascades: a program that requires an instrumented library too early, or one that loads the agent after user modules, ends up with gaps in what is observed. The agent's own API is built around wrapping functions, as the custom instrumentation example shows with a shim that wraps parse-json, so anything loaded before the agent registers its wrappers is a candidate for missing data. This is why the package is installed with a config file and a startup flag rather than as an ordinary library you import somewhere in the middle of your code.
Three steps, a config file you own, and a preload flag
Installation is described as three steps, and the middle one is the one people get wrong. First the package goes into your application:
npm install newrelicThen the stock configuration file is copied out of the package into your program's base folder:
cp ./node_modules/newrelic/newrelic.js ./<your destination>Third, you add your New Relic license key and application or service name to that file:
/* File: newrelic.js */
'use strict'
/**
* New Relic agent configuration.
*
* See lib/config/schemas/ in the agent distribution for a more complete
* description of configuration variables and their potential values.
*/
exports.config = {
app_name: ['Your application or service name'],
license_key: 'your new relic license key',
/* ... rest of configuration .. */
}The agent points you at lib/config/schemas/ in its own distribution for the full list of configuration variables, so the copied file is a starting point rather than the reference. A New Relic account is needed before any of this is useful, and the project asks you to test before using the agent in production.
The program then runs with the agent loaded first:
node -r newrelic your-program.jsThat is the whole startup change for a CommonJS application, and it is a deployment decision as much as a code change: every place that starts the process has to carry the flag. The alternative form is inside the program itself:
const newrelic = require('newrelic')
/* ... the rest of your program ... */The project's framing is that the preload form is for when you control the run command, while the in-file form is the fallback. Either way the module has to be the first thing that loads.
ESM apps rename the config and add a loader flag
If your application uses import and export statements, the bootstrap changes. A configuration file has to be renamed from newrelic.js to newrelic.cjs so it can be loaded properly, and the project states that all the contents behave the same once renamed:
mv newrelic.js newrelic.cjsThe second change is the loader file:
node --import newrelic/esm-loader.mjs -r newrelic your-program.jsThe agent ships an ESM loader at esm-loader.mjs, and the project states that the agent includes support for ES Modules. Note what this means operationally: the ESM path needs both flags, and the config file name changes, so an upgrade that only copies the newrelic.js file into place leaves an ESM application with a config it cannot load. A working example lives in the newrelic-node-examples repository.
Custom instrumentation in ESM needs isEsm: true
The agent supports adding your own custom instrumentation to ES module applications through the instrumentation API methods, with one difference from CommonJS: you must provide a property of isEsm: true.
import newrelic from 'newrelic'
newrelic.instrument({ moduleName: 'parse-json', isEsm: true }, function wrap(shim, parseJson, moduleName) {
shim.wrap(parseJson.default, function wrapParseJson(shim, orig) {
return function wrappedParseJson() {
const result = orig.apply(this, arguments)
result.instrumented = true
return true
}
})
})The supported methods in ESM apps are listed explicitly: newrelic.instrument, newrelic.instrumentConglomerate, newrelic.instrumentDatastore, newrelic.instrumentMessages and newrelic.instrumentWebframework. Anything outside that list is not covered.
One deprecation deserves a date attached to it. newrelic.instrumentLoadedModule is deprecated and scheduled for removal in v15. It was never supported in ES module apps, and in CommonJS it existed only to retrofit instrumentation when the agent was loaded after user modules, which the project says is no longer supported. Code that still calls it should be checked before a major version bump.
The module export is the API surface, and Next.js has its own path
The newrelic module returns an object with the agent's API methods attached, and the README's usage example adds a custom attribute:
const newrelic = require('newrelic')
/* ... */
newrelic.addCustomAttribute('some-attribute', 'some-value')Frameworks get separate treatment. For Next.js the project recommends the hybrid agent functionality, and points at a documentation page on Next.js instrumentation with hybrid agent, plus an App Router example in the newrelic-node-examples repository that shows loading the hybrid agent instrumentation, injecting the browser agent and deploying to Vercel. So the pattern is consistent: the agent is loaded first, the framework integration is layered on top, and in a serverless deployment such as Vercel the load order is a property of the platform's runtime rather than of your source tree.
Native v8 metrics arrive through a different door
The core agent and the optional companion module take different routes to the same result, and the difference is worth understanding before you install both. The core agent instruments at the JavaScript layer, wrapping functions in the modules your application loads, which is what the custom instrumentation example demonstrates. The companion package @newrelic/native-metrics is described as providing hooks into the native v8 layer of Node.js to provide metrics to the Node.js agent. One reads the application from inside JavaScript, the other reads the runtime from below JavaScript. There is a practical difference: the core agent works on its own, while @newrelic/native-metrics is a module that has to be installed and configured to accompany it. If your profiling question is about V8 itself rather than about your handlers, that second route is the one the project points to.
The test suite expects Docker, Elasticsearch, OpenSearch and Kafka
Working on the agent means working on a multi-service test environment. The documented steps are to fork the agent, install its dependencies and run tests using npm:
git clone [email protected]:your-user-name/node-newrelic.git
cd node-newrelicnpm installDocker has to be installed, and the services are started with:
npm run servicesThe docker-compose.yml at the top level defines what that means: an Elasticsearch service on image docker.elastic.co/elasticsearch/elasticsearch:9.0.0 with port 9200 published, an OpenSearch service on image opensearchproject/opensearch:2 with 9201 mapped to 9200, and a Kafka setup based on the end-to-end tests in node-rdkafka that needs both zookeeper and kafka, with the zookeeper image at confluentinc/cp-zookeeper:7.9.1 on port 2181. Both search clusters are configured as single node with security disabled and disk watermarks turned off. Anyone without Docker on the machine cannot run the suite at all, which is the practical constraint on contributing.
What the repository does not tell you, and what it releases
Release activity is visible and regular: v14.8.0 on 2026-10-13, v14.7.0 on 2026-10-07 and v14.6.0 on 2026-10-06, with package.json at version 14.8.0, and the last push was on 2026-10-19. The tree also carries changelog.json, NEWS.md, a Migration Guide and compatibility.md, so migration guidance exists even though it is not part of the README. What the README does not give you is an overhead figure: it asks you to test before production use and leaves the cost of wrapping every call to you to measure. The licence of the code is Apache-2.0, with LICENSE plus THIRD_PARTY_NOTICES.md, THIRD_PARTY_NOTICES_ADDENDUM.md and a third_party_manifest.json for bundled dependencies. That licence covers the agent source. The service it reports to is a separate commercial relationship, and the requirement to have a New Relic account before starting makes that dependency explicit. Teams that need metrics with no external account should look elsewhere.
Editorial conclusion
Adopt the newrelic package if you run long-lived Node.js services, can control the startup command, and already have a New Relic account. Do not adopt it for processes you cannot preload, or as a substitute for a metrics backend you host yourself. Before committing, check three things: whether your entry point is CommonJS or ESM, whether the ESM custom instrumentation methods you rely on are on the supported list, and whether any code still calls newrelic.instrumentLoadedModule, which is deprecated and scheduled for removal in v15.
Frequently asked questions
How do I install the New Relic Node.js agent and start it with my program?
Install the package with npm install newrelic, copy ./node_modules/newrelic/newrelic.js into your program's base folder, add your license_key and app_name, and start the program with node -r newrelic your-program.js. The README frames this as three steps and asks you to test before using it in production.
How do I use the newrelic agent with an ES module application?
Rename your configuration file from newrelic.js to newrelic.cjs, then start the program with node --import newrelic/esm-loader.mjs -r newrelic your-program.js. Custom instrumentation in ESM apps must set isEsm: true on the instrument call.
What happens to newrelic.instrumentLoadedModule in version 15?
It is deprecated and scheduled for removal in v15. It was never supported in ES module apps, and in CommonJS it only existed to retrofit instrumentation when the agent was loaded after user modules, which is no longer supported.
Do I need Docker to run the New Relic Node.js agent test suite?
The documented steps require Docker to be installed, then the services are started with npm run services, which brings up the Elasticsearch, OpenSearch and Kafka related services defined in docker-compose.yml. The tests themselves are run with npm.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/newrelic-node-newrelic)Was this useful?