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

nuqiwealth-widgets

v1.1.0

Published

Embeddable React / Next.js widgets for live stock market data — powered by Nuqi Wealth

Readme

nuqiwealth-widgets

Embeddable React / Next.js widgets for live stock market data, powered by Nuqi Wealth.

npm install nuqiwealth-widgets

Credentials required. The package installs freely but every widget renders a neutral locked state without a valid apiKey and clientId. Purchase a plan at nuqiwealth.com or contact [email protected] to get yours.


Widgets

| Component | Description | Feature key | |-----------|-------------|-------------| | StockList | Filterable, sortable, paginated stock table | stock-list | | StockDetail | Full-screen overlay — chart, financials, analyst ratings & news | stock-detail | | BasketList | Card grid of curated investment baskets with mini charts and CAGR | curated-baskets | | BasketDetail | Full-screen overlay — basket performance chart, composition & description | cep-detail |

  • React 18 & 19 · Next.js 13 / 14 / 15 (App Router & Pages Router)
  • Dual build — ESM + CJS + .d.ts types
  • Pre-compiled CSS — no Tailwind setup needed in your project
  • 8 built-in themes including dark and light
  • Container-responsive — widgets reflow on their own width, not the viewport
  • Per-client feature lock — same package, different widgets unlocked per partner

Quick start

React (Vite)

// src/main.tsx
import 'nuqiwealth-widgets/styles.css'
// src/App.tsx
import { useState } from 'react'
import { NuqiWidgets, StockList, StockDetail } from 'nuqiwealth-widgets'

export default function App() {
  const [stockKey, setStockKey] = useState<string | null>(null)

  return (
    <NuqiWidgets
      apiKey={import.meta.env.VITE_NUQI_API_KEY}
      clientId={import.meta.env.VITE_NUQI_CLIENT_ID}
      baseUrl={import.meta.env.VITE_NUQI_BASE_URL}
      theme="dark"
    >
      <StockList onStockClick={setStockKey} />
      {stockKey && (
        <StockDetail stockKey={stockKey} onClose={() => setStockKey(null)} />
      )}
    </NuqiWidgets>
  )
}

Next.js App Router

// app/providers.tsx
'use client'
import { NuqiWidgets } from 'nuqiwealth-widgets'
import 'nuqiwealth-widgets/styles.css'

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <NuqiWidgets
      apiKey={process.env.NEXT_PUBLIC_NUQI_API_KEY!}
      clientId={process.env.NEXT_PUBLIC_NUQI_CLIENT_ID!}
      baseUrl={process.env.NEXT_PUBLIC_NUQI_BASE_URL!}
      theme="dark"
    >
      {children}
    </NuqiWidgets>
  )
}
// app/layout.tsx
import { Providers } from './providers'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}

Next.js Pages Router

// pages/_app.tsx
import type { AppProps } from 'next/app'
import { NuqiWidgets } from 'nuqiwealth-widgets'
import 'nuqiwealth-widgets/styles.css'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <NuqiWidgets
      apiKey={process.env.NEXT_PUBLIC_NUQI_API_KEY!}
      clientId={process.env.NEXT_PUBLIC_NUQI_CLIENT_ID!}
      baseUrl={process.env.NEXT_PUBLIC_NUQI_BASE_URL!}
      theme="dark"
    >
      <Component {...pageProps} />
    </NuqiWidgets>
  )
}

Environment variables

# .env (Vite)
VITE_NUQI_API_KEY=your_api_key_here
VITE_NUQI_CLIENT_ID=your_client_id_here
VITE_NUQI_BASE_URL=https://api.nuqiwealth.com

# .env.local (Next.js)
NEXT_PUBLIC_NUQI_API_KEY=your_api_key_here
NEXT_PUBLIC_NUQI_CLIENT_ID=your_client_id_here
NEXT_PUBLIC_NUQI_BASE_URL=https://api.nuqiwealth.com

Never commit these to source control.


API reference

<NuqiWidgets> — provider

Wrap your app (or the section that renders widgets) once. All widgets must be descendants.

| Prop | Type | Required | Description | |------|------|----------|-------------| | apiKey | string | ✓ | Publishable widget key issued by Nuqi Wealth | | clientId | string | ✓ | Client identifier issued by Nuqi Wealth | | baseUrl | string | ✓ | API base URL provided with your credentials | | theme | PresetThemeName \| ThemeConfig | | Preset name or custom theme object. Default: "dark" | | userToken | string | | End-user JWT for per-user feature gating | | refreshInterval | number | | Polling interval in ms. Default: 30000 | | onError | (err: NuqiError) => void | | Error callback |


<StockList>

Filterable, sortable, paginated table of stocks. Container-responsive — switches layouts automatically at different widths.

import { StockList } from 'nuqiwealth-widgets'

<StockList
  onStockClick={(key) => setStockKey(key)}
  exchange="NASDAQ"
  sector="Technology"
  limit={20}
/>

