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

paraluna

v0.2.1

Published

![npm](https://img.shields.io/npm/v/paraluna)

Readme

🌘 Paraluna — Reactive Home Automation ☂️

npm

Paraluna is a set of building blocks to implement home automation using FRP with typescript (and rxjs).

Since every input to your home-automation is typically an event, incoming events can be transformed and written back to devices (e.g. a switch "on" event needs to be written to a "light").

Given that everything is an event you can apply Event Sourcing to build up arbitrary complex "application" state with ease.

On top of that, the model to consume events and return "commands" (to be written to mqtt etc.) makes it possible to model home-automation as pure functions and thus even enable unit testing.

Sinks and Sources

The idea to communicate with the outside is to think of "sources" as side-effects for input (of events) and "sinks" as side-effects for output (of "commands"). So sources are streams of events or rather values, like triggers or sensors which provide read-only values. Sinks on the other side allow writing values, e.g. a bulb that receives a brightness value.

This basic idea of "sinks" and "sources" is inspired by the cycle.js framework.

RXJS

Building upon rxjs your automation "connects" to an Observable of events and returns observables of "commands" ({state: "ON"} via mqtt topic livingroom/light).

Given RXJS Operators it's easy to build complex automations (think of the typical reactive/rxjs examples how to implement autocomplete with debounce etc.).

When to use paraluna?

  • when modeling your home automation tasks as reactive streams, sinks & sources and event sourced fits your way of thinking
  • when programming-capabilities of other platforms are not sufficient (e.g. home-assistant)
  • when writing typescript/code is more convenient than writing yaml, using Node-RED
  • you want to unit-test your automations
  • you like rxjs and typescript

Integration

Paraluna works great with mqtt (e.g. zigbee2mqtt), but also supports home-assistant. Supporting other "systems" is just a matter of defining appropriate drivers (sources and sinks).

Typically, devices can be controlled directly via mqtt/zigbee2mqtt, but to reuse automation/scripts/scenes it makes sense to use home-assistant as proxy.

Also, home-assistant offers additional "sensors" (or entities to be precise in hass-speak) via it's integrations that are not available via mqtt, e.g. Weather Information, Device Information (from mobile phones), sunset etc.

zigbee2mqtt

Required settings

  • advanced.last_seen ISO_8601 not required directly, but used in type definitions
  • device_options.retain true simplifies usage, especially startup
Device specific

Assumes defaults

  • base topic "zigbee2mqtt" (mqtt.base_topic)
  • json message format (exerimental.output "json" or "attribute_and_json")

home-assistant

  • uses hasso to access home-assistant

Examples

Run examples either via nodemon (during development to watch for changes) or via ts-node directly.

The examples expect the following environment variables to be set.

  • HASS_TOKEN
  • HASS_URL
  • MQTT_HOST
  • MQTT_USER
  • MQTT_PASSWORD

With direnv the proper values may be set into a local .envrc file:

# copy the example file
$ cp .envrc.local{.sample,}
# set custom values
$ $EDITOR .envrc.local
# if not yet done, allow the .envrc file
$ direnv allow

ts-node

$ cd examples
$ ts-node index.ts

nodemon

To make nodemon/ts-node work with typescript project references and also watching changes in src, calling nodemon is a bit counter-intuitive. It needs to be called in project-root, but the examples path needs to be omitted.

$ nodemon index.ts