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

@jini-ai/cms

v0.3.9

Published

Content-model capability for Jini-hosted products: framework-free contracts, ports, and domain services in `/core` and per-domain subpaths; Node-bound persistence adapters in `/server`.

Readme

@jini-ai/cms

Content-model capability for Jini-hosted products.

Status: implemented, port in progress. Created 2026-08-02 as an empty shell; the port has been landing since. Measured 2026-09-05 at v0.3.4: 131 non-test source files / 21,718 lines under src/ (34,938 including tests), 11 domain trees, and 14 public subpath exports wired in package.json. Some domain modules named under Port inventory have not moved yet — check src/ and the exports map for what is actually reachable today rather than trusting this paragraph's counts.

Layers

| subpath | runtime | contents | |---|---|---| | . / ./core | universal | Content contracts and types, ports, pure domain services, kernel registries. No Express, no node:*, no DOM. | | ./server | node | Concrete adapters for the ports in /core: SQLite/Postgres repositories, filesystem blob stores, image transformers. |

/server depends on /core. The reverse is a boundary violation — if a core module wants something from /server, the dependency is backwards and the fix is a port (interface) in core, not a widened export.

./server means the Node-bound layer, not the HTTP server — same convention as @jini-ai/admin. HTTP transport is out of scope; Jini has @jini-ai/http-kit and @jini-ai/server.

Why the split exists before there is any code to split

The source of this port is an existing CMS runtime, and the boundary is drawn where a measured defect was.

There, the content model and its HTTP composition root share one src/ tree with nothing enforcing a boundary between them. Measured 2026-08-02:

  • 53 import edges point into the composition root. 22 of them are domain modules importing a 454-line RouteDeps type whose first line is import type { Express } from "express".
  • Git history shows the cost: no content module could be changed without also changing the server. features/theme and server co-changed in 71% of commits touching the former; identity and server in 45%.
  • 33 of 38 modules formed a single strongly-connected component — none could be extracted without dragging the other 32.

The decomposition itself was sound (propagation cost 11%, a textbook Martin instability gradient, domain modules that essentially never co-change with each other). What was missing was enforcement. Full analysis: ADS-memory/reports/refactors/2026-08-02-module-graph-analysis.md in the originating repo.

A package's exports map is precisely the enforcement a single src/ tree cannot provide. A consumer of @jini-ai/cms/core physically cannot reach a Node adapter, and /core physically cannot import a transport type, because the module resolver refuses. Porting into this shape from the first commit means that failure mode cannot recur here.

Port inventory

The kernel went first — the source repo's src/core/{ports,commands,events,tools} — because every domain module depends on it. Domain modules followed in no particular order: the source repo's git history shows they essentially never co-change with each other, so each ports independently without coordination.

Landed (directories under src/, each with its own subpath export): core, content-types, entries, identity, media, navigation, presentation, settings, taxonomy, workspace, and the server adapter layer.

Still to move: post, seo, comments, forms, redirects, widgets, newsletter, members. (widgets has an exports entry but no src/widgets/ tree yet.)

Explicitly not ported:

  • src/server/** — Express composition root; superseded by @jini-ai/http-kit / @jini-ai/server.
  • Admin UI — @jini-ai/admin already owns that surface.

When porting tests, git mv them rather than re-authoring: re-authoring costs a full pass and still loses coverage.

Scripts

pnpm --filter @jini-ai/cms build
pnpm --filter @jini-ai/cms typecheck
pnpm --filter @jini-ai/cms test

Open cleanup

  • Add coverage thresholds. vitest.config.ts still has none. That was a deliberate omission while the package was a placeholder; it no longer is, so the reason has expired. Set them against what the ported modules actually measure — siblings run 98–100%.
  • Delete CMS_SERVER_LAYER (src/server/index.ts). It existed only to give the /server entry point something real to resolve, and real exports have since landed. Its /core counterpart CMS_CORE_LAYER is already gone.