Versions and releases
Where each Voidhash SDK and library installs from, how to pin a build, and what changed.
Every Voidhash SDK and server library is an alpha release: its API can change between builds.
Each one installs from the Voidhash package registry, pkg.voidha.sh, or from the
Voidhash repository on GitHub. npm still serves an older
preview of @voidhash/web, @voidhash/node and @voidhash/react-native
(0.0.1-alpha.1-canary.3.3.73d606d) that doesn't match these docs; don't install it.
Packages
| Package | Install from | Pin a build | Version |
|---|---|---|---|
| Swift | Swift Package Manager, main branch of the repository. CocoaPods: @voidhash/ios from the package registry. | revision: with a commit | 0.0.1-alpha.1 |
| Kotlin | A clone of the repository, as a Gradle included build | Check out a commit | 0.0.1-alpha.1 |
| React Native | Package registry: @voidhash/react-native | …/@voidhash/react-native/<hash> | 0.0.1-alpha.1 |
| Web | Package registry: @voidhash/web. Script tag: cdn.voidhash.com. | …/@voidhash/web/<hash>; script tag: a version URL | 0.0.1-alpha.1 |
| Node.js | Package registry: @voidhash/node | …/@voidhash/node/<hash> | 0.0.1-alpha.1 |
| PHP | A clone of the repository, as a Composer path repository | Check out a commit | Unversioned |
| Go | A clone of the repository, through a replace directive | Check out a commit | Unversioned |
| Rust | A clone of the repository, as a path dependency | Check out a commit | 0.1.0 |
| CLI | Not published yet | — | 0.0.1-alpha.1 |
A registry build's installed version ends with -g and the short hash of the commit it was built
from, such as 0.0.1-alpha.1-g83f7412. Install that build again from
https://pkg.voidha.sh/<package>/83f7412. branch:main in place of the hash always names the newest
build.
Build retention
Builds on the package registry are kept for three weeks, so pin a recent one and update regularly. Once a build is removed, its URL stops installing, and so does a lockfile that records it, for example in CI. Commits in the GitHub repository don't expire.
Upgrade
- Read the changelog since your build. Entries marked Breaking need code changes.
- Install the newer build:
- Package registry: run the install command again with
branch:mainor the new hash. - Swift Package Manager: change
revision:to the new commit. If you followmain, choose File → Packages → Update to Latest Package Versions in Xcode. - Repository clone: check out the newer commit in the clone, or move the submodule to it.
- Package registry: run the install command again with
- React Native: ship a new native build. An over-the-air update can't deliver a new SDK version, and must not roll an app back to an earlier one.
Changelog
Notable changes for customers, newest first.
November 2026
Swift, Kotlin and React Native
setAdDataSharingrecords whether a person agreed to share their purchases with ad platforms, for sending purchases to Meta.- Swift credits new installs to Apple Ads campaigns, and Kotlin reads the Google Play install
referrer, plus Meta's apps when you set
metaAppId. Turn it off withinstallAttribution.
Web
playStoreUrl(packageName)builds a Google Play link that carries the visitor's latest campaign into your Android app's install.crossSubdomainIdentitykeeps one anonymous visitor across your subdomains.- New
$pageleaveand$outbound_clickevents, on by default.
Every client SDK
setGroupsreplaces all of a person's groups in one call and sends a$groupidentifyonly for a group that changed.identifywith the same ID and profile as the last call sends nothing, andsignOut()does nothing when nobody is signed in, so both can run every time your app checks its session.analyticsWhilePendingset to buffer holds events captured while consent ispendingin memory and records them when consent is granted.grantConsentOnIdentifyletsidentifygrant a pending consent.- Analytics consent covers what the SDK observes, not what your app says about a person: person
attributes and groups are sent whatever the consent, as
identifyalready was, so flags and cohorts that target them work for people who declined tracking. Events, screens, sessions, ad attribution and agreeing to ad data sharing still need consent. To send nothing before consent, don't make those calls until then. - Breaking:
reset()means the same on every SDK. For a signed-in person it does exactly whatsignOut()does, including$sign_outand a new session. When nobody is signed in,signOut()does nothing andreset()starts a fresh anonymous person without an event. Before,reset()recorded$sign_outfor anonymous people on Swift and Kotlin, recorded none on Web, and on React Native recorded none and kept the session. - Person attributes named
emailandnameset the person's own email and name on every SDK. - With
analyticsWhilePendingset to buffer, a grant records$app_installedor$app_updatedbefore the held events. - Swift and Kotlin: a manual screen name is trimmed, and a blank screen or event name is ignored and
reported as
ANALYTICS_EVENT_INVALID. The session ID is empty without analytics consent. - React Native:
setPersonAttributesSync()works in observer mode, attribute calls wait forinit()and keep their order after anidentify()you didn't await, and asetGroupsentry without anidis anINVALID_ARGUMENTerror. - The publishable key is optional. Without one the client is inert, for builds and environments without a Voidhash project.
- Web:
identify,signOut,reset, the group methods andsetAnalyticsConsenttake effect in call order without awaiting each one.
Server libraries
- Methods for organization invitations, Meta measurement settings and automations.
October 2026
Swift, Kotlin and React Native
- Breaking: the SDKs buy and finish purchases themselves by default. Observer mode is off unless you turn it on.
- The React Native SDK runs on the native Swift and Kotlin clients. Upgrading needs a new native build; the identity, queued events and receipts, and the cached person carry over.
- Apps keep working while Voidhash is unreachable. On Swift,
purchase(product:)returns.deferredwhen the store charged but Voidhash hasn't confirmed yet; React Native returns statusdeferred. - Kotlin acknowledges a Google Play purchase on the device 48 hours after payment if Voidhash still hasn't confirmed it, so Google Play doesn't refund it.
- Buy App Store promotional offers and Google Play developer offers with an
offerId. - Purchases made from a paywall are credited to that paywall in analytics.
- Analytics consent:
analyticsConsentandsetAnalyticsConsentstop analytics for a person without affecting purchases. isAnonymousDistinctIdis exported from the Swift and React Native SDKs.
Web
- The SDK records page views, sessions and campaign attribution, and installs from the package registry.
- A script-tag build for sites without a bundler.
analytics.beforeSend,analytics.sanitizeUrlandpauseAnalytics()let you change, drop or pause events. WithanalyticsConsentSource: "app", your consent tool's answer is the only source.- Breaking:
createCheckout(),redirectToCheckout()andgetStripeClientReferenceId()are removed. PutgetDistinctId()on the checkout your server creates; see Sell on the web.
Every client SDK
- Breaking: new anonymous IDs look like
vh_anon_<uuid>. IDs stored by earlier builds keep their old form and stay anonymous; check both withisAnonymousDistinctId. - The publishable key alone decides the environment; the SDKs no longer send one.
Server libraries
- The Node.js library installs from the package registry.
- The libraries follow the redesigned REST API: methods are grouped and named after its endpoint groups and operations.
- Payment sources can report subscriptions, and provider endpoints answer test requests.
- Breaking: provider endpoints no longer handle
checkout.create. Your server creates checkouts at your payment provider.
CLI
voidhash loginsigns in with a code you confirm in the browser, and the CLI acts as you.- Commands for every area of Studio, with keys, webhooks and store mappings per environment.
September 2026
Swift, Kotlin and React Native
- Offline-first: reads answer from the device cache, and purchases, receipts and events queue until Voidhash is reachable.
- Automatic screen tracking, app lifecycle events and analytics sessions.
- Restores keep the purchase with the person who made it, through reinstalls and upgrades.
- Paywalls render natively, with multi-screen flows.
- React Native no longer depends on AsyncStorage,
expo-constantsorexpo-linking.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.