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

@vtechcom/hexcore

v2.0.0-beta.1

Published

Boot and operate Cardano Hydra Heads — control-plane and web UI in one command

Readme

Hexcore v2

Monorepo for booting and operating Hydra Heads on Cardano — control-plane and web UI in one repository.

v2 is a rewrite of hydra-hexcore focused on one thing: going from git clone to a running Hydra Head without a checklist.


What changed from v1

| | v1 | v2 | |---|---|---| | Repos | 3 separate (hydra-hexcore, hexcore-ui, hexcore-cli) | 1 monorepo | | Key material | You generated Hydra + Cardano keys yourself and POSTed them in | Generated server-side on head creation | | Database | MySQL + Redis, provisioned before first run | Embedded SQLite in the state dir | | Config | ~30 env vars, unvalidated | zod-validated, works with a single key set | | Setup failures | Surfaced as stack traces at random later points | pnpm doctor checks everything up front | | Container names | Derived from DB ids (hexcore-hydra-node-7) | Deterministic (hexcore-h1-n0) | | Ports | Scan upward from 10005 until free | Deterministic block per head | | Failed boot | Left orphaned containers behind | Rolls back every container it created | | Head state | Only "is the container up?" | Real Hydra state probed over WebSocket | | Types | Duplicated between API and UI | Single zod schema in packages/shared |


Requirements

  • Node >= 22
  • Docker running and reachable by your user
  • Nothing else. The offline backend runs a real multi-node Hydra Head with no chain, no credential and no waiting — a Blockfrost project id (free, https://blockfrost.io) or a synced cardano-node socket is only needed when you want heads on the real chain.

No MySQL. No Redis. No RabbitMQ.


Quick start

npm install -g @vtechcom/hexcore@beta
hexcore

This is a beta, published under the beta tag rather than latest — so npm i -g @vtechcom/hexcore without @beta will not resolve until 2.0.0 is final. The package is scoped; the command it installs is plain hexcore. See CHANGELOG.md for what that means and what is known broken.

Building it from this checkout gives the identical artefact:

pnpm install
node scripts/pack-cli.mjs        # builds, packs, and verifies the tarball installs
npm i -g ./vtechcom-hexcore-2.0.0-beta.1.tgz

That starts the control-plane and serves the web UI from the same port, and prints a setup link with a one-time token in it:

Hexcore is not configured yet. Open this link to finish setup:
  http://localhost:4000/setup?token=…

Open it, answer four questions, and you have a working installation. Nothing to edit by hand; there is no .env to copy.

The token is not ceremony. Setup has to be reachable without a login, because it is where the login is created — so on any interface but loopback, whoever reaches the port first would otherwise choose the admin password.

Prefer a terminal, or setting up a machine with no browser pointed at it?

hexcore init      # the same questions, in the shell

Everything the CLI does

hexcore                 # start the control-plane and the web UI
hexcore init            # configure from the terminal
hexcore config          # every setting, and which layer it came from
hexcore doctor          # check Docker, chain access and permissions
hexcore reset           # forget the configuration; heads and keys are kept
hexcore clean           # delete every head and its containers; keys are kept
hexcore clean --all     # delete everything, including keys

Where configuration comes from

Four layers, highest wins:

  1. a real environment variable — for containers and CI
  2. a .env in the current directory
  3. ~/.hexcore/config.json, written by the setup wizard or hexcore init
  4. the built-in defaults

hexcore config prints the value and the layer that supplied it, which is the only useful answer to "I changed that setting and nothing happened".

From a checkout

pnpm install
pnpm build
pnpm start

Same first-run experience — the setup link is printed on boot. pnpm doctor runs the preflight checks on their own.

On Apple Silicon, read this before creating a head

Every hydra-node image the Hydra core team publishes is amd64-only. On a Mac with an M-series chip the 2.2.0+ image runs under Rosetta, stalls inside a cryptographic warm-up before it installs a logger, and fails as a plain readiness timeout with nothing in the log to explain it.

Hexcore warns about this while you are still choosing, and on macOS/arm64 it recommends aniadev9/hydra-node:2.3.0-arm64 — the same 2.3.0 source rebuilt for arm64, which starts natively in 0.47s.

That is a community image on a personal Docker Hub account, not one this project controls. It is offered because the only upstream image that boots there is 2.1.x, which carries a double-spend defect. If you would rather not depend on someone else's registry, rebuild 2.3.0 yourself and push it as you/hydra-node:2.3.0-arm64 — it resolves to the same profile, with the same flags and the same warnings. This recommendation goes away the moment upstream publishes multi-arch images (#7).

Create and start a head

TOKEN=$(curl -s -X POST localhost:4000/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"<your password>"}' | jq -r .data.token)

# Creates the head AND generates every key it needs.
curl -X POST localhost:4000/api/heads \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"my-head","nodeCount":3}'

