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

@kenzi-wealth/widget-native

v0.2.3

Published

The Kenzi Widget for smart conversations, AI-enabled analysis and investment intelligence for your investment portfolio.

Readme

Kenzi Widget (React Native)

The React Native SDK for the Kenzi widget — smart conversations, AI-enabled analysis, and investment intelligence for your investment portfolio.

See more on our website: https://kenziwealth.com/ or reach out for a demo on [email protected].

Requirements

  • React 18 or later
  • React Native 0.70 or later
  • Peer dependencies: jotai ≥ 2.19, react-native-svg ≥ 15
  • Works with both bare React Native and Expo (managed and bare workflows). No native code — no pod install or custom dev build required.

Installation

npm install @kenzi-wealth/widget-native
yarn add @kenzi-wealth/widget-native
pnpm add @kenzi-wealth/widget-native

Quick Start

Render the <Widget /> component anywhere in your app and pass a trigger as its child. The trigger is shown when the chat is closed; when activated, it opens the chat dialog.

import { Text } from 'react-native'
import { Widget, KenziTrigger } from '@kenzi-wealth/widget-native'

const App = () => (
	<Widget>
		<KenziTrigger>
			<Text>Ask Kenzi</Text>
		</KenziTrigger>
	</Widget>
)

API

<Widget />

The main chat widget. Renders the chat dialog, prompt input, guided actions, and trade confirmation flow. Place it once in your component tree.

Props

| Prop | Type | Default | Description | | ------------------ | ----------- | ------- | ------------------------------------------------------------------------- | | children | ReactNode | — | Content rendered when the chat is closed. Typically a <KenziTrigger />. | | persistentPrompt | boolean | false | When true, the prompt input is rendered even while the chat is closed. |

Examples

With a trigger button:

import { Widget, KenziTrigger } from '@kenzi-wealth/widget-native'

const App = () => (
	<Widget>
		<KenziTrigger>
			<Text>Ask Kenzi</Text>
		</KenziTrigger>
	</Widget>
)

With a persistent prompt input:

<Widget persistentPrompt>
	<KenziTrigger>
		<Text>Ask Kenzi</Text>
	</KenziTrigger>
</Widget>

<KenziTrigger />

An unstyled Pressable that opens the chat when activated. Accepts all standard PressableProps — supply your own style and children to control the visuals (wrap text in a React Native <Text> as usual).

Props

Extends PressableProps (with onPress overridden):

| Prop | Type | Description | | --------- | ------------ | --------------------------------------------------- | | onPress | () => void | Called immediately before the chat opens. Optional. |

Examples

With a custom label and styling:

import { Text } from 'react-native'
import { KenziTrigger } from '@kenzi-wealth/widget-native'

const Trigger = () => (
	<KenziTrigger style={styles.trigger}>
		<Text style={styles.triggerLabel}>Ask Kenzi</Text>
	</KenziTrigger>
)

Running side effects when the chat opens:

<KenziTrigger onPress={() => trackEvent('chat_opened')}>
	<Text>Chat</Text>
</KenziTrigger>

<InvestmentHealthCard />

A pressable card that displays the user's investment health score with an animated circular gauge. Tapping the card opens the chat with a prefilled analysis flow.

Props

| Prop | Type | Default | Description | | --------- | ------------------------ | ----------- | ---------------------------------------------------------------- | | variant | 'default' \| 'compact' | 'default' | 'compact' hides the description text and keeps only the gauge. |

import { InvestmentHealthCard } from '@kenzi-wealth/widget-native'

const Cards = () => (
	<>
		<InvestmentHealthCard />
		<InvestmentHealthCard variant="compact" />
	</>
)

<TradeIntentCard />

A pressable card highlighting a suggested trade with a match score. Tapping the card opens the chat with a prefilled trade-intent flow seeded with the configured instrument.

Props

| Prop | Type | Default | Description | | ---------------- | ------------------ | ------------------------- | -------------------------------------------------------------------------------------- | | title | string | — | Card heading, e.g. "Investment Intelligence". | | match | number | — | Match score, rendered as {match}% match. | | ticker | string | — | Instrument ticker symbol (e.g. "Z74"). Carried into the chat and the trade order. | | name | string | — | Instrument display name (e.g. "Singtel"). Used in the body, prompts, and trade copy. | | price | number | — | Price per share in the instrument's currency. | | description | string | name-interpolated default | Short explanation shown beneath the title. | | instrumentType | 'Stock' \| 'ETF' | 'Stock' | Instrument type. Flows into the trade order on confirmation. | | lotSize | number | 1 | Minimum tradable share increment (e.g. 100 for Bursa/KLS board lots). |

Examples

Minimum configuration — the card renders a default name-interpolated description:

import { TradeIntentCard } from '@kenzi-wealth/widget-native'

const Suggestion = () => (
	<TradeIntentCard
		title="Investment Intelligence"
		match={98}
		ticker="Z74"
		name="Singtel"
		price={4.9}
	/>
)

With a custom description and Bursa/KLS board lot:

<TradeIntentCard
	title="Investment Intelligence"
	match={98}
	ticker="Z74"
	name="Singtel"
	price={4.9}
	lotSize={100}
	description="Singtel adds growth potential and some extra swings."
/>

For an ETF:

<TradeIntentCard
	title="Investment Intelligence"
	match={92}
	ticker="SPY"
	name="SPDR S&P 500 ETF"
	price={500}
	instrumentType="ETF"
/>

useKenzi()

A React hook for programmatic control of the chat widget. Must be called within a component tree that also renders <Widget />.

Return value

type UseKenzi = {
	isOpen: boolean
	open: () => void
	close: () => void
}

| Property | Type | Description | | -------- | ------------ | ----------------------------------------------------- | | isOpen | boolean | Reactive — whether the chat dialog is currently open. | | open | () => void | Opens the chat dialog. No-op if already open. | | close | () => void | Closes the chat dialog. No-op if already closed. |

open and close are stable references, safe to pass as props or use in dependency arrays.

Example

import { Pressable, Text } from 'react-native'
import { useKenzi } from '@kenzi-wealth/widget-native'

const ChatToggle = () => {
	const { isOpen, open, close } = useKenzi()

	return (
		<Pressable onPress={isOpen ? close : open}>
			<Text>{isOpen ? 'Close chat' : 'Open chat'}</Text>
		</Pressable>
	)
}