<!-- review: finished -->

<a id="external-njs"></a>

# NJS

The module provides integration of the JavaScript programming language into
Angie's event processing model and allows extending server functionality using
JavaScript scripts. It consists of two modules:

- [HTTP JS](https://en.angie.software//angie/docs/installation/external-modules/http_js.md#http-js) — for processing HTTP traffic;
- [Stream JS](https://en.angie.software//angie/docs/installation/external-modules/stream_js.md#stream-js) — for processing TCP/UDP traffic.

<a id="installation-19"></a>

## Installation

To [install](https://en.angie.software//angie/docs/installation/index.md#install-packages) the module, use one of
the following packages:

- Angie: `angie-module-njs` or `angie-module-njs-light`;
- Angie PRO: `angie-pro-module-njs` or `angie-pro-module-njs-light`.

<a id="features-1"></a>

## Features

The module extends server functionality using scripts written in njs,
a subset of JavaScript, enabling implementation of custom server-side logic
and much more:

- Complex access control and security checks before
  the request reaches the proxied server.
- Response header manipulation.
- Writing flexible asynchronous handlers and content filters.

Also available is a standalone command-line utility that can be used
independently of the server for developing and debugging njs scripts.

<a id="loading-the-module-19"></a>

## Loading the Module

Loading modules in the `main{}` context:

```nginx
load_module modules/ngx_http_js_module.so;    # for HTTP
load_module modules/ngx_stream_js_module.so;  # for Stream
```

<a id="usage"></a>

## Usage

Detailed documentation is available in the sections for individual modules:

- [HTTP JS](https://en.angie.software//angie/docs/installation/external-modules/http_js.md#http-js)
- [Stream JS](https://en.angie.software//angie/docs/installation/external-modules/stream_js.md#stream-js)

<a id="security"></a>

## Security

The module does not execute dynamic code, especially code received from the network.
The only way to execute such code using njs is to configure the
`js_import` directive in the server configuration. JavaScript code is loaded once
at server startup.

In the module's threat model, JavaScript code is considered a trusted source just like
the configuration file and site certificates. In practice, this means the following:

- disclosure of memory contents and other security issues caused by
  modification of JavaScript code are not considered security issues,
  but are treated as regular bugs;
- measures must be taken to protect the JavaScript code used by the module;
- if there are no `js_import` directives in the configuration file,
  the server is protected from vulnerabilities related to JavaScript.

<a id="command-line-utility"></a>

## Command-Line Utility

The **njs** command-line utility helps develop and debug njs scripts
and is installed along with the modules. Unlike when the module runs
as part of Angie, Angie objects (`HTTP` and
`Stream`) are not available when using the utility.

Examples of using the utility:

```console
$ echo "2**3" | njs -q
8

$ njs

>> globalThis
global {
 njs: njs {
  version: '0.3.9'
 },
 global: [Circular],
 process: process {
  argv: [
   '/usr/bin/njs'
  ],
...
```

<a id="preloaded-objects"></a>

## Preloaded Objects

For each incoming request, the module creates a separate virtual machine. This
provides many benefits, such as predictable memory consumption and
request isolation. However, since all requests are isolated, if a request
handler needs to access any data, it must read it
itself. This is inefficient, especially when the data volume is large.

To solve this problem, a mechanism for preloaded shared objects was introduced.
Such objects are created as immutable and have no prototype chains: their values
cannot be changed, properties cannot be added or removed.

Here are a few examples of working with preloaded objects in njs:

- Accessing properties by name:
  ```javascript
  preloaded_object.prop_name
  preloaded_object[prop_name]
  ```
- Enumerating properties:
  ```javascript
  for (i in preloaded_object_name) {
        // ...
  }
  ```
- Applying non-modifying built-in methods using `call()`:
  ```javascript
  Array.prototype.filter.call(preloaded_object_name, ...)
  ```

<a id="api-reference"></a>

## API Reference

For a complete reference of all njs objects, methods, and properties, see:

- [NJS API Reference](https://en.angie.software//angie/docs/configuration/njs-reference.md#njs-reference)

<a id="additional-information-20"></a>

## Additional Information

- Official website: [https://nginx.org/en/docs/njs/](https://nginx.org/en/docs/njs/)
- Usage examples: [https://github.com/nginx/njs-examples/](https://github.com/nginx/njs-examples/)
