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

@reventlessdev/reventless-host-shell

v3.0.0-alpha.91

Published

Reventless host shell SPA — loads plugin UI fragments at runtime via Module Federation

Readme

npm License: Proprietary Docs

@reventlessdev/reventless-host-shell

The web front end of a Reventless platform, shipped as a prebuilt bundle.

This is how a Reventless application gets a user interface. You do not write one: your plugins already describe their read models and commands, and those descriptions become lists, detail pages, filters, forms and routes. There is nothing here to compile and no component code to author — you add the shell to your platform stack and your domain shows up in a browser.

Adding a UI to your platform

1. Serve the shell from your platform stack

Pass ~hostUiBundle to deployPlatform. The deploy resolves this package's built bundle, hosts it as your platform's static site, and writes a config.json beside index.html naming the endpoints, auth mode and services it just provisioned:

let default = Platform.deployPlatform(
  ~version=Reventless.PackageVersion.fromCaller(),
  ~hostUiBundle={},
)

That generated config is what lets one prebuilt bundle serve every environment — you never rebuild the shell per stage.

2. Let each plugin contribute its screens

A plugin declares which of its components should appear, and where, by passing a UI fragment manifest. makeAutoUIManifest derives that manifest from the plugin structure you already have, so a read model becomes a list page and an aggregate becomes a detail panel without naming them twice:

Platform.Plugin.make(
  ~name="Catalog",
  ~pluginStructure,
  ~uiFragments=Platform.Plugin.makeAutoUIManifest(
    ~remoteEntryUrl=uiBundleUrl,
    ~name="Catalog",
    ~pluginStructure,
    ~readModelPositions=["platform-summary"],
    ~aggregatePositions=["resource-detail"],
  ),
  // …aggregates, slices, extension points
)

Components marked internal are left out of the manifest, so hiding a read model from the UI does not mean unwiring it.

3. Run it against a local platform

npx reventless-host-shell

This serves the built bundle and proxies /graphql to localhost:4000 and /platform-graphql to localhost:4001, where an in-memory Reventless platform serves its domain and admin APIs. Use it while developing; production is served by the platform stack from step 1.

4. Correct what was inferred

AutoUI guesses labels, column order, which view a list opens in, and which fields belong on a form. Where a guess is wrong, a ui-hints.json overrides it without touching code — point hostUiBundle.uiHintsFile at the file and the deploy publishes it beside config.json. Absent, the shell treats the 404 as "no hints" and uses its own defaults.

5. Turn on the capabilities that need infrastructure

Some features need something provisioned before they appear. Uploads are the example: hostUiBundle.uploadBucket provisions a presigned-upload service against an object store and threads its URL into the config, which is what makes file and image fields accept a real upload.

Leave it unset and the service is not provisioned, the endpoint is omitted from the config, and the shell notices — the upload input is never registered, so a file field renders plainly rather than failing.

What you get

  • Screens without UI code. The generated pages are the product, not a scaffold to replace later.
  • New plugins without redeploying the shell. Plugins that bring their own screens are loaded at runtime as Module Federation remotes: the shell has no remotes compiled into it and discovers them from the platform as it boots.
  • Alternative views where the data supports them. A read model is a table by default, and is offered other views when its schema fits them — a status enum earns a board, a latitude/longitude pair earns a map. An offered view is a toggle the user can take or leave, never a forced default.
  • Live updates, presence and uploads when the platform advertises the matching endpoints, and nothing when it does not.

What is in config.json

The deploy writes this for you; write it by hand only when self-hosting the bundle. The keys the shell reads include:

| Key | Purpose | |---|---| | apiEndpoint | the domain GraphQL API | | platformApiEndpoint | the platform (admin) GraphQL API | | authMode | local or cognito, with the matching cognito* keys | | domainApiEventsEndpoint | live updates transport; absent ⇒ no live updates | | clientEventsNamespace | channel namespace browsers may publish to; absent ⇒ presence and chat surfaces stay dark | | viewModes | which optional view modes to register |

Uploads need no key. A file or image input mints its upload target through the domain API's Upload_Presign mutation, naming the object store its own field declares, and PUTs the bytes straight there — so apiEndpoint is all it needs. See docs/guides/upload-contract.md in reventless-core for the contract.

To host the bundle yourself, serve this package's dist/ as static files with a config.json next to index.html.

License

Proprietary — see LICENSE. This package is published so that it can be obtained and run to operate a Reventless application; it grants no redistribution or modification rights.