npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@functionkit/functions-framework

v0.1.1

Published

fnkit Functions Framework for Node.js — invoke functions via MQTT topics instead of HTTP

Readme

fnkit — MQTT Functions Framework for Node.js

An open source FaaS (Function as a Service) framework for writing portable Node.js functions invoked via MQTT messages instead of HTTP requests.

Adapted from the Google Cloud Functions Framework for Node.js.

How It Works

Instead of standing up an HTTP server, fnkit connects to an MQTT broker and subscribes to a topic based on your function name. When a message arrives, your function is invoked with familiar (req, res) arguments.

MQTT Message → Broker → fnkit subscribes → Your Function(req, res) → Optional MQTT Response

Quick Start

1. Create your function

// index.js
const fnkit = require('@functionkit/functions-framework')

fnkit.mqtt('hello', (req, res) => {
  console.log('Received:', req.body)
  res.send({ message: `Hello, ${req.body.name || 'World'}!` })
})

2. Install the framework

npm install @functionkit/functions-framework

3. Run it

npx fnkit --target=hello --broker=mqtt://localhost:1883

Your function is now listening on topic fnkit/hello. Publish a message to that topic and your function will be invoked.

4. Test it

# In another terminal, publish a message
mosquitto_pub -h localhost -t fnkit/hello -m '{"name": "Max"}'

Function Signature

fnkit uses the same (req, res) pattern as the HTTP Functions Framework:

fnkit.mqtt('myFunction', (req, res) => {
  // req — MQTT request object
  // res — MQTT response object
})

Request Object (req)

| Property | Type | Description | | ----------------- | ------------------------ | ---------------------------------------------------------------- | | topic | string | The full MQTT topic the message was received on | | payload | Buffer | The raw message payload | | body | any | Parsed payload (JSON if possible, otherwise raw string) | | params | Record<string, string> | Topic segments beyond the function name (wildcard subscriptions) | | properties | object | MQTT v5 user properties (analogous to HTTP headers) | | headers | object | Alias for properties | | correlationData | Buffer | MQTT v5 correlation data | | responseTopic | string | MQTT v5 response topic | | contentType | string | MQTT v5 content type | | messageId | number | MQTT packet identifier | | qos | 0 \| 1 \| 2 | QoS level of the received message | | retain | boolean | Whether the message was retained | | executionId | string | Unique execution ID for this invocation |

Response Object (res)

| Method | Description | | ----------------- | -------------------------------------------------------------------------------- | | send(data) | Publish response. Accepts string, Buffer, or object (auto JSON-serialized) | | json(obj) | Publish JSON response (sets content type) | | status(code) | Set a status code in response user properties (chainable) | | set(key, value) | Set an MQTT v5 user property on the response (chainable) | | end() | Signal completion without sending a response |

Fire-and-Forget

Functions don't have to send a response. Just process the message and return:

fnkit.mqtt('logger', (req, res) => {
  console.log('Event received:', req.body)
  // No res.send() needed — fire and forget
})

Async Functions

Async functions are fully supported:

fnkit.mqtt('process', async (req, res) => {
  const result = await doSomethingAsync(req.body)
  res.send(result)
})

Response Topics

Responses are published to (in order of precedence):

  1. MQTT v5 Response Topic — If the incoming message has a responseTopic property
  2. Defaultfnkit/{functionName}/response

Correlation data from the incoming message is automatically forwarded.

Configuration

Configure via CLI flags or environment variables. CLI flags take precedence.

| CLI Flag | Environment Variable | Description | Default | | ----------------------- | -------------------------- | ----------------------------------------- | ----------------------- | | --broker | MQTT_BROKER | MQTT broker URL (mqtt:// or mqtts://) | mqtt://localhost:1883 | | --target | FUNCTION_TARGET | Name of the function to invoke | function | | --topic-prefix | MQTT_TOPIC_PREFIX | Topic prefix before function name | fnkit | | --source | FUNCTION_SOURCE | Path to function source code | cwd | | --qos | MQTT_QOS | Default QoS level (0, 1, 2) | 1 | | --client-id | MQTT_CLIENT_ID | MQTT client identifier | auto-generated | | --username | MQTT_USERNAME | Broker username | — | | --password | MQTT_PASSWORD | Broker password | — | | --ca | MQTT_CA | Path to CA certificate (TLS) | — | | --cert | MQTT_CERT | Path to client certificate (mTLS) | — | | --key | MQTT_KEY | Path to client private key (mTLS) | — | | --reject-unauthorized | MQTT_REJECT_UNAUTHORIZED | Reject unauthorized TLS certs | true |

package.json Configuration

{
  "scripts": {
    "start": "fnkit --target=hello --broker=mqtt://localhost:1883"
  }
}

Security

TLS (Port 8883)

fnkit --target=hello --broker=mqtts://broker:8883 --ca=/path/to/ca.crt

mTLS (Mutual TLS)

fnkit --target=hello \
  --broker=mqtts://broker:8883 \
  --ca=/path/to/ca.crt \
  --cert=/path/to/client.crt \
  --key=/path/to/client.key

Username/Password

fnkit --target=hello --broker=mqtt://broker:1883 --username=user --password=pass

MQTT v5 Features

fnkit uses MQTT v5 by default, enabling:

  • Response Topics — Request-reply pattern via responseTopic property
  • Correlation Data — Match responses to requests
  • User Properties — Key-value metadata on messages (like HTTP headers)
  • Content Type — Indicate payload format

Comparison with HTTP Functions Framework

| Aspect | HTTP Framework | fnkit | | ------------ | ------------------------------------- | ------------------------------------------ | | Transport | HTTP server (Express) | MQTT client (subscribes to broker) | | Routing | URL path → function | Topic fnkit/{name} → function | | Request | Express req (URL, headers, body) | MqttRequest (topic, properties, payload) | | Response | Express res (status, headers, body) | MqttResponse (publish to reply topic) | | Invocation | Per HTTP request | Per MQTT message | | Signature | (req, res) => {} | (req, res) => {} ✅ Same pattern! | | Registration | functions.http('name', handler) | fnkit.mqtt('name', handler) | | Config | --port, --target | --broker, --target, --topic-prefix |

Architecture

See the design docs for:

  • Architecture — System overview and components
  • Contract — The MQTT Functions Framework contract (language-agnostic)
  • Decisions — Design decisions and rationale

Based On

This framework is adapted from the Google Cloud Functions Framework for Node.js (Apache-2.0 License). The function registry, loader, and options parsing patterns are reused. The HTTP transport layer has been replaced with MQTT.

License

Apache-2.0 — See LICENSE for details.