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

@mbdayo/react-native-kickstart-exchange

v0.1.0

Published

Unofficial React Native (bare / CLI) wrapper for the Kickstart Exchange banner ad SDK. No Expo modules required.

Readme

@mbdayo/react-native-kickstart-exchange

Unofficial React Native wrapper for the Kickstart Exchange banner ad SDK, for bare React Native (CLI) projects. No Expo modules required.

Kickstart Exchange is a privacy-preserving cross-promotion network for independent Apple-platform apps: you earn points by showing other developers' ads, and spend points advertising your own. This package wraps twostraws/KickstartSDK — Paul Hudson's official SwiftUI SDK — as a Fabric native component.

Not affiliated with or endorsed by Kickstart Exchange or Paul Hudson.

import {KickstartExchangeBanner} from '@mbdayo/react-native-kickstart-exchange';

<KickstartExchangeBanner apiKey="ks_live_YOUR_KEY" />;

That's the whole integration. The banner sizes itself, so you don't pass a height.

Why this package

There is an excellent Expo module, @tomyail/react-native-kickstart-exchange. If your app uses Expo, use that one. This package exists for bare RN apps that don't want to adopt Expo Modules just to show a banner, and it differs in two ways that matter:

  • The banner measures itself. The ad card's height depends on Dynamic Type and ad copy. Measured on an iPhone 17: 84pt at the default text size, 391.5pt at accessibility-extra-large. A fixed height either clips the "Get" button and the "Ad" disclosure badge at large text sizes, or leaves dead space at small ones.
  • Impressions follow real on-screen visibility. See Viewability — a banner scrolled off screen stops counting as viewed.

It also takes standard React Native ColorValue props (named colours, rgba(), DynamicColorIOS) rather than hex strings.

Requirements

| | | |---|---| | Platform | iOS 18+ only. Android, web, and iOS < 18 render null. | | Architecture | New Architecture (Fabric). No legacy-arch ViewManager. | | React Native | 0.80 or later | | Xcode | 26 or later (the SDK is Swift 6 / SwiftUI) | | App deployment target | iOS 18.0 — see below |

The iOS 18 deployment target

The upstream SDK requires iOS 18, so this pod does too, and CocoaPods will refuse to install into an app targeting anything lower. You must raise your app's deployment target in both places:

ios/Podfile:

platform :ios, '18.0'

And in Xcode, set iOS Deployment Target to 18.0 for your app target (or edit IPHONEOS_DEPLOYMENT_TARGET in the .pbxproj).

If iOS 18 is too high a floor for your app, this SDK is not usable at all yet — the requirement comes from upstream, not from this wrapper.

Installation

npm install @mbdayo/react-native-kickstart-exchange
cd ios && pod install

There is no Swift Package to add and no Podfile edit beyond the platform line: the MIT-licensed SDK sources are vendored into this package and compiled by its pod. See docs/VENDORING.md.

No Android code ships at all — autolinking skips the platform entirely.

API keys

Register your app at exchange.kickstart.tools to get a ks_live_… key. Approval requires an App Store link and developer-identity verification.

For development, pass the literal string 'preview':

<KickstartExchangeBanner apiKey={__DEV__ ? 'preview' : 'ks_live_YOUR_KEY'} />

The upstream SDK honours 'preview' only in Debug builds and on the Simulator. It renders the server's sample advertisement, creates no session, and records no impression. Note that the preview response carries no impression token, so preview mode cannot be used to verify impression reporting.

Props

| Prop | Type | Default | Notes | |---|---|---|---| | apiKey | string | — | Required. ks_live_… or 'preview'. | | style | StyleProp<ViewStyle> | — | Leave the height out unless autoHeight is false. | | autoHeight | boolean | true | Size to the measured card height. | | cornerStyle | 'rounded' \| 'square' | 'rounded' | | | strokeColor | ColorValue | SDK default (.quaternary) | Card border. | | actionTextColor | ColorValue | blue | "Get" button text. | | disclosureBackgroundColor | ColorValue | blue | The "Ad" badge. | | colorScheme | 'system' \| 'light' \| 'dark' | 'system' | Force the card's appearance. | | onSizeChange | (size: {width, height}) => void | — | Fires on every measurement, including the initial height: 0. | | onAdVisibilityChange | (isVisible: boolean) => void | — | Derived from measured height; see below. | | testID | string | — | |

