njs is a JavaScript engine integrated with NGINX. It ships as:
- a standalone CLI (
build/njs) for testing and scripting, - two NGINX modules:
ngx_http_js_moduleandngx_stream_js_module, - two interchangeable JS engines selectable per location/server via the
js_enginedirective:- njs — the built-in engine, deprecated since 1.0.0.
- QuickJS — recommended. Set
js_engine qjs;in nginx.conf.
This file is the index. Detailed instructions live under docs/agent/.
| If you are doing... | Read |
|---|---|
Editing C in src/, external/, nginx/ — engine, modules, build system |
docs/agent/engine-dev.md |
| Writing JavaScript that runs in njs (CLI or NGINX), targeting either engine | docs/agent/js-dev.md |
| Writing JavaScript that must run on the deprecated njs engine | docs/agent/js-dev-njs.md |
You are extending or fixing the engine, the QuickJS integration, or the nginx modules.
Quick facts:
- Build (CLI):
./configure && make njs→build/njs. Rebuild is fast. - Build (NGINX): configure NGINX with
--add-module=<njs>/nginx(static) or--add-dynamic-module=<njs>/nginx(dynamic) in a separate NGINX tree. - Dual engine = dual code. Most external modules ship both an
njs_*.cand aqjs_*.cimplementation. If you change behavior on one side, change it on the other. - Tests:
make unit_test,make lib_test,make test262. NGINX integration tests undernginx/t/run withprove -I <tests-lib> nginx/t/. - Code style and commits: follow docs/agent/engine-dev.md for formatting, warnings, and commit-log style.
Full details, sanitizer builds, VM architecture, and object model: docs/agent/engine-dev.md.
You are writing .js modules that run inside js_content / js_filter /
js_set / js_access / js_preread handlers, or under the standalone CLI.
Orientation:
- Default to the QuickJS engine (
js_engine qjs;). The built-in njs engine is deprecated since 1.0.0; write new code for QuickJS. - Language baseline. QuickJS is ES2023; the njs engine is ES5.1 strict with a curated ES6+ subset. See the compatibility page.
- Nginx drives the engine, not the JS. Code only runs from
directive-bound entry points (HTTP:
js_content,js_access,js_header_filter,js_body_filter,js_set,js_periodic). - Quick test (CLI):
./build/njs -c '<code>'or./build/njs file.js. - Test inside NGINX:
prove -I <tests-lib> nginx/t/<your>.twithTEST_NGINX_GLOBALS_HTTP='js_engine qjs;'(and the same for_STREAM).
Everything else — full integration-point semantics, nginx.conf wiring
(js_shared_dict_zone, resolver + js_fetch_*, js_import /
js_path / js_engine), bindings (r, s, ngx.fetch, ngx.shared,
crypto, …), engine-only features, do/don't recipes:
docs/agent/js-dev.md. For code that must run on
the deprecated njs engine, also see
docs/agent/js-dev-njs.md.