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

@astrocal/react

v0.1.1

Published

React SDK for Astrocal — Provider, hooks, and embeddable booking widget for React apps

Readme

@astrocal/react

React SDK for Astrocal — Provider, hooks, API client, and embeddable booking widget for React apps.

Installation

npm install @astrocal/react
# or
pnpm add @astrocal/react

For the widget component, also install the optional peer dependency:

npm install @astrocal/widget

Quick Start

Provider Setup

Wrap your app (or a subtree) with AstrocalProvider to make the API client available via hooks:

import { AstrocalProvider } from "@astrocal/react";

function App() {
  return (
    <AstrocalProvider apiKey="sk_live_...">
      <MySchedulingPage />
    </AstrocalProvider>
  );
}

Using the Hook

Access the typed API client anywhere inside the provider:

import { useAstrocal } from "@astrocal/react";

function EventTypesList() {
  const astrocal = useAstrocal();
  const [eventTypes, setEventTypes] = useState([]);

  useEffect(() => {
    astrocal.eventTypes.list().then(({ data }) => setEventTypes(data));
  }, [astrocal]);

  return (
    <ul>
      {eventTypes.map((et) => (
        <li key={et.id}>
          {et.title} — {et.duration_minutes}min
        </li>
      ))}
    </ul>
  );
}

Standalone Client

Use the API client without React context:

import { AstrocalApiClient } from "@astrocal/react";

const client = new AstrocalApiClient({ apiKey: "sk_live_..." });

const { data: eventTypes } = await client.eventTypes.list();
const { slots } = await client.availability.query({
  event_type_id: eventTypes[0].id,
  start: "2026-03-01",
  end: "2026-03-07",
  timezone: "America/New_York",
});

Widget Component

The AstrocalWidget component wraps @astrocal/widget for seamless React integration.

Inline Mode

Renders the booking calendar directly in your page:

import { AstrocalWidget } from "@astrocal/react";

function BookingPage() {
  return (
    <AstrocalWidget
      eventTypeId="evt_abc123"
      timezone="America/New_York"
      colorScheme="light"
      onBookingCreated={(booking) => {
        console.log("Booked!", booking.id);
      }}
    />
  );
}

Popup Mode

Wraps a trigger element that opens the widget as a modal on click:

import { AstrocalWidget } from "@astrocal/react";

function BookButton() {
  return (
    <AstrocalWidget eventTypeId="evt_abc123" mode="popup">
      <button>Book a Meeting</button>
    </AstrocalWidget>
  );
}

Widget Props

| Prop | Type | Default | Description | | ------------------ | ----------------------------- | ---------------------------- | ----------------------------- | | eventTypeId | string | — | Event type UUID (required) | | mode | "inline" \| "popup" | "inline" | Render mode | | apiUrl | string | "https://api.astrocal.dev" | API base URL | | timezone | string | auto-detect | IANA timezone | | theme | ThemeConfig | — | CSS custom property overrides | | colorScheme | "light" \| "dark" \| "auto" | "auto" | Color scheme | | demo | boolean | false | Demo mode (mock data) | | onBookingCreated | (booking) => void | — | Booking success callback | | onError | (error) => void | — | Error callback | | onClose | () => void | — | Popup close callback | | className | string | — | Container CSS class | | style | CSSProperties | — | Container inline styles |

API Client Methods

Event Types

client.eventTypes.list(); // GET /v1/event-types
client.eventTypes.get(id); // GET /v1/event-types/:id
client.eventTypes.create(input); // POST /v1/event-types
client.eventTypes.update(id, input); // PATCH /v1/event-types/:id
client.eventTypes.delete(id); // DELETE /v1/event-types/:id

Bookings

client.bookings.list(params?)               // GET /v1/bookings
client.bookings.get(id)                     // GET /v1/bookings/:id
client.bookings.cancel(id, reason?)         // POST /v1/bookings/:id/cancel
client.bookings.reschedule(id, input)       // POST /v1/bookings/:id/reschedule

Availability

client.availability.query(params); // GET /v1/availability

Webhooks

client.webhooks.list()                      // GET /v1/webhooks
client.webhooks.get(id)                     // GET /v1/webhooks/:id
client.webhooks.create(input)               // POST /v1/webhooks
client.webhooks.update(id, input)           // PATCH /v1/webhooks/:id
client.webhooks.delete(id)                 // DELETE /v1/webhooks/:id
client.webhooks.listDeliveries(id, params?) // GET /v1/webhooks/:id/deliveries
client.webhooks.retryDelivery(whId, delId)  // POST /v1/webhooks/:id/deliveries/:id/retry

Usage

client.usage.get()                          // GET /v1/usage
client.usage.summary(period?)               // GET /v1/usage/summary

API Keys

client.apiKeys.list(); // GET /v1/api-keys
client.apiKeys.create(input); // POST /v1/api-keys
client.apiKeys.revoke(id); // DELETE /v1/api-keys/:id

Error Handling

All API errors throw AstrocalError:

import { AstrocalError } from "@astrocal/react";

try {
  await client.eventTypes.get("invalid_id");
} catch (err) {
  if (err instanceof AstrocalError) {
    console.log(err.status); // 404
    console.log(err.code); // "not_found"
    console.log(err.message); // "Event type not found"
  }
}

Next.js

Works with both App Router and Pages Router. For App Router, the provider and widget include "use client" directives automatically.

// app/layout.tsx
import { AstrocalProvider } from "@astrocal/react";

export default function RootLayout({ children }) {
  return (
    <AstrocalProvider apiKey={process.env.NEXT_PUBLIC_ASTROCAL_KEY!}>{children}</AstrocalProvider>
  );
}

TypeScript

All types are exported for use in your application:

import type {
  EventType,
  Booking,
  AvailabilitySlot,
  PaginatedResponse,
  AstrocalClient,
} from "@astrocal/react";

License

MIT