| Prop | Type | Default | Description | |------|------|---------|-------------| | onStockClick | (key: string) => void | | Called when a row is clicked | | exchange | string | | Filter by exchange | | country | string | | Filter by country | | sector | string | | Filter by sector | | search | string | | Pre-fill the search input | | defaultSort | string | | Default sort column key | | sortableColumns | string[] | | Override which columns are sortable | | limit | number | | Max rows per page | | height | number \| string | | Widget height | | width | number \| string | | Widget width. Omit to fill parent | | theme | PresetThemeName \| ThemeConfig | | Per-widget theme override | | className | string | | | | style | React.CSSProperties | | |


<StockDetail>

Full-screen overlay showing a single stock's chart, financials, analyst ratings, and news. Renders into a portal so it sits above your page layout.

import { StockDetail } from 'nuqiwealth-widgets'

{stockKey && (
  <StockDetail
    stockKey={stockKey}
    onClose={() => setStockKey(null)}
  />
)}

| Prop | Type | Required | Description | |------|------|----------|-------------| | stockKey | string | ✓ | Stock identifier (returned by StockList.onStockClick) | | onClose | () => void | ✓ | Called when the overlay is dismissed | | width | number \| string | | Panel max-width. Default: 680px | | height | number \| string | | Panel max-height. Default: 90vh | | theme | PresetThemeName \| ThemeConfig | | Per-widget theme override | | className | string | | | | style | React.CSSProperties | | | | overlayClassName | string | | | | overlayStyle | React.CSSProperties | | |


<BasketList>

Responsive card grid of curated investment baskets, each showing a mini performance chart, CAGR, and risk level.

import { BasketList } from 'nuqiwealth-widgets'
import type { BasketItem } from 'nuqiwealth-widgets'

<BasketList
  onBasketClick={(basket: BasketItem) => setBasket(basket)}
  risk="growth"
/>

| Prop | Type | Default | Description | |------|------|---------|-------------| | onBasketClick | (basket: BasketItem) => void | | Called when a card is clicked | | risk | 'all' \| 'conservative' \| 'balanced' \| 'growth' \| 'aggressive' | 'all' | Filter by risk level | | limit | number | | Max baskets to display | | height | number \| string | | Scrollable card area height | | width | number \| string | | Widget width. Omit to fill parent | | theme | PresetThemeName \| ThemeConfig | | Per-widget theme override | | className | string | | | | style | React.CSSProperties | | |


<BasketDetail>

Full-screen overlay showing a basket's performance chart, stock composition table, and description.

import { BasketDetail } from 'nuqiwealth-widgets'

{basket && (
  <BasketDetail
    basketId={basket.id}
    onClose={() => setBasket(null)}
  />
)}

| Prop | Type | Required | Description | |------|------|----------|-------------| | basketId | string | ✓ | Basket identifier (from BasketItem.id) | | onClose | () => void | ✓ | Called when the overlay is dismissed | | width | number \| string | | Panel max-width. Default: 760px | | height | number \| string | | Panel max-height. Default: 90vh | | theme | PresetThemeName \| ThemeConfig | | Per-widget theme override | | className | string | | | | style | React.CSSProperties | | | | overlayClassName | string | | | | overlayStyle | React.CSSProperties | | |


Themes

Eight built-in presets:

| Preset | Accent | Mode | |--------|--------|------| | dark | Teal | Dark — default | | light | Teal | Light | | midnight | Blue | Dark | | forest | Emerald | Dark | | sunset | Amber | Dark | | violet | Purple | Dark | | arctic | Cyan | Light | | dawn | Amber-brown | Light |

// Preset string
<NuqiWidgets theme="midnight" ...>

// Spread a preset and override specific tokens
import { MidnightTheme } from 'nuqiwealth-widgets'
<NuqiWidgets theme={{ ...MidnightTheme, accent: '#6366f1' }} ...>

// Per-widget override (overrides the provider theme for that widget only)
<StockList theme="arctic" />

Without credentials

If apiKey or clientId is missing or invalid:

  • NuqiWidgets marks itself ready immediately — no infinite spinner
  • Each widget renders a neutral locked placeholder instead of fetching data
  • No errors are thrown; no network requests are made
  • Your app layout is never broken

You can build your UI with widgets in place before credentials are issued.


Security

  • Keys are browser-safe by design. apiKey and clientId are publishable widget keys scoped to read-only market data for your registered domain. They are not admin credentials.
  • No secrets are bundled. This package contains no hardcoded keys, no backend credentials, and no internal infrastructure details.
  • Per-user gating. Pass an end-user JWT as userToken to apply per-user feature restrictions. A per-user lock can only restrict — it cannot grant access the client plan does not already include.
  • Requests abort on unmount. All polling is cancelled when a widget unmounts — no stale requests or memory leaks.

Getting credentials

Purchase a plan at nuqiwealth.com to receive your apiKey, clientId, baseUrl, and the list of feature keys included in your plan. For enterprise enquiries contact [email protected].


License

Proprietary — see LICENSE. A valid purchased API key is required to use this software. Redistribution and reverse engineering are prohibited.