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

@codiris/brainboard-sdk

v1.0.0

Published

Embed Codiris Brainboard whiteboard functionality into your applications

Readme

@codiris/brainboard-sdk

Embed Codiris Brainboard whiteboard functionality into your applications. Build collaborative visual experiences with AI-powered features.

Installation

npm install @codiris/brainboard-sdk
# or
yarn add @codiris/brainboard-sdk
# or
pnpm add @codiris/brainboard-sdk

Quick Start

Basic Usage (Vanilla JS/TS)

import { BrainboardClient } from '@codiris/brainboard-sdk';

// Initialize the client
const client = new BrainboardClient({
  apiKey: 'your-api-key',
  workspaceId: 'your-workspace-id', // optional
});

// List boards
const { data: boards } = await client.listBoards();

// Create a board
const { data: board } = await client.createBoard({
  name: 'My Board',
  description: 'A collaborative whiteboard',
});

// Add objects to the board
await client.createObject(board.id, {
  type: 'sticky',
  x: 100,
  y: 100,
  width: 200,
  height: 200,
  text: 'Hello World!',
  fill: '#ffeb3b',
});

React Usage

import { BrainboardProvider, BrainboardEmbed, useBoards } from '@codiris/brainboard-sdk/react';

// Wrap your app with the provider
function App() {
  return (
    <BrainboardProvider config={{ apiKey: 'your-api-key' }}>
      <MyComponent />
    </BrainboardProvider>
  );
}

// Use the embed component
function MyComponent() {
  const { boards, createBoard } = useBoards();

  return (
    <div>
      <button onClick={() => createBoard({ name: 'New Board' })}>
        Create Board
      </button>

      {boards[0] && (
        <BrainboardEmbed
          boardId={boards[0].id}
          width="100%"
          height="600px"
          showToolbar
          onBoardChange={(board) => console.log('Board updated:', board)}
        />
      )}
    </div>
  );
}

Features

Board Management

// List boards with filtering
const { data } = await client.listBoards({
  status: 'active',
  search: 'project',
  page: 1,
  pageSize: 20,
});

// Get a specific board
const { data: board } = await client.getBoard('board-id');

// Update a board
await client.updateBoard('board-id', {
  name: 'Updated Name',
  isPublic: true,
});

// Delete a board
await client.deleteBoard('board-id');

// Duplicate a board
const { data: newBoard } = await client.duplicateBoard('board-id', 'Copy of Board');

Objects (Canvas Elements)

// Create various object types
await client.createObject(boardId, {
  type: 'text',
  x: 100, y: 100,
  text: 'Hello World',
  fontSize: 24,
});

await client.createObject(boardId, {
  type: 'shape',
  x: 200, y: 200,
  width: 150, height: 100,
  shapeType: 'rectangle',
  fill: '#3b82f6',
});

await client.createObject(boardId, {
  type: 'sticky',
  x: 400, y: 100,
  width: 200, height: 200,
  text: 'Idea #1',
  fill: '#fef08a',
});

// Batch create
await client.createObjects(boardId, [
  { type: 'sticky', x: 100, y: 100, text: 'Task 1' },
  { type: 'sticky', x: 320, y: 100, text: 'Task 2' },
  { type: 'sticky', x: 540, y: 100, text: 'Task 3' },
]);

// Update objects
await client.updateObject(boardId, objectId, {
  text: 'Updated text',
  fill: '#22c55e',
});

// Delete objects
await client.deleteObject(boardId, objectId);
await client.deleteObjects(boardId, [id1, id2, id3]);

Supported Object Types

| Type | Description | |------|-------------| | sticky | Sticky note with text | | text | Text block | | shape | Shapes (rectangle, circle, triangle, diamond, star, etc.) | | line | Connecting line | | arrow | Arrow connector | | image | Image element | | card | Card with title, description, tags | | table | Data table | | kanban | Kanban board | | code | Code block with syntax highlighting | | chart | Chart (line, bar, pie, etc.) | | embed | External embed (YouTube, Figma, etc.) | | frame | Presentation frame | | draw | Freehand drawing |

Collaboration

// Get board members
const { data: members } = await client.getMembers(boardId);

// Invite a member
await client.inviteMember(boardId, '[email protected]', 'editor');

// Update member role
await client.updateMemberRole(boardId, memberId, 'viewer');

// Remove a member
await client.removeMember(boardId, memberId);

// Generate share link
const { data } = await client.generateShareLink(boardId, {
  canEdit: false,
  expiresAt: '2024-12-31T23:59:59Z',
});
console.log(data.shareUrl);

Comments

// Get comments
const { data: comments } = await client.getComments(boardId);

// Add a comment
await client.addComment(boardId, 'Great idea!', objectId);

// Reply to a comment
await client.addComment(boardId, 'I agree!', objectId, parentCommentId);

// Resolve a comment
await client.resolveComment(boardId, commentId);

AI Features

// Generate content
const { data } = await client.generateContent({
  prompt: 'Create a user journey map for an e-commerce checkout flow',
  type: 'diagram',
});

// Chat with AI about board content
const { data: response } = await client.chat(boardId, [
  { role: 'user', content: 'What are the main themes on this board?' }
]);
console.log(response.content);
console.log(response.sources); // Cited sources from the board

// Execute natural language commands
await client.executeCommand(boardId, 'make all sticky notes blue');
await client.executeCommand(boardId, 'align selected items to the left', selectedIds);

