
Security News
Lovable’s OJ Rewrites Vite’s Dev Server in Rust as AI Lowers the Cost of Forking Open Source
Lovable’s OJ rewrites Vite’s dev server in Rust, reducing memory use and preview times as AI lowers the cost of open source reimplementation.
@device-router/middleware-fastify
Advanced tools
Fastify middleware for DeviceRouter — device classification and rendering hints per request
Fastify middleware for DeviceRouter. Adds device classification and rendering hints to every request.
pnpm add @device-router/middleware-fastify @device-router/storage @fastify/cookie
For automatic probe injection:
pnpm add @device-router/probe
import Fastify from 'fastify';
import cookie from '@fastify/cookie';
import { createDeviceRouter } from '@device-router/middleware-fastify';
import { MemoryStorageAdapter } from '@device-router/storage';
const app = Fastify();
const { middleware, probeEndpoint } = createDeviceRouter({
storage: new MemoryStorageAdapter(),
});
await app.register(cookie);
app.post('/device-router/probe', probeEndpoint);
app.addHook('preHandler', middleware);
app.get('/', (req, reply) => {
const profile = req.deviceProfile;
if (profile?.hints.preferServerRendering) {
return reply.send(renderSSR());
}
if (profile?.hints.deferHeavyComponents) {
return reply.send(renderLite());
}
reply.send(renderFull());
});
app.listen({ port: 3000 });
preHandler hook that reads the session cookie, loads the profile from storage, and attaches it to req.deviceProfilereq.deviceProfile.hints and req.deviceProfile.tiers to adapt responsesAutomatically inject the probe <script> into HTML responses:
const { middleware, probeEndpoint, injectionMiddleware } = createDeviceRouter({
storage: new MemoryStorageAdapter(),
injectProbe: true,
probeNonce: 'my-csp-nonce', // optional
});
When injectProbe is enabled, injectionMiddleware is returned as an onSend hook. Register it to inject the script before </head>:
app.addHook('preHandler', middleware);
if (injectionMiddleware) {
app.addHook('onSend', injectionMiddleware);
}
Streaming responses: The
onSendhook receives the serialized payload as a string. If you stream responses viareply.raw, the hook is bypassed and injection is skipped. Add the probe<script>tag to your HTML shell manually instead.
const { middleware, probeEndpoint } = createDeviceRouter({
storage,
thresholds: {
cpu: { lowUpperBound: 4, midUpperBound: 8 },
memory: { midUpperBound: 8 },
},
});
| Option | Type | Default | Description |
|---|---|---|---|
storage | StorageAdapter | (required) | Storage backend for profiles |
cookieName | string | 'device-router-session' | Session cookie name |
cookiePath | string | '/' | Cookie path |
cookieSecure | boolean | false | Set Secure flag on the session cookie |
ttl | number | 86400 (24h) | Profile TTL in seconds |
rejectBots | boolean | true | Reject bot/crawler probe submissions |
thresholds | TierThresholds | Built-in defaults | Custom tier thresholds (validated at startup) |
injectProbe | boolean | false | Auto-inject probe into HTML |
probePath | string | — | Custom probe endpoint path |
probeNonce | string | ((req: FastifyRequest) => string) | — | CSP nonce for injected script |
fallbackProfile | FallbackProfile | — | Fallback profile for first requests |
classifyFromHeaders | boolean | false | Classify from UA/Client Hints |
onEvent | OnEventCallback | — | Observability callback for logging/metrics |
Pass an onEvent callback to receive events for classification, storage, bot rejection, and errors:
const { middleware, probeEndpoint } = createDeviceRouter({
storage,
onEvent: (event) => {
console.log(`[device-router] ${event.type}`, event);
},
});
See the Observability guide for details.
Use the individual pieces when you need fine-grained control over each component:
import {
createMiddleware,
createProbeEndpoint,
createInjectionMiddleware,
loadProbeScript,
} from '@device-router/middleware-fastify';
// Use only what you need
const hook = createMiddleware({ storage, thresholds });
const endpoint = createProbeEndpoint({ storage, ttl: 3600 });
const injection = createInjectionMiddleware({
probeScript: loadProbeScript(),
});
app.addHook('preHandler', hook);
app.addHook('onSend', injection);
app.post('/device-router/probe', endpoint);
loadProbeScript() reads the @device-router/probe bundle and optionally rewrites the endpoint URL via { probePath }. Thresholds passed to createMiddleware() are validated at creation time.
createDeviceRouter(options) — All-in-one setup returning { middleware, probeEndpoint, injectionMiddleware? }createMiddleware(options) — Standalone preHandler hook (validates thresholds)createProbeEndpoint(options) — Standalone probe endpoint handlercreateInjectionMiddleware(options) — Standalone onSend injection hookloadProbeScript(options?) — Load the minified probe script for use with createInjectionMiddleware()@fastify/cookie 11.xMIT
FAQs
Fastify middleware for DeviceRouter — device classification and rendering hints per request
The npm package @device-router/middleware-fastify receives a total of 0 weekly downloads. As such, @device-router/middleware-fastify popularity was classified as not popular.
We found that @device-router/middleware-fastify demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Lovable’s OJ rewrites Vite’s dev server in Rust, reducing memory use and preview times as AI lowers the cost of open source reimplementation.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.