The response contains one cardanoAddress per node. Fund each of them with test ADA (https://docs.cardano.org/cardano-testnets/tools/faucet) — a Hydra node cannot commit without UTxOs.

curl -X POST localhost:4000/api/heads/1/start  -H "Authorization: Bearer $TOKEN"
curl     localhost:4000/api/heads/1/status     -H "Authorization: Bearer $TOKEN"

Layout

apps/
  control-plane/        NestJS + Fastify adapter
    src/
      config.ts         zod-validated environment
      preflight.ts      startup checks (also `pnpm doctor`)
      hydra/keys.ts     Hydra + Cardano key generation
      hydra/head.service.ts   head lifecycle: create/start/stop/reset
      hydra/ws-client.ts      live Hydra state over WebSocket
      docker/           container orchestration + rollback
      db/               SQLite schema and repositories
      controllers/      REST API (Swagger annotated)
  web/                  Nuxt SPA (ssr:false) — Tailwind v4 + shadcn-vue

packages/
  shared/               zod schemas + types used by BOTH sides

docs/                   UI specification and architecture notes
sketches/               HTML mockups the UI design was chosen from

Web UI

Built, and served by the control-plane on the same port when SERVE_WEB=true — which is what hexcore does. It builds to static files (nuxt generate), so there is no second process and no second port.

State directory

Everything mutable lives under STATE_DIR. Unset, that is ~/.hexcore — unless a .hexcore already exists in the working directory, which is adopted instead so an existing checkout keeps the heads and keys it already has.

~/.hexcore/
  config.json                   settings from the wizard (0600)
  hexcore.db                    SQLite
  secrets.json                  jwt secret + admin password hash (0600)
  install-id                    distinguishes this installation's containers
  heads/head-1/
    keys/n0.hydra.sk            0600, text-envelope format
    keys/n0.cardano.sk
    persistence/n0/             hydra-node state
    protocol-parameters.json

hexcore config prints the resolved path. Back this up to preserve funded addresses — the Cardano signing keys exist here and nowhere else. hexcore clean --all deletes it, which is why that one is CLI-only and asks you to type your machine's name.


API

| Method | Path | Purpose | |---|---|---| | GET | /health | Liveness + Docker reachability (public) | | POST | /api/auth/login | Get a bearer token (public) | | GET | /api/heads | List heads with their nodes | | POST | /api/heads | Create a head, generating all keys | | GET | /api/heads/:id | Head detail | | PATCH | /api/heads/:id | Update settings (applied on next start) | | POST | /api/heads/:id/start | Boot every node, wait until ready | | POST | /api/heads/:id/stop | Remove containers, keep keys + state | | POST | /api/heads/:id/restart | Stop then start | | POST | /api/heads/:id/reset | Wipe persistence (includeKeys for keys too) | | DELETE | /api/heads/:id | Delete head, containers and state | | GET | /api/heads/:id/status | Live state probed from the nodes | | GET | /api/heads/:id/nodes/:index/logs | Tail a node's container log | | GET | /api/heads/:id/events | Lifecycle audit trail |

Every response is { ok: true, data } or { ok: false, error: { code, message } }.


Troubleshooting

Run pnpm doctor first — it diagnoses most problems with a concrete fix.

DOCKER_UNAVAILABLE — Docker is not running, or your user cannot use the socket. On Linux: sudo usermod -aG docker $USER, then log out and back in.

CHAIN_PROVIDER_ERROR / Blockfrost 403 — the key does not match CARDANO_NETWORK. A key starting with preprod only works on preprod.

Node never becomes ready — check its log: GET /api/heads/:id/nodes/0/logs. The usual cause is an unfunded Cardano address; the head cannot proceed without UTxOs at each node's address.

Port already in use — change PORT_BASE; each node needs 10 ports.


Development

pnpm dev            # control-plane + web in watch mode
pnpm dev:api        # control-plane only
pnpm test           # unit tests
pnpm doctor         # environment diagnostics

Licence

Apache License 2.0. Use it, ship it, fork it, build a product on it — the licence also grants you a patent licence from the contributors, which is the main reason to prefer it over MIT for infrastructure.

Two things it does not cover, because they are not ours to license:

  • hydra-node is a separate project (cardano-scaling/hydra, Apache-2.0). Hexcore runs its published container images; it does not vendor or modify them.
  • aniadev9/hydra-node:2.3.0-arm64, the community rebuild recommended on Apple Silicon, is a third-party image on a personal Docker Hub account. It is a rebuild of upstream's Apache-2.0 source, but this project does not control that registry — see the Apple Silicon section above.