Run JavaScript Inside Nginx with njs: A Hands‑On Guide
This article introduces njs, the JavaScript engine for Nginx, explains its basic "Hello world" example and walks through advanced features such as filesystem APIs, asynchronous I/O, shared memory, response handling, logging, and the global namespace, all with concrete code snippets.
Introduction
JavaScript is known for flexibility across front‑end, back‑end, desktop and mobile. The article explores using JavaScript inside Nginx via the njs engine.
What is njs?
njs is a subset of JavaScript that runs directly in Nginx. It implements ECMAScript 5.1 strict mode and supports many ES6+ features, allowing familiar syntax to write Nginx modules for access control, security checks, and response‑header manipulation.
Typical Use Cases
Fine‑grained access control and security checks before upstream requests.
Response‑header manipulation to meet business requirements.
Asynchronous content handlers and filters to boost processing capacity.
Basic HTTP Example
A minimal njs script returns “Hello world!” and the corresponding Nginx configuration.
njs script (http.js)
function hello(r) {
r.return(200, "Hello world!");
}
export default {hello};Nginx configuration
load_module modules/ngx_http_js_module.so;
events {}
http {
js_import http.js;
server {
listen 8000;
location / {
js_content http.hello;
}
}
}Visiting the root URL triggers the script and returns “Hello world!”.
Advanced njs Features
Beyond basic request handling, njs provides filesystem APIs, asynchronous operations, shared memory, response handling, logging, and a global namespace.
Filesystem API
Common functions include: access() – check file permissions. open() – open files (sync/async). readdir() – read directory contents. realpath() – resolve absolute path. rename() – rename files or directories. unlink() – delete files. rmdir() – delete directories (recursive). stat() – get file status. symlink() – create symbolic links.
Asynchronous Processing
njs supports promises, enabling non‑blocking I/O. Example reads a file and returns different status codes based on accessibility.
function asyncExample(r) {
// Asynchronous file check
fs.promises.access('/path/to/file', fs.constants.R_OK).then(() => {
r.return(200, 'File is accessible');
}).catch(() => {
r.return(403, 'File is not accessible');
});
}
export default { asyncExample };Shared Memory
Shared memory zones let multiple worker processes exchange data.
// Set shared data
function setSharedData(r) {
const shared = ngx.shared.my_shared_zone;
shared.set('key', 'value');
r.return(200, 'Data set in shared memory');
}
// Get shared data
function getSharedData(r) {
const shared = ngx.shared.my_shared_zone;
const value = shared.get('key');
r.return(200, value || 'No data found');
}
export default { setSharedData, getSharedData };Responding to Clients
njs can send headers, body chunks, and finish the response.
function respondExample(r) {
r.sendHeader();
r.send('Hello, ');
r.send('world!');
r.finish();
}
export default { respondExample };Logging
Different log levels are available via ngx.log.
function logExample(r) {
ngx.log(ngx.INFO, 'This is an info message.');
ngx.log(ngx.WARN, 'This is a warning message.');
ngx.log(ngx.ERR, 'This is an error message.');
r.return(200, 'Logged messages');
}
export default { logExample };Global Namespace
Both njs and ngx expose global functions and variables.
function globalNamespaceExample(r) {
// Get njs version, e.g., '0.4.7'
njs.version;
ngx.log(ngx.INFO, 'Using njs version: ' + njs.version);
const shared = ngx.shared.my_shared_zone;
shared.set('key', 'value');
r.return(200, 'Global namespace example');
}
export default { globalNamespaceExample };Conclusion
The examples demonstrate how njs enables asynchronous processing, shared memory, client responses, logging, and global‑namespace usage, extending Nginx with the flexibility of JavaScript while retaining high performance.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Full-Stack Cultivation Path
Focused on sharing practical tech content about TypeScript, Vue 3, front-end architecture, and source code analysis.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
