Netjet Express Preload Middleware
raw JSON →Netjet is an Express.js middleware designed to automatically inject `<link rel="preload">` headers into HTML responses. These headers enable web browsers to perform early resource fetching, which can significantly improve page load performance by fetching critical assets like scripts, styles, and images before the browser's main parsing engine discovers them. The package is currently at version 1.4.0 and appears to be in an active maintenance state, with recent updates focusing on bug fixes and additional preload attributes. It differentiates itself by offering automatic, configurable scanning of HTML responses for subresources to preload, and leverages an `lru-cache` for efficient caching of resource analysis. Its primary use case is optimizing web application delivery for HTTP/2 and modern browsers.
Common errors
error TypeError: app.use() requires middleware functions but got a [object Undefined] ↓
netjet() to obtain the middleware function, even if you don't pass any options. Correct usage is app.use(netjet()) or app.use(netjet({ /* options */ })). error No preload headers are generated, despite serving HTML with assets. ↓
netjet is placed *before* your static file server (express.static) and other HTML-serving routes. Also, check the netjet options; ensure that images: true, scripts: true, and styles: true are explicitly set if you want those resources to be preloaded. error ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client ↓
netjet is placed early in the middleware chain, specifically before any middleware or route handlers that might explicitly call res.send(), res.end(), or res.setHeaders() in a way that bypasses Netjet's interception mechanism. Warnings
gotcha The package is marked as 'stability-experimental' in its README badge. While actively maintained, this suggests the API might evolve, and future versions could introduce breaking changes or significant behavioral shifts without strict adherence to semantic versioning for major increments. ↓
breaking Prior to version 1.1.3, URLs included in generated `Link` preload headers were not consistently or correctly encoded. This could lead to malformed headers, HTTP/2 push failures, or browsers failing to fetch preloaded resources, especially for URLs containing special characters. ↓
gotcha Netjet relies on intercepting and modifying the HTML response to inject preload headers. It must be placed *before* any middleware that serves the HTML content (e.g., `express.static`, templating engines, or routes sending HTML). If placed after, it will not be able to process the response and add headers. ↓
gotcha The `cache` option, which uses `lru-cache` internally, can lead to uncontrolled memory growth if `cache.max` is not configured. Without a maximum number of items, the cache will continuously store resource analysis results, potentially consuming excessive memory over time. ↓
Install
npm install netjet yarn add netjet pnpm add netjet Imports
- netjet wrong
import netjet from 'netjet';correctconst netjet = require('netjet'); - NetjetOptions
/** @typedef {import('netjet').NetjetOptions} NetjetOptions */ - netjet() middleware wrong
app.use(netjet);correctapp.use(netjet({ directives: ['nopush'] }));
Quickstart
const express = require('express');
const netjet = require('netjet');
const path = require('path');
const fs = require('fs');
const app = express();
const port = 1337;
const root = path.join(__dirname, 'public'); // Assuming a 'public' folder
// Create a 'public' directory and dummy files if they don't exist
if (!fs.existsSync(root)) {
fs.mkdirSync(root);
}
fs.writeFileSync(path.join(root, 'style.css'), 'body { color: blue; }');
fs.writeFileSync(path.join(root, 'image.png'), '/* dummy image content */');
fs.writeFileSync(path.join(root, 'script.js'), 'console.log("Script loaded!");');
app
.use(netjet({
// Enable parsing for images, scripts, styles (often true by default, but explicit for clarity)
images: true,
scripts: true,
styles: true,
// Example option from v1.3.0 notes to add custom attributes
directives: ['nopush'],
// Recommended: configure an LRU cache to prevent unbounded memory usage
cache: { max: 500 }
}))
.use(express.static(root)) // Serve static files after Netjet has a chance to process responses
.get('/', (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>Netjet Demo</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>Hello from Netjet!</h1>
<img src="/image.png" alt="demo image">
<script src="/script.js"></script>
</body>
</html>
`);
})
.listen(port, () => {
console.log(`Netjet demo app listening on http://localhost:${port}`);
console.log(`Open http://localhost:${port} in your browser and inspect network/headers for preload links.`);
});