JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 18
  • Score
    100M100P100Q73450F
  • License MIT

React SDK for Pillar product copilot — AI assistant for SaaS and web apps

Package Exports

  • @pillar-ai/react

Readme

@pillar-ai/react

React bindings for Pillar, the open-source product copilot SDK. Add an AI assistant to your React or Next.js app that executes tasks using your UI. GitHub · Docs

npm version npm downloads License: MIT TypeScript

What is Pillar?

Pillar is a product copilot for SaaS and web apps. Users say what they want, and Pillar uses your UI to make it happen.

A CRM user could ask:

"Close the Walmart deal as won and notify implementation"

An analytics user could ask:

"Add a weekly signups chart to my dashboard"

Pillar understands the intent, builds a plan, and executes it client-side with the user's session. No proxy servers, no token forwarding.

Documentation

Full docs · React quickstart · API reference

Installation

npm install @pillar-ai/react
# or
pnpm add @pillar-ai/react
# or
yarn add @pillar-ai/react

Quick start

1. Get your agent slug

Sign up at app.trypillar.com and grab your agent slug from the dashboard.

2. Add the provider

Wrap your app with PillarProvider:

import { PillarProvider } from "@pillar-ai/react";

function App() {
  return (
    <PillarProvider agentSlug="your-agent-slug">
      <YourApp />
    </PillarProvider>
  );
}

For Next.js App Router, create a client wrapper:

// providers/PillarSDKProvider.tsx
"use client";

import { PillarProvider } from "@pillar-ai/react";

export function PillarSDKProvider({ children }: { children: React.ReactNode }) {
  return (
    <PillarProvider agentSlug="your-agent-slug">{children}</PillarProvider>
  );
}
// app/layout.tsx
import { PillarSDKProvider } from "@/providers/PillarSDKProvider";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <PillarSDKProvider>{children}</PillarSDKProvider>
      </body>
    </html>
  );
}

3. Define your first tool

Tools tell Pillar what your app can do. Define them with the usePillarTool hook:

import { usePillarTool } from "@pillar-ai/react";
import { useRouter } from "next/navigation";

export function usePillarTools() {
  const router = useRouter();

  usePillarTool({
    name: "open_settings",
    type: "navigate",
    description: "Navigate to the settings page",
    examples: ["open settings", "go to settings"],
    autoRun: true,
    execute: () => router.push("/settings"),
  });
}

Call usePillarTools() from any component inside PillarProvider (e.g. your layout).

Defining tools

Tools are the building blocks. When a user makes a request, Pillar matches intent to tools and executes them.

Single tool

usePillarTool({
  name: "open_dashboard",
  type: "navigate",
  description: "Navigate to the main dashboard",
  examples: ["go to dashboard", "show me the dashboard"],
  execute: () => router.push("/dashboard"),
});

Tool with input schema

Pillar extracts parameters from the user's request:

usePillarTool({
  name: "view_user_profile",
  type: "navigate",
  description: "View a specific user's profile page",
  inputSchema: {
    type: "object",
    properties: {
      userId: { type: "string", description: "The user ID to view" },
    },
    required: ["userId"],
  },
  execute: ({ userId }) => router.push(`/users/${userId}`),
});

Multiple tools at once

usePillarTool([
  {
    name: "open_billing",
    type: "navigate",
    description: "Navigate to billing and subscription settings",
    examples: ["go to billing", "view my subscription"],
    execute: () => router.push("/settings/billing"),
  },
  {
    name: "open_team",
    type: "navigate",
    description: "Navigate to team management page",
    examples: ["manage team", "invite team members"],
    execute: () => router.push("/settings/team"),
  },
]);

Tool types

Type Use case
navigate Navigate to a page or view
trigger_tool Run a function (export, toggle, API call)
query Return data to the assistant
external_link Open an external URL
copy_text Copy text to clipboard

See Setting Up Tools for the full guide.

Hooks

usePillar

Access SDK state and methods:

import { usePillar } from "@pillar-ai/react";