Colour props map to the SDK's exchangeAd… modifiers. Omitting one leaves the SDK's own default untouched, which is not always a plain colour — a missing strokeColor draws .quaternary, not "no border".

Sizing

The component measures the hosted SwiftUI card and applies the result as its own height. Concretely: native measures the card at its ideal height, emits onSizeChange, and the component stores that as its style height. Until the first ad loads the card occupies no space, so the banner's height is 0 and nothing is reserved in your layout.

Set autoHeight={false} to take over — to animate the height yourself, or to reserve a fixed slot. You must then supply a height via style, or nothing will be visible.

onAdVisibilityChange is derived from the measured height, not reported by the SDK, which exposes no load callback. height > 0 means an ad is on screen. Use it to collapse placeholders or surrounding padding when no ad is available:

const [hasAd, setHasAd] = useState(false);

<View style={hasAd ? styles.adSlot : undefined}>
  <KickstartExchangeBanner apiKey={key} onAdVisibilityChange={setHasAd} />
</View>;

Theming

The card's background uses SwiftUI's .windowBackground, which resolves against the system appearance. If your app has its own theme toggle that can diverge from the system setting, pass colorScheme so the card matches:

<KickstartExchangeBanner apiKey={key} colorScheme={myTheme === 'dark' ? 'dark' : 'light'} />

Viewability and impressions

The SDK records an impression once the banner has been continuously visible for one second, gating on SwiftUI's onScrollVisibilityChange. That signal describes visibility within an enclosing SwiftUI scroll view — a notion that doesn't exist when the banner is hosted inside a UIKit/React Native hierarchy, where SwiftUI cannot see that the view sits below the fold of a React Native ScrollView.

This wrapper hosts the banner in a non-scrolling SwiftUI ScrollView and drives its height from real on-screen visibility, computed natively from window membership and intersection with any clipping or scrolling ancestors, and refreshed as those ancestors scroll. The result: a banner scrolled out of view reports as not visible and stops accruing an impression, and one scrolled into view starts.

Two honest caveats:

  • Visibility is binary: any visible portion counts as visible, rather than the SDK's internal 50% threshold. The only lever available over SwiftUI's own visibility is the hosted scroll view's height, and collapsing it while the card is still partly on screen would make a visible ad vanish mid-scroll. So a partly-visible banner may begin its impression slightly earlier than a pure SwiftUI host would.
  • Without this handling, onScrollVisibilityChange still fires — it reports the card visible as soon as it has a non-zero size, regardless of where it actually sits. Impressions are then recorded for ads nobody saw.

App backgrounding is handled by the SDK itself, through scenePhase.

App Store privacy

This is an ad SDK, so shipping it has App Store Connect consequences. See docs/PRIVACY.md for what to declare and why. In short: declare Product Interaction and Advertising Data as collected, not linked to identity, and not used for tracking; and mention Kickstart Exchange in your privacy policy.

The SDK's PrivacyInfo.xcprivacy ships in a named resource bundle (RNKickstartExchangeResources) so it stays visible to Apple's privacy tooling without colliding with your app's own manifest.

Per Apple's review guidelines and upstream's instructions, link the banner only into a main app binary — never an app extension, App Clip, or widget.

Known limitations

  • No card background override. Upstream hard-codes .windowBackground for the card surface. Overriding it would require patching the vendored source, which this package deliberately avoids so that upstream updates stay a clean copy. Use colorScheme to control how that background resolves.
  • iOS only. The SDK supports macOS, tvOS, watchOS, and visionOS, but this wrapper targets iOS; react-native-macos/-tvos are not wired up.
  • New Architecture only. There is no legacy RCTViewManager.
  • One banner per screen region is the intended use. The SDK serves one ad per app run and dedupes impressions across banners itself.

Example app

npm install
npm run build
cd example && npm install
cd ios && pod install && cd ..
npx react-native run-ios

The harness renders two banners — one above the fold and one 500pt down — plus live measurement readout, a style toggle, and a mount toggle.

Upstream SDK version

Vendored from KickstartSDK 0.5.0 (36f475be). npm run check-upstream verifies the vendored tree still matches the pin and reports newer upstream tags; npm run sync-upstream -- --tag <version> moves it. Details in docs/VENDORING.md.

License

MIT for this wrapper. The vendored SDK is MIT, © 2026 Paul Hudson — see THIRD_PARTY_NOTICES.md.