VoidhashDocs
DevelopersHelp centerGuidesAPI reference
Dashboard
Get started
Introduction
Quickstart
How Voidhash works
Glossary
Versions and releases
Concepts
Teams, projects and environments
API keys
Products and perks
Offers
Subscription lifecycle
People and identity
Groups
Events
Features
Paywalls in your app
Feature flags and A/B tests
Paywall components
Push notifications
Ad attribution in your app
Client SDKs
React Native
Swift
Kotlin
Web
Your backend
Node.js
PHP
Go
Rust
Other languages
Payment sources
Forward store notifications
Developer tools
CLI
MCP server
Query analytics with VoidQL
Components
Develop a component
Editor panels
Panel handlers and state
Component definition
Component props
Publishing
Installing and capabilities

Publishing

Share components with every project of your organization.

Publishing a component to your organization makes it available to every project of the organization. Published components stay private to your organization: other organizations cannot see or install them.

This is a step beyond voidhash publish, which adds versions to one project's own components (see Develop a component). The organization's commands are under voidhash registry.

Claim your namespace

Every component your organization publishes is named <namespace>/<name>, such as acme/plan-picker. An organization admin claims the namespace once, on the project's Components page or with the CLI:

voidhash registry publisher claim acme

Namespaces use lowercase letters, digits and dashes. You can rename it until you publish the first component; after that, paywalls refer to components by it, so it stays fixed.

Publish a bundle

A bundle is a directory with the component's definition and its modules. A component crate outside your project's .voidhash working copy is a bundle once it is built:

FileRequiredContents
component.jsonYesThe component definition.
module.wasmYesThe component module. A crate's build is found automatically.
panel.wasmWith an editor panelThe editor panel module, found the same way.
icon.png, icon.svg, icon.webpNoThe icon the dashboard shows. At most 256 KiB.
thumbnails/<state>.pngNoA preview per preview state. At most 1 MiB each.
README.mdNoDocumentation people read before installing.
agent.mdNoGuidance the Voidhash agent reads before using the component.

Build, check and publish from the crate directory:

voidhash test .
voidhash registry publish

voidhash test builds both modules into target/voidhash, where registry publish looks for them, and runs the checks publishing runs. See Develop a component for testing.

Publishing checks the bundle before accepting it: the definition, the module and the definition agreeing with it, the size limits, and the panel module when the definition declares one. It then runs the same checks as voidhash test: the component conformance suite on the module, and the panel checks on the panel module. A version that fails any check is not published. Each problem is listed so you can fix them all at once. The CLI checks the panel module before it uploads anything.

A self-hosted server without a component build service cannot run the conformance suite. It publishes versions without it and marks each one conformance-not-run. Run voidhash test before you publish to such a server. voidhash registry list shows these warnings next to the version.

Every version is permanent. Publishing the same bundle again, for example from a retried CI job, returns the version you already published; publishing different contents under an existing version fails. Bump version in component.json instead.

Publish from CI

Use the project's secret API key. Publishing acts for the key's project, and the component belongs to the project's organization:

voidhash config set api_key "$VOIDHASH_SECRET_KEY"
voidhash registry publish ./plan-picker

A secret key can publish, deprecate and yank the components its project owns, but only an organization admin who signed in with login can claim the namespace.

Who owns a component

Each component is owned by the project that first published it. Only people who can deploy paywalls in that project, its secret key, and organization admins can publish new versions of the component, deprecate it or yank it. Every other project of the organization can still install and use it, so a project cannot change a component that other projects publish and depend on.

The component's details on the Components page, and voidhash registry list, show which project owns it. An organization admin can move a component to another project: open the Components page of the project that should own it, open the component's details, and choose Make this project the owner. From the CLI, sign in with login and run:

voidhash registry transfer acme/plan-picker --project <project-id>

The previous project loses the access ownership gave it. A secret key cannot move a component.

Publish a project component

To share a component that already lives in one project, publish one of its ready versions from the Components page (Publish to organization), or with the CLI:

voidhash registry publish --from-project plan-picker@3 --version 1.0.0

plan-picker@3 is the project component and the version voidhash publish reported. The registry version uses the same module as the project version, and its definition is created from the module.

Deprecate and yank

  • Deprecate a version, or a whole component, when people should stop using it. It can no longer be installed or newly inserted, and paywalls using it cannot be built again until they move to another version. You can lift a deprecation.
  • Yank a version that must never be used again, for example one that crashes. A yank is permanent.
voidhash registry deprecate acme/plan-picker 1.0.0 --message "Use 1.1.0"
voidhash registry yank acme/plan-picker 1.0.1 --message "Crashes on Android"

Paywalls already deployed keep working in both cases. The Components page shows where each version is still used, so you can update those paywalls.

Next steps

  • Install components in a project
  • Component definition reference
  • Develop a component

Something wrong or missing on this page? Tell us by email or on Discord.

PreviousComponent propsNextInstalling and capabilities

On this page

Claim your namespacePublish a bundlePublish from CIWho owns a componentPublish a project componentDeprecate and yankNext steps