// Generate audio overview
const { data: audio } = await client.generateAudioOverview(boardId, 'podcast');
console.log(audio.audioUrl, audio.script);

Templates

// List templates
const { data: templates } = await client.listTemplates('brainstorming');

// Create from template
const { data: board } = await client.createFromTemplate(
  'template-id',
  'My Brainstorm Session'
);

// Save board as template
await client.saveAsTemplate(boardId, 'My Template', 'Reusable board layout');

Import & Export

// Import from URL
await client.importFromUrl(boardId, 'https://example.com/article', { x: 100, y: 100 });

// Extract from PDF
await client.extractPdf(boardId, 'https://example.com/document.pdf');

// Create from interview data
await client.createFromInterview(interviewId, 'Interview Summary Board');

// Export
const { data: json } = await client.exportAsJson(boardId);
const { data: image } = await client.exportAsImage(boardId, 'png', { scale: 2 });
const { data: pdf } = await client.exportAsPdf(boardId, { includeFrames: true });

React Hooks

useBoard(boardId)

const { board, loading, error, updateBoard } = useBoard('board-id');

useBoards(options?)

const { boards, total, loading, createBoard, deleteBoard } = useBoards({
  status: 'active',
  page: 1,
});

useBoardObjects(boardId)

const {
  objects,
  selectedObjects,
  createObject,
  updateObject,
  deleteObject,
  selectObject,
  clearSelection,
} = useBoardObjects('board-id');

useBoardMembers(boardId)

const { members, inviteMember, removeMember } = useBoardMembers('board-id');

useBoardComments(boardId, objectId?)

const { comments, addComment, deleteComment } = useBoardComments('board-id');

useBrainboardChat(boardId)

const { messages, loading, sendMessage, clearMessages } = useBrainboardChat('board-id');

// Send message with source grounding
await sendMessage('What patterns do you see?', true);

useBrainboardGenerate()

const { loading, generate } = useBrainboardGenerate();

const result = await generate({
  prompt: 'Create a SWOT analysis template',
  type: 'diagram',
});

useBrainboardEvent(type, callback)

useBrainboardEvent('object:created', (event) => {
  console.log('New object:', event.data);
});

useTemplates(category?)

const { templates, createFromTemplate } = useTemplates('planning');

React Components

<BrainboardEmbed />

Full-featured embedded board editor.

<BrainboardEmbed
  boardId="board-id"
  width="100%"
  height="600px"
  readOnly={false}
  showToolbar={true}
  showSidebar={false}
  showComments={true}
  showMinimap={true}
  theme="light"
  onReady={() => console.log('Ready!')}
  onBoardChange={(board) => console.log(board)}
  onObjectSelect={(objects) => console.log(objects)}
/>

<BrainboardViewer />

Read-only board viewer.

<BrainboardViewer
  boardId="board-id"
  width="100%"
  height="400px"
  showNavigation={true}
  autoFit={true}
/>

<BrainboardThumbnail />

Board thumbnail preview.

<BrainboardThumbnail
  board={board}
  width={200}
  height={150}
  onClick={() => navigate(`/boards/${board.id}`)}
/>

<BrainboardList />

Grid view of boards.

<BrainboardList
  boards={boards}
  gridColumns={3}
  onSelect={(board) => setSelectedBoard(board)}
  emptyMessage="No boards yet"
/>

Events

Listen to real-time events:

import { globalEvents } from '@codiris/brainboard-sdk';

globalEvents.on('board:updated', (event) => {
  console.log('Board updated:', event.data);
});

globalEvents.on('object:created', (event) => {
  console.log('Object created:', event.data);
});

globalEvents.on('user:joined', (event) => {
  console.log('User joined:', event.data);
});

// Listen to all events
globalEvents.onAll((event) => {
  console.log(`${event.type}:`, event.data);
});

Event Types

| Event | Description | |-------|-------------| | board:loaded | Board finished loading | | board:updated | Board properties changed | | object:created | New object added | | object:updated | Object modified | | object:deleted | Object removed | | object:selected | Objects selected | | object:deselected | Selection cleared | | camera:moved | Viewport changed | | user:joined | User joined the board | | user:left | User left the board | | cursor:moved | User cursor moved | | comment:added | New comment added | | error | Error occurred |

Configuration

const client = new BrainboardClient({
  // Required
  apiKey: 'your-api-key',

  // Optional
  baseUrl: 'https://app.codiris.ai/api', // Custom API endpoint
  workspaceId: 'workspace-id',            // Default workspace
  userId: 'user-id',                      // Current user ID
  userEmail: '[email protected]',          // Current user email
  userName: 'User Name',                  // Current user name
  debug: false,                           // Enable debug logging
});

TypeScript Support

The SDK is fully typed. Import types as needed:

import type {
  Board,
  BoardObject,
  BoardMember,
  CreateBoardInput,
  CreateObjectInput,
  BrainboardConfig,
} from '@codiris/brainboard-sdk';

Error Handling

All API methods return a consistent response format:

const response = await client.getBoard('board-id');

if (response.success) {
  console.log(response.data);
} else {
  console.error(response.error);
}

With React hooks, errors are exposed via the error property:

const { board, loading, error } = useBoard('board-id');

if (error) {
  return <div>Error: {error.message}</div>;
}

License

MIT