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

@finamx/dev-host

v0.6.0

Published

Local developer host for `finamx-ext dev`: a prebuilt static React board that embeds your extensions through the real `@finamx/host-bridge`, the built-in base extensions, and the asset locator the CLI uses to find them. It is loaded by the CLI as an optio

Readme

@finamx/dev-host

Local developer host for finamx-ext dev: a prebuilt static React board that embeds your extensions through the real @finamx/host-bridge, the built-in base extensions, and the asset locator the CLI uses to find them. It is loaded by the CLI as an optional dependency and is not used directly.

npm i -D @finamx/dev-host

Version 0.1.0, not yet published.

Embedding the board (0.4.0)

import '@finamx/dev-host/styles.css'; // scoped to .dh-root, never restyles the page
import { DevHostShell, CLOUD_CAPS, initStoreWithClient } from '@finamx/dev-host/ui';

initStoreWithClient(myControlClient); // any ControlClient, no CLI secret needed
<DevHostShell caps={CLOUD_CAPS} panels={[{ id: 'edges', label: 'Связи', element: <Edges /> }]} />;

Capability flags (BoardCaps): autoPlace (project extensions place themselves), s2s, catalogAdd, baseAdd, edges, mockEditor, cspFeed and themeTarget (document writes the theme variables on <html>, container on the board root only). LOCAL_CAPS keep the finamx-ext dev behaviour; CLOUD_CAPS is for the cabinet. Cloud route types live in @finamx/dev-host/cloud-protocol.

Security model

  • Every server binds to loopback (127.0.0.1) only.
  • A per-run secret travels in the URL fragment of the link printed by the CLI and is required as Authorization: Bearer on every control call.
  • Host and Origin headers are checked against DNS rebinding and CSRF; the board page runs under a strict CSP.
  • The CLI never hands out the developer key: not to the UI, the extension origins, NDJSON or logs, and not through the environment of the processes it starts. The project watch script is your own code and runs with your user's permissions (it can read the credentials file like any program you run); the CLI says so in one line when it starts it, and --no-watch skips it.
  • Only mocks derived from the host domain are served; real data never enters the dev host.

NDJSON events (finamx-ext dev --json)

Every line on stdout is one JSON object with v: 1, ts and type. Strings that come from widgets, hosts or HTTP bodies are sanitised (control characters, bidi marks, length caps). The developer key and the board secret never appear. Nothing else is written to stdout.

| type | when | fields | bus log row | |------|------|--------|-------------| | dev.ready | the board and all origins are listening | url, hostId, status | — | | dev.stopped | the CLI shuts the dev host down | status | — | | bus.publish | a widget publishes a topic through the broker | extensionId, topic, to, schema, fields | шина | | bus.subscribe | a widget subscribes to a topic | extensionId, topic | шина | | invoke | a widget calls a domain method | extensionId, method, result, code, mock, mockPath, scope | invoke | | schema.error | a published payload fails the topic schema | extensionId, topic, schema, fields | ошибки | | scope.denied | a call is denied because the scope is not granted | extensionId, method, topic, scope, code | ошибки | | csp.violation | a frame reports a CSP violation | extensionId, directive, blockedUrl | ошибки | | build | the project watch build starts, succeeds or fails | extensionId, status, message | — | | domain.changed | the poll sees a new domainHash for the selected host | hostId, previousHash, domainHash | — | | domain.poll_failed | the domain poll failed; the cache is kept | hostId, message | — | | domain.refreshed | "Обновить домен" pulled the domain | hostId, previousHash, domainHash, diff | — | | consent.changed | a consent toggle was switched | extensionId, scope, granted | — | | bridge.handshake | a frame completed the bridge handshake | extensionId | — | | tokens.delivered | UI tokens were delivered to a frame | extensionId, theme | — | | s2s.token | a local platform.s2s.user.v1 token was issued | extensionId, dir, aud, exp, scope | s2s | | s2s.pull | the local pull endpoint answered | method, result, code, mock | s2s | | s2s.push | a signed push was sent to the manifest webhook | extensionId, url, status, payload | s2s | | catalog.added | a catalog artifact was verified and added | extensionId, status | — | | error | any other dev host error | code, message | ошибки |

Built-in base extensions

  • Instrument picker: publishes fdc3.instrument.
  • JSON inspector/table: shows the payloads of any chosen topic.
  • Topic mapper: maps a source topic to a target topic with JS code. The code runs through the host repl.js method backed by @finamx/repl, because the platform CSP forbids eval inside a widget. The function may be async; a result that is undefined or cannot be sent as JSON is shown as an error and nothing is published. repl.js is the dev host's own method and is offered to this built-in widget only: a project or catalog extension that lists repl.js gets SCOPE_DENIED unless the selected host domain itself declares a repl.js method (the @manifest domain never does). The code runs in a worker on the board origin whose response CSP forbids all network access; that header is the boundary.

All of them go through the same frame, origin and CSP path as author extensions.