Note: This is beta-quality software. Interfaces may change without warning.
ngrok is a globally distributed reverse proxy commonly used for quickly getting a public URL to a service running inside a private network, such as on your local laptop. The ngrok agent is usually deployed inside a private network and is used to communicate with the ngrok cloud service.
This is the ngrok agent in library form, suitable for integrating directly into NodeJS applications. This allows you to quickly build ngrok into your application with no separate process to manage.
A quickstart guide and a full API reference are included in the ngrok-nodejs API documentation.
- Install the
ngrok-nodejs
package from npm:
npm install @ngrok/ngrok
-
After you've installed the package, you'll need an authtoken. Retrieve one on the authtoken page of your ngrok dashboard
-
Add the following code block using the connect method to expose your nodejs application at port
8080
onlocalhost
:
const ngrok = require("@ngrok/ngrok");
(async function() {
const url = await ngrok.connect({ addr: 8080, authtoken_from_env: true });
console.log(`Ingress established at: ${url}`);
})();
You can find more examples in the /examples directory.
To use most of ngrok's features, you'll need an authtoken. To obtain one, sign up for free at ngrok.com and retrieve it from the authtoken page of your ngrok dashboard. Once you have copied your authtoken, you can reference it in several ways.
You can set it in the NGROK_AUTHTOKEN
environment variable and pass authtoken_from_env: true
to the connect method:
await ngrok.connect({authtoken_from_env: true, ...});
Or pass the authtoken directly to the connect method:
await ngrok.connect({authtoken: token, ...});
Or set it for all connections with the authtoken method:
await ngrok.authtoken(token);
The connect method is the easiest way to start an ngrok session and establish a listener to a specified address. The connect method returns a promise that resolves to the public URL of the listener.
With no arguments the connect method will start an HTTP listener to localhost
port 80
:
const ngrok = require("@ngrok/ngrok");
(async function() {
console.log( await ngrok.connect() );
})();
You can pass the port number to forward on localhost
:
const url = await ngrok.connect(4242);
Or you can specify the host and port via a string:
const url = await ngrok.connect("localhost:4242");
More options can be passed to the connect
method to customize the connection:
const url = await ngrok.connect({addr: 8080, basic_auth: "ngrok:online1line"});
const url = await ngrok.connect({addr: 8080, oauth_provider: "google", oauth_allow_domains: "example.com"});
The (optional) proto
parameter is the listener type, which defaults to http
. To create a TCP listener:
const url = await ngrok.connect({proto: 'tcp', addr: 25565});
See Full Configuration for the list of possible configuration options.
To close a listener use the disconnect method with the url
of the listener to close:
await ngrok.disconnect(url);
Or omit the url
to close all listeners:
await ngrok.disconnect();
The close method on a listener will shut it down, and also stop the ngrok session if it is no longer needed. This method returns a promise that resolves when the listener is closed.
const listener = await ngrok.getListenerByUrl(url);
await listener.close();
To list all current non-closed listeners use the listeners method:
const listeners = await ngrok.listeners();
This example shows all the possible configuration items of ngrok.connect:
const url = await ngrok.connect({
// session configuration
addr: `localhost:8080`, // or `8080` or `unix:${UNIX_SOCKET}`
authtoken: "<authtoken>",
authtoken_from_env: true,
on_status_change: (addr, error) => {
console.log(`disconnected, addr ${addr} error: ${error}`);
},
session_metadata: "Online in One Line",
// listener configuration
allow_user_agent: "^mozilla.*",
basic_auth: ["ngrok:online1line"],
circuit_breaker: 0.1,
compression: true,
deny_user_agent: "^curl.*",
domain: "<domain>",
ip_restriction_allow_cidrs: ["0.0.0.0/0"],
ip_restriction_deny_cidrs: ["10.1.1.1/32"],
metadata: "example listener metadata from nodejs",
mutual_tls_cas: [fs.readFileSync('ca.crt', 'utf8')],
oauth_provider: "google",
oauth_allow_domains: ["<domain>"],
oauth_allow_emails: ["<email>"],
oauth_scopes: ["<scope>"],
oauth_client_id: "<id>",
oauth_client_secret: "<secret>",
oidc_issuer_url: "<url>",
oidc_client_id: "<id>",
oidc_client_secret: "<secret>",
oidc_allow_domains: ["<domain>"],
oidc_allow_emails: ["<email>"],
oidc_scopes: ["<scope>"],
proxy_proto: "", // One of: "", "1", "2"
request_header_remove: ["X-Req-Nope"],
response_header_remove: ["X-Res-Nope"],
request_header_add: ["X-Req-Yup:true"],
response_header_add: ["X-Res-Yup:true"],
schemes: ["HTTPS"],
verify_webhook_provider: "twilio",
verify_webhook_secret: "asdf",
websocket_tcp_converter: true,
});
The Config interface also shows all the available options.
Degit can be used for cloning and running an example directory like this:
npx degit github:ngrok/ngrok-nodejs/examples/<example> <folder-name>
cd <folder-name>
npm i
For example:
npx degit github:ngrok/ngrok-nodejs/examples/express express && cd express && npm i
- AWS App Runner - See the ngrok SDK Serverless Example repository
- Express - Quickstart Example, Configuration Example
- Fastify - Example
- Hapi - Example
- Koa - Example
- Nest.js - Example main.ts
- Next.js - Example next.config.js loading ngrok.config.js
- Remix - Example remix.config.js loading ngrok.config.js
- Svelte - Example svelte.config.js (works in vite.config.js too) loading ngrok.config.cjs
- Typescript - Example ts-node
- Vue - Example vite.config.ts loading ngrok.config.ts
- Winston Logging - Example
- ngrok.connect - ngrok.connect Minimal Example, Full ngrok.connect Example
- HTTP - ngrok.listen Example, Minimal Example, Full Configuration Example
- Labeled - Example
- TCP - Example
- TLS - Example
- Windows Pipe - Example
For more control over Sessions and Listeners, the builder classes can be used.
A minimal example using the builder class looks like the following:
async function create_listener() {
const session = await new ngrok.NgrokSessionBuilder().authtokenFromEnv().connect();
const listener = await session.httpEndpoint().listen();
console.log("Ingress established at:", listener.url());
listener.forward("localhost:8081");
}
See here for a Full Configuration Example
As of version 0.7.0
there is backend TLS connection support, validated by a filepath specified in the SSL_CERT_FILE
environment variable, or falling back to the host OS installed trusted certificate authorities. So it is now possible to do this to connect:
await ngrok.connect({ addr: "https://127.0.0.1:3000", authtoken_from_env: true });
If the service is using certs not trusted by the OS, such as self-signed certificates, add an environment variable like this before running: SSL_CERT_FILE=/path/to/ca.crt
.
All methods return a Promise
and are suitable for use in asynchronous
programming. You can use callback chaining with .then()
and .catch()
syntax
or the await
keyword to wait for completion of an API call.
The asynchronous functions will throw an error on failure to set up a session or listener, which can be caught and dealt with using standard then/catch semantics.
new ngrok.NgrokSessionBuilder().authtokenFromEnv().connect()
.then((session) => {
session.httpEndpoint().listen()
.then((tun) => {})
.catch(err => console.log('listener setup error: ' + err))
})
.catch(err => console.log('session setup error: ' + err))
.await;
Pre-built binaries are provided on NPM for the following platforms:
OS | i686 | x64 | aarch64 | arm |
---|---|---|---|---|
Windows | ✓ | ✓ | * | |
MacOS | ✓ | ✓ | ||
Linux | ✓ | ✓ | ✓ | |
Linux musl | ✓ | ✓ | ||
FreeBSD | ✓ | |||
Android | ✓ | ✓ |
ngrok-nodejs, and ngrok-rust which it depends on, are open source, so it may be possible to build them for other platforms.
- Windows-aarch64 will be supported after the next release of Ring.
This project relies on NAPI-RS, an excellent system to ease development and building of Rust plugins for NodeJS.
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in ngrok-nodejs by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.