
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@attaryz/fastify-devtools
Advanced tools
Fastify DevTools plugin: dashboard, entry view, metrics, replay, WebSocket capture, Redis tracking, and storage
Fastify DevTools plugin: live request dashboard, entry details view, copy helpers (URL, cURL, fetch()), replay via fastify.inject, basic metrics, WebSocket message capture, Redis cache tracking, and optional Mongo persistence. Ships with zero dependencies at runtime (aside from Fastify) and can be plugged into any Fastify app.
@attaryz/fastify-devtools@0.3.x)Note: Fastify v5 requires Node.js 20+. See UPGRADE-TO-V5.md for migration guide.
npm install @attaryz/fastify-devtools
Or with Yarn:
yarn add @attaryz/fastify-devtools
Peer dependencies:
Register the plugin in your Fastify app:
import Fastify from "fastify"
import fastifyDevtools from "@attaryz/fastify-devtools"
const app = Fastify({ logger: true })
app.register(fastifyDevtools, {
enabled: true,
basePath: "/__devtools",
bufferSize: 200,
token: process.env.DEVTOOLS_TOKEN, // optional access token
maxBodyBytes: 10_000, // default 10KB truncation threshold
persistEnabled: false, // set true to persist to Mongo (requires fastify.mongoose)
persistTtlDays: 14, // TTL for persisted entries
slowMs: 1000, // UI only, for SLOW badges
captureWebSockets: true, // capture WebSocket messages (default: true)
trackRedisCache: true, // track Redis cache hits/misses (default: true)
})
// Example routes ...
app.listen({ port: 3000 })
Browse to:
http://localhost:3000/__devtoolshttp://localhost:3000/__devtools/entry/:idIf token is set, you can also pass it as a query param ?token=... or header x-devtools-token.
If you want to persist entries in MongoDB, decorate Fastify with a connected Mongoose instance before registering this plugin. For example, with @fastify/mongoose or your own decoration:
import mongoose from "mongoose"
await mongoose.connect(process.env.MONGO_URI!)
;(app as any).mongoose = mongoose // decorate
app.register(fastifyDevtools, { persistEnabled: true, persistTtlDays: 7 })
The plugin will create a DevtoolsEntry model and manage TTL index on tsDate.
The plugin automatically detects and captures WebSocket messages when using:
@fastify/websocket - Captures raw WebSocket messagessocket.io - Captures Socket.io eventsImportant: DevTools must be registered after the WebSocket plugin for tracking to work:
import Fastify from "fastify"
import websocket from "@fastify/websocket"
import fastifyDevtools from "@attaryz/fastify-devtools"
const app = Fastify({ logger: true })
// 1. Register WebSocket plugin FIRST
await app.register(websocket)
// 2. Register DevTools AFTER
await app.register(fastifyDevtools, {
enabled: true,
basePath: "/__devtools",
captureWebSockets: true
})
// 3. Add your WebSocket routes
app.register(async function (fastify) {
fastify.get('/ws', { websocket: true }, (connection, req) => {
connection.socket.on('message', message => {
console.log('Received:', message.toString())
connection.socket.send('Echo: ' + message)
})
})
})
await app.listen({ port: 3000 })
WebSocket messages are displayed in a separate tab in the dashboard with:
When Redis is detected (via fastify.redis or fastify.ioredis decorators), the plugin automatically tracks all cache operations without any code changes:
import Fastify from "fastify"
import redis from "@fastify/redis"
import fastifyDevtools from "@attaryz/fastify-devtools"
const app = Fastify({ logger: true })
// 1. Register Redis plugin
await app.register(redis, {
host: '127.0.0.1',
port: 6379
})
// 2. Register DevTools (will auto-wrap Redis client)
await app.register(fastifyDevtools, {
enabled: true,
basePath: "/__devtools",
trackRedisCache: true
})
// 3. Use Redis normally - tracking happens automatically!
app.get('/data/:id', async (request, reply) => {
// No special code needed - just use fastify.redis normally
const cached = await app.redis.get(`data:${request.params.id}`)
if (cached) {
return JSON.parse(cached) // Automatically tracked as CACHE HIT ✓
}
const data = { id: request.params.id, value: 'fresh data' }
await app.redis.set(
`data:${request.params.id}`,
JSON.stringify(data),
'EX',
3600
)
return data // Automatically tracked as CACHE MISS ✗
})
await app.listen({ port: 3000 })
Supported Redis operations:
GET - Tracked with cache hit/miss statusSET - Tracked as cache writeDEL - Tracked as cache deletionThe dashboard will show:
No code changes required! The plugin automatically wraps your Redis client when it detects fastify.redis or fastify.ioredis.
GET {basePath} — Dashboard HTMLGET {basePath}/requests — Last 100 in-memory entries (JSON)GET {basePath}/status — Status (buffer length, SSE clients, persistence state)GET {basePath}/events — Server-Sent Events stream for live updatesPOST {basePath}/clear — Clear in-memory bufferGET {basePath}/requests/:id — Single entry JSONGET {basePath}/entry/:id — Entry HTML viewGET {basePath}/websockets — Last 100 WebSocket messages (JSON)GET {basePath}/websockets/connections — Active WebSocket connectionsGET {basePath}/redis/status — Redis detection and statuspersistEnabled):
GET {basePath}/store/requests?limit&method&status&q&from&to&beforeIdPOST {basePath}/store/clearGET {basePath}/store/export.json?method&status&q&from&to&limitGET {basePath}/store/export.ndjson?method&status&q&from&to&limitfastify.inject@fastify/websocket and Socket.ioThis package ships precompiled views in dist/views. When you run build locally:
yarn build
That will:
dist/src/views/ to dist/views/token to require x-devtools-token or ?token=....authorization, cookie) and fields (password, token, jwt, secret). Review and extend as needed.MIT
FAQs
Fastify DevTools plugin: dashboard, entry view, metrics, replay, WebSocket capture, Redis tracking, and storage
We found that @attaryz/fastify-devtools 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.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.