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

@buyingbuddy/react

v0.2.0

Published

IDX MLS real estate integration for React, Next.js, and Framer — property search, map results, listings, lead capture, and CRM via Buying Buddy.

Readme

@buyingbuddy/react

Add IDX/MLS integration to your site with React components that embed Buying Buddy IDX CRM widgets - MLS property search, map-based results, detailed listing pages, featured-listing showcases, lead-capture forms, and market reports.

Buying Buddy widgets ship as a <bb-widget> custom element loaded from the Buying Buddy plugin script. This package wraps that element in idiomatic React components so you can add IDX search and listings to your site without writing script tags or touching the custom element directly.

Works with React, Next.js, and Framer.

Is this the right package for you? This is a React component library — you use it inside a build-tooled project (Vite, Next.js, Framer) that compiles JSX/TypeScript. If you just want to drop a widget into a plain HTML page with a <script> tag, you don't need this package — use the standard widget install from your Buying Buddy account dashboard (Widgets → Installation and Setup) instead.

Prerequisites

Before anything will render, you need both of these:

  1. A Buying Buddy account activation key. Find it in your dashboard under Widgets → Plugin Installation and Setup. There is no anonymous or "try it" mode — the widgets will not load without a valid activation key.
  2. Your domain authorized on that account. An activation key only works on domains registered to its account. On an unauthorized domain the runtime loads but the widgets stay empty (no data is returned) — if widgets render blank, check that the domain is registered under Widgets → Plugin Installation and Setup.

Don't have an account yet? Start a free trial or buy a license to get your activation key.

Install

Inside an existing React project:

npm install @buyingbuddy/react

React 18 or 19 is required as a peer dependency, so make sure your project has them:

npm install react react-dom

Starting from scratch

No React project yet? This gets you from nothing to a running page:

npm create vite@latest my-site -- --template react
cd my-site
npm install
npm install @buyingbuddy/react
npm run dev          # opens a dev server, usually http://localhost:5173

Then paste one of the examples below into src/App.jsx and save — the page reloads automatically.

Quick start

import { BuyingBuddyProvider, BuyingBuddyWidget } from "@buyingbuddy/react";

export default function App() {
  return (
    <BuyingBuddyProvider activationKey="account-activation-key">
      <BuyingBuddyWidget type="FeaturedGallery" filter="limit:12" />
    </BuyingBuddyProvider>
  );
}

Replace account-activation-key with your activationKey. The provider loads the Buying Buddy script for that account once, waits for it to initialize, then renders your widgets. While it loads it renders the fallback (nothing, by default).

Examples

A standalone search form:

<BuyingBuddyProvider activationKey="account-activation-key">
  <BuyingBuddyWidget type="SearchForm" />
</BuyingBuddyProvider>

Display properties in grid or list layout, with a limit: token in the filter capping how many:

<BuyingBuddyWidget type="FeaturedGallery" filter="limit:12" />

To show listings from the broader MLS instead, add search criteria to the filter (below). If the filter contains no other criteria then widgets show the account's own (featured) listings.

Display selected properties in a grid layout. All options are expressed as +-joined tokens inside a single filter string — criteria, sort, and count alike. Use FIELD() for a field that accepts several values:

{/* 6 listings over $300k, priced high-to-low */}
<BuyingBuddyWidget
  type="FeaturedGallery"
  filter="price_min:300000+orderby:price desc+limit:6"
/>

{/* combine criteria with + ; FIELD() for multi-value fields */}
<BuyingBuddyWidget
  type="FeaturedGallery"
  filter="city:Denver+FIELD(property_beds:3,4,5)+orderby:price desc+limit:9"
/>

Search Results (results widgets are driven by the search/cookie state, and SearchResults is bound to the map viewport):

<BuyingBuddyWidget
  type="SearchResults"
  filter="city:Denver+price_min:300000+orderby:price desc"
/>

Interactive map with a fixed height:

<BuyingBuddyWidget type="InteractiveMap" style={{ height: "600px" }} />

Next.js

The provider runs entirely in the browser (it loads a script and reads window), so the file that renders it must be a client component. In the App Router, add the "use client" directive at the top of the file — it tells Next.js to run this component in the browser rather than only on the server.

In app/page.tsx:

"use client";

import { BuyingBuddyProvider, BuyingBuddyWidget } from "@buyingbuddy/react";

export default function Page() {
  return (
    <BuyingBuddyProvider activationKey="account-activation-key" fallback={<p>Loading…</p>}>
      <BuyingBuddyWidget type="SearchResults" />
    </BuyingBuddyProvider>
  );
}

Because the widgets are client-only, their listing content is not server-rendered — keep that in mind if SEO of the listings themselves matters to you.

Framer

A standalone, single-file widget for the Framer website builder is included at framer/BuyingBuddyWidget.tsx. It bundles the script loading and adds Framer property controls (activation key, widget type, filter), so you configure everything from Framer's design panel — no React code required.

  1. Open framer/BuyingBuddyWidget.tsx and copy its entire contents. (It also ships inside the npm package at node_modules/@buyingbuddy/react/framer/BuyingBuddyWidget.tsx.)
  2. In Framer, go to Assets → Code → + and paste it in.
  3. Drag the component onto your canvas and set your activation key in the property panel.

API

<BuyingBuddyProvider>

Loads the Buying Buddy runtime for an account and makes it available to the widgets inside it. Use one provider, near the top of your tree.

| Prop | Type | Default | Description | |------|------|---------|-------------| | activationKey | string | — | Required. Your Buying Buddy account activation key. | | fallback | ReactNode | null | Rendered while the script is loading. Not shown on error — see Caveats. |

<BuyingBuddyWidget>

Renders a single widget. Must be a descendant of <BuyingBuddyProvider>.

| Prop | Type | Description | |------|------|-------------| | type | BuyingBuddyWidgetType | Required. Widget to render — e.g. "FeaturedGallery", "SearchForm", "SearchResults", "InteractiveMap", "SearchDetails". | | filter | string | Property filter as +-joined tokens, e.g. "city:Denver+FIELD(property_beds:3,4,5)+orderby:price desc+limit:9". | | style | React.CSSProperties | Inline styles applied directly to the <bb-widget> element. A height here sizes the widget (e.g. for InteractiveMap / SearchResults). |

Common type values include FeaturedGallery, FeaturedList, SearchForm, SearchResults, SearchDetails, QuickSearch, InteractiveMap, Communities, LcForm (lead capture), LoginPanel, Calculator, MarketReport, MarketStats, Brokers, OfficeRoster, and Disclaimer. The type prop accepts any string, so newer widget types work even before they're added to the typings.

TypeScript

The package is written in TypeScript and ships its own types. These are exported for your own typing needs:

import type {
  BuyingBuddyWidgetType,
  BuyingBuddyWidgetProps,
  BuyingBuddyProviderProps,
  BuyingBuddyContextValue,
} from "@buyingbuddy/react";

Caveats & limitations

  • One account per page. The Buying Buddy script installs a single global, so a page is expected to use one activationKey. Rendering two providers with different activation keys on the same page is not supported.
  • Client-side only. Widgets render in the browser after the script loads — nothing is server-rendered. There's no SSR/streaming output, so the listing content isn't in the initial HTML (relevant for SEO).
  • Changing a prop rebuilds the widget. Changing type or filter tears down and recreates the underlying <bb-widget>, losing in-widget state (map position, scroll, form input).
  • The script persists after unmount. Unmounting the provider does not remove the script or reset the global — remounting reuses the already-loaded runtime. This is intentional.
  • Error UI is built in. If the runtime script fails to load (network error), the provider renders its own inline error message in place of children (and fallback is not shown). You can't currently replace the default error UI. Note this only covers script load failure — an unauthorized domain loads fine but renders empty widgets (see Prerequisites).
  • ESM-only. This package ships as ES modules only (no CommonJS build). Use it in a project with ESM/bundler support.
  • Pre-release. This package is 0.x — the API may change.

Development

npm install
npm run build   # compile src/ to dist/ (JS + .d.ts)
npm run dev     # rebuild on change (tsc --watch)
npm test        # run the unit tests (vitest)

License

MIT © Blue Fire Group / Buying Buddy