function MyComponent() {
  const {
    pillar, // SDK instance
    isReady, // Whether SDK is initialized
    isPanelOpen, // Panel open state
    open, // Open the panel
    close, // Close the panel
    toggle, // Toggle the panel
    navigate, // Navigate to a view
    setTheme, // Update theme at runtime
    on, // Subscribe to events
  } = usePillar();

  if (!isReady) return <div>Loading...</div>;

  return <button onClick={() => open()}>Get Help</button>;
}

useHelpPanel

Panel-specific controls:

import { useHelpPanel } from "@pillar-ai/react";

function HelpButton() {
  const {
    isOpen,
    open,
    close,
    toggle,
    openArticle,
    openCategory,
    openSearch,
    openChat,
  } = useHelpPanel();

  return (
    <div>
      <button onClick={toggle}>{isOpen ? "Close" : "Help"}</button>
      <button onClick={openChat}>Ask co-pilot</button>
    </div>
  );
}
Method Description
open(options?) Open the panel
close() Close the panel
toggle() Toggle open/closed
openArticle(slug) Open a specific article
openCategory(slug) Open a category view
openSearch(query?) Open search with optional query
openChat() Open the co-pilot chat view

Components

PillarProvider

The root component. Initializes and configures the SDK.

Prop Type Required Description
agentSlug string Yes Your agent slug from app.trypillar.com
config object No SDK configuration (panel, theme, triggers)
onTask (task) => void No Generic handler for dynamic tools
<PillarProvider
  agentSlug="your-agent-slug"
  config={{
    panel: { position: "right", mode: "push", width: 400 },
    theme: { mode: "auto", colors: { primary: "#2563eb" } },
  }}
>
  {children}
</PillarProvider>

PillarPanel

For custom panel placement, set panel.container to 'manual' and render PillarPanel where you want it:

import { PillarProvider, PillarPanel } from "@pillar-ai/react";

function App() {
  return (
    <PillarProvider
      agentSlug="your-agent-slug"
      config={{ panel: { container: "manual" } }}
    >
      <div className="layout">
        <main>Your content</main>
        <PillarPanel className="sidebar-panel" />
      </div>
    </PillarProvider>
  );
}

Generic task handler

For dynamic or backend-triggered tools, use the onTask prop on PillarProvider. For most cases, prefer usePillarTool which co-locates the handler with the tool definition.

<PillarProvider
  agentSlug="your-agent-slug"
  onTask={(task) => {
    if (task.name.startsWith("nav_")) {
      router.push(task.data.path);
      return;
    }

    switch (task.name) {
      case "notification":
        showNotification(task.data.message);
        break;
      case "refresh_data":
        queryClient.invalidateQueries();
        break;
    }
  }}
>
  {children}
</PillarProvider>

Inline UI with render

For inline_ui tools, use the render prop to display custom React components in the chat. The AI agent provides data directly to the render component — no execute function needed:

import { usePillarTool, type ToolRenderProps } from "@pillar-ai/react";

function InviteCard({ data }: ToolRenderProps<{ emails: string[]; teamName: string }>) {
  return (
    <div className="p-4 border rounded">
      <p>Invite {data.emails?.length || 0} members to {data.teamName}</p>
    </div>
  );
}

usePillarTool({
  name: "invite_members",
  description: "Invite team members via email",
  type: "inline_ui",
  inputSchema: {
    type: "object",
    properties: {
      emails: { type: "array", items: { type: "string" } },
      teamName: { type: "string" },
    },
  },
  render: InviteCard,
});

The render component receives:

  • data — Data provided by the AI agent (extracted from the conversation via inputSchema)
  • onStateChange?(state, message?) — optional loading/success/error states

Exports

Export Description
PillarProvider Context provider that initializes the SDK
PillarPanel Component for custom panel placement
usePillar Hook for SDK access and panel control
useHelpPanel Hook for panel-specific controls
usePillarTool Hook to register tools
Package Description
@pillar-ai/sdk Core vanilla JS SDK
@pillar-ai/vue Vue 3 bindings
@pillar-ai/svelte Svelte bindings

Requirements

  • React 17+ or React 19+
  • React DOM 17+ or React DOM 19+

License

MIT