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

@iblai/iblai-js

v1.20.2

Published

Unified JavaScript SDK for IBL.ai — re-exports data-layer, web-containers, and web-utils under a single package

Readme

@iblai/iblai-js

Unified JavaScript/TypeScript SDK for building applications on the IBL.ai platform. This package bundles the core IBL frontend libraries under a single namespace with convenient subpath imports for data fetching, UI components, authentication, and utilities.

Installation

npm install @iblai/iblai-js
# or
pnpm add @iblai/iblai-js
# or
yarn add @iblai/iblai-js

Peer Dependencies

The following peer dependencies must be installed in your project:

npm install react react-dom @reduxjs/toolkit react-redux @iblai/iblai-api

| Peer Dependency | Version | | -------------------- | ----------- | | react | >= 19.1.0 | | react-dom | >= 19.1.0 | | @reduxjs/toolkit | >= 2.7.0 | | react-redux | >= 9.2.0 | | @iblai/iblai-api | >= 4.166.0-ai |

next (>= 15) is an optional peer dependency, required only when using @iblai/iblai-js/web-containers/next.

@playwright/test and @axe-core/playwright are optional peer dependencies, required only when using @iblai/iblai-js/playwright.

Framework Configuration

Next.js

The SDK ships pre-compiled with 'use client' directives already applied to client components. Do not add @iblai/iblai-js or its sub-packages (@iblai/data-layer, @iblai/web-containers, @iblai/web-utils) to transpilePackages in your next.config.ts — they are ready to use as-is.

// next.config.ts
const nextConfig = {
  // Do NOT add @iblai packages here — they ship pre-built dist files
  // transpilePackages: ['@iblai/iblai-js'], // ← Don't do this
};

Node.js 25+

If you're running Node.js 25 or later, you must disable the experimental Web Storage API in Node.js. Without this flag, Node.js provides a server-side localStorage that conflicts with the SDK's browser-only storage guards, causing hydration errors and runtime failures.

Add this to your package.json scripts:

{
  "scripts": {
    "dev": "NODE_OPTIONS='--no-experimental-webstorage' next dev",
    "start": "NODE_OPTIONS='--no-experimental-webstorage' next start"
  }
}

Vite / CRA / Other React Frameworks

No special configuration required. Install and import directly.

Styling Setup (Tailwind CSS)

The SDK's React components use Tailwind CSS utility classes. To ensure these classes are included in your app's CSS output, you need two things in your global CSS file:

  1. Import the SDK's base styles (CSS variables for the IBL design system)
  2. Add a @source directive so your Tailwind instance scans the SDK's compiled components for class names

Tailwind CSS v4 (recommended)

In your global CSS file (e.g., app/globals.css):

@import 'tailwindcss';

/* SDK: custom base styles (CSS variables, no Tailwind utilities) */
@import '@iblai/iblai-js/web-containers/styles';

/* SDK: scan compiled components so Tailwind generates their utility classes */
@source "../node_modules/@iblai/iblai-js/dist/web-containers/source";

The @source directive tells your Tailwind instance to scan the SDK's compiled JavaScript for class names like lg:grid-cols-2, md:flex, hidden, etc. Without this, responsive and utility classes used only in SDK components won't be generated.

Tailwind CSS v3

In your tailwind.config.js, add the SDK's compiled output to the content array:

module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
    './node_modules/@iblai/iblai-js/dist/web-containers/source/**/*.js',
  ],
};

Then import the base styles in your CSS:

@import '@iblai/iblai-js/web-containers/styles';

Why this is needed

The SDK does not ship pre-built Tailwind utility CSS. Instead, it ships:

  • Base styles (styles.css) — CSS variables and custom component classes that don't depend on Tailwind
  • Compiled component source (source/index.esm.js) — the bundled JavaScript containing all Tailwind class name strings

Your app's single Tailwind instance scans both your own code and the SDK's compiled source, then generates one unified set of utility classes. This avoids CSS cascade conflicts that would occur if two separate Tailwind builds produced overlapping @layer utilities blocks.

Quick Start

1. Initialize the data layer

Call initializeDataLayer once at app startup, before any API calls or store creation. It configures the base URLs and a storage adapter that the SDK uses for token persistence.

import { initializeDataLayer } from '@iblai/iblai-js/data-layer';
import type { StorageService } from '@iblai/iblai-js/data-layer';

// Implement the StorageService interface for your environment.
// For web apps, wrap localStorage; for React Native, use AsyncStorage.
const storageService: StorageService = {
  getItem: async (key) => localStorage.getItem(key),
  setItem: async (key, value) => localStorage.setItem(key, value),
  removeItem: async (key) => localStorage.removeItem(key),
};

initializeDataLayer(
  'https://base.manager.iblai.app', // Platform manager URL (dmUrl)
  'https://learn.iblai.app',        // LMS URL (lmsUrl)
  storageService,
  // Optional: HTTP error handlers keyed by status code
  // { 401: () => redirectToLogin(), 403: () => showForbidden() }
);

2. Configure the Redux store

The SDK provides pre-bundled reducers and middleware for quick store setup. Choose the bundle that matches your app:

import { configureStore } from '@reduxjs/toolkit';
import { mentorReducer, mentorMiddleware } from '@iblai/iblai-js/data-layer';
// For Skills apps, use skillsReducer and skillsMiddleware instead

const store = configureStore({
  reducer: mentorReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(mentorMiddleware),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

3. Wrap your app with providers

import { Provider } from 'react-redux';
import { AuthProvider, MentorProvider } from '@iblai/iblai-js/web-utils';

function App({ children }) {
  return (
    <Provider store={store}>
      <AuthProvider>
        <MentorProvider>
          {children}
        </MentorProvider>
      </AuthProvider>
    </Provider>
  );
}

4. Use hooks and components

import { useChatV2 } from '@iblai/iblai-js/web-utils';
import { Loader } from '@iblai/iblai-js/web-containers';

function ChatPage({ mentorSlug }: { mentorSlug: string }) {
  const { messages, sendMessage, isLoading } = useChatV2({ mentor: mentorSlug });

  if (isLoading) return <Loader />;

  return (
    <div>
      {messages.map((msg) => (
        <p key={msg.id}>{msg.content}</p>
      ))}
      <button onClick={() => sendMessage('Hello!')}>Send</button>
    </div>
  );
}

Subpath Exports

@iblai/iblai-js/data-layer

Redux-based data layer for all IBL.ai API interactions. Built on RTK Query.

Key exports:

| Export | Description | | --- | --- | | initializeDataLayer(dmUrl, lmsUrl, storageService, httpErrorHandler?) | One-time SDK initialization (must be called before API usage) | | mentorReducer / mentorMiddleware | Pre-bundled Redux reducer and middleware for Mentor apps | | skillsReducer / skillsMiddleware | Pre-bundled Redux reducer and middleware for Skills apps | | IblDataLayer | Core singleton with storage and config access | | StorageService | Interface for pluggable persistence (localStorage, AsyncStorage, etc.) | | STORAGE_KEYS | Constants for token storage keys (DM_TOKEN_KEY, AXD_TOKEN_KEY, EDX_TOKEN_KEY) | | mentorApiSlice | RTK Query slice for mentor CRUD operations | | chatApiSlice | RTK Query slice for chat sessions and messages | | tenantApiSlice | RTK Query slice for tenant management | | userApiSlice | RTK Query slice for user profiles | | platformApiSlice | RTK Query slice for platform configuration | | notificationsApiSlice | RTK Query slice for notification management |

import {
  initializeDataLayer,
  mentorReducer,
  mentorMiddleware,
  skillsReducer,
  skillsMiddleware,
  IblDataLayer,
  STORAGE_KEYS,
  mentorApiSlice,
  chatApiSlice,
} from '@iblai/iblai-js/data-layer';
import type { StorageService } from '@iblai/iblai-js/data-layer';

@iblai/iblai-js/web-containers

Framework-agnostic React component library. These components work in any React app (Next.js, Vite, CRA, etc.).

Key exports:

| Export | Description | | --- | --- | | Loader | Loading spinner component | | TenantSwitch | Tenant/organization switcher dropdown | | useIframeMessageHandler | Hook for cross-iframe communication | | useLocalStorage | Hook for reactive localStorage state | | useTimeTracking | Hook for user activity time tracking | | useTauri | Hook for Tauri desktop app integration | | isTauriApp | Utility to detect Tauri runtime |

import {
  Loader,
  TenantSwitch,
  useIframeMessageHandler,
  useLocalStorage,
} from '@iblai/iblai-js/web-containers';

@iblai/iblai-js/web-containers/next

Next.js-specific components and hooks. Requires next as a dependency.

Key exports:

| Export | Description | | --- | --- | | SsoLogin | Full SSO login page component | | initializeLocalStorageWithObject | Populate localStorage from SSO data during login | | ErrorPage | Server-side error page | | ClientErrorPage | Client-side error boundary page | | UserProfileDropdown | User avatar/menu dropdown | | UserProfileModal | Full user profile editor modal | | Account | Account settings component | | OrganizationTab | Organization management tab | | useTimeTracker | Hook for page-level time tracking (uses next/navigation) | | useGetChatDetails | Hook for fetching chat session details |

import {
  SsoLogin,
  ErrorPage,
  UserProfileDropdown,
  useTimeTracker,
  useGetChatDetails,
} from '@iblai/iblai-js/web-containers/next';

@iblai/iblai-js/web-containers/sso

Framework-agnostic SSO utilities for handling authentication callbacks. Use these to build custom SSO login flows in any React framework.

Key exports:

| Export | Description | | --- | --- | | handleSsoCallback(options?) | Complete SSO callback handler — parses URL params, stores tokens, syncs cookies, and redirects | | parseSsoData(queryParam) | Decode and parse the base64-encoded SSO data from the callback URL | | initializeLocalStorageWithObject(data, keys) | Store parsed SSO data into localStorage using configurable keys | | syncSsoDataToCookies(data) | Sync authentication data to cookies for cross-subdomain sharing | | setCookie(name, value, days?) | Set a cookie with configurable expiry | | getBaseDomain() | Extract the base domain for cookie sharing (e.g., example.com from app.example.com) | | DEFAULT_SSO_STORAGE_KEYS | Default localStorage key names (CURRENT_TENANT, USER_DATA, TENANTS) |

import {
  handleSsoCallback,
  parseSsoData,
  initializeLocalStorageWithObject,
  DEFAULT_SSO_STORAGE_KEYS,
} from '@iblai/iblai-js/web-containers/sso';
import type { SsoStorageKeys, HandleSsoCallbackOptions } from '@iblai/iblai-js/web-containers/sso';

Example — handling an SSO callback:

// In your SSO callback route (e.g., /sso/callback)
import { handleSsoCallback } from '@iblai/iblai-js/web-containers/sso';

// This parses the URL, stores tokens, syncs cookies, and redirects:
await handleSsoCallback({
  redirectUrl: '/dashboard',  // Where to go after login
});

@iblai/iblai-js/web-utils

Authentication, state management, chat hooks, and general-purpose utilities.

Key exports:

| Export | Description | | --- | --- | | AuthProvider | React context provider for authentication state | | MentorProvider | React context provider for active mentor state | | TenantProvider | React context provider for tenant/organization state | | useChatV2 | Primary hook for chat interactions (send messages, stream responses) | | useAdvancedChat | Extended chat hook with tool use, file attachments, and advanced features | | useSubscriptionHandler | Hook for managing Stripe subscription flows | | isLoggedIn() | Check if the current user has a valid session | | redirectToAuthSpa(options?) | Redirect to the IBL auth SPA for login | | handleLogout() | Clear tokens and redirect to logout | | WithPermissions | HOC for role-based access control (RBAC) | | checkRbacPermission(permission, userPermissions) | Programmatic RBAC permission check | | chatSlice | Redux slice for chat UI state (selected mentor, session, etc.) |

import {
  AuthProvider,
  MentorProvider,
  TenantProvider,
  useChatV2,
  useAdvancedChat,
  isLoggedIn,
  redirectToAuthSpa,
  handleLogout,
  WithPermissions,
  checkRbacPermission,
  chatSlice,
} from '@iblai/iblai-js/web-utils';

@iblai/iblai-js/playwright

Shared Playwright test utilities for E2E testing across IBL.ai apps. Unlike the other subpaths, this is not a re-export — it contains original source code for test infrastructure shared between standalone app repos (mentorai, skillsai).

Requires: @playwright/test and @axe-core/playwright as dev dependencies.

pnpm add -D @playwright/test @axe-core/playwright dotenv cross-env

Config Generation

Generate a complete Playwright config with per-browser auth setup projects:

// e2e/playwright.config.ts
import { createPlaywrightConfig } from '@iblai/iblai-js/playwright';
import dotenv from 'dotenv';
import path from 'path';

dotenv.config({ path: path.resolve(__dirname, '.env.development') });

export default createPlaywrightConfig({
  platforms: [
    {
      name: 'skills',
      dependencies: ['setup'],
      otherTestMatch: ['**skills/*/*.spec.ts'],
    },
  ],
});

createPlaywrightConfig generates browser-specific setup projects (Chrome, Firefox, Safari, Edge) that each run auth.setup.ts, then creates test projects for each platform/browser combination. The devices option defaults to ['Desktop Chrome', 'Desktop Firefox', 'Desktop Safari', 'Desktop Edge'].

Auth Setup

Create an auth.setup.ts that authenticates once per browser and saves the storage state:

// e2e/auth.setup.ts
import { test as setup, createAuthSetup } from '@iblai/iblai-js/playwright';

setup(
  'authenticate',
  createAuthSetup({
    hostUrl: process.env.SKILLS_HOST || '',
    authHost: process.env.AUTH_HOST || '',
    appName: 'skills',
    postLoginUrlMatcher: (url) =>
      url.href.includes('/home') || url.href.includes('/start'),
  })
);

createAuthSetup supports four auth flows via the authFlow option: 'username_password' (default), 'magic_link', 'sso', and 'direct_sso'. Credentials are read from PLAYWRIGHT_USERNAME and PLAYWRIGHT_PASSWORD env vars.

Custom Reporter

Re-export the SDK's custom reporter for Playwright:

// e2e/custom-reporter.ts
export { CustomReporter as default } from '@iblai/iblai-js/playwright';

Test Helpers

import {
  // Extended test fixture with step support (optional — most tests use @playwright/test directly)
  test,
  expect,

  // Navigation
  safeWaitForURL,
  waitForPageLoad,
  isFirefox,

  // Page interaction
  waitForPageReady,
  checkAdminStatus,
  reliableClick,
  reliableFill,
  waitForDialogReady,
  selectDateFromCalendar,

  // Accessibility
  expectNoAccessibilityViolations,
  expectNoAccessibilityViolationsOnDialogs,

  // Auth helpers
  loginWithEmailAndPassword,
  signUpWithEmailAndPassword,
  loginWithMicrosoftIdp,
  AuthFlowBuilder,
  createAuthSetup,

  // Logging
  logger,

  // Email testing
  MailsacClient,

  // Config generation
  createPlaywrightConfig,
  createEnvConfig,
  CustomReporter,
} from '@iblai/iblai-js/playwright';

Environment Variables

Tests expect these env vars (set them in .env.development or CI):

| Variable | Description | | --- | --- | | SKILLS_HOST / MENTOR_NEXTJS_HOST | App host URL | | AUTH_HOST | Auth service URL | | PLAYWRIGHT_USERNAME | Login username | | PLAYWRIGHT_PASSWORD | Login password | | AUTH_FLOW | Auth flow type (username_password, magic_link, sso, direct_sso) | | AUTH_IDP | SSO identity provider name (required for sso/direct_sso flows) |

Directory Structure

Both mentorai and skillsai follow this layout:

e2e/
├── playwright.config.ts     # Uses createPlaywrightConfig()
├── auth.setup.ts            # Uses createAuthSetup()
├── custom-reporter.ts       # Re-exports CustomReporter
├── .env.development         # Environment variables
├── tests/
│   ├── utils.ts             # App-specific env var exports
│   ├── helpers.ts           # App-specific auth/login helpers
│   ├── shared.ts            # Shared test helper functions
│   └── <platform>/          # Test spec files by feature
└── utils/                   # App-specific helper modules

MCP Server (AI-Assisted Development)

This package includes an MCP (Model Context Protocol) server (@iblai/mcp) that provides AI assistants like Claude with authoritative documentation about the IBL packages — components, hooks, API queries, provider setup patterns, and more.

Usage with Claude Code

Option 1 — npx (no install needed):

claude mcp add --transport stdio iblai-js-mcp -- npx @iblai/mcp

pnpm projects: If your project already has @iblai/iblai-js installed, npx may detect the transitive @iblai/mcp dependency locally but fail to link its binary. Use pnpm dlx instead:

claude mcp add --transport stdio iblai-js-mcp -- pnpm dlx @iblai/mcp

Option 2 — after installing @iblai/iblai-js globally:

npm install -g @iblai/iblai-js
claude mcp add --transport stdio iblai-js-mcp -- ibl-mcp-server

Option 3 — project-level config (shared with team via git):

Create a .mcp.json file at your project root:

{
  "mcpServers": {
    "iblai-js-mcp": {
      "command": "npx",
      "args": ["@iblai/mcp"]
    }
  }
}

For pnpm projects where @iblai/iblai-js is a dependency:

{
  "mcpServers": {
    "iblai-js-mcp": {
      "command": "pnpm",
      "args": ["dlx", "@iblai/mcp"]
    }
  }
}

Claude Code will detect this file and prompt team members to approve the server on first use.

What the MCP Server Provides

| Category | Tool / Resource | Description | | --- | --- | --- | | Components | get_component_info | Detailed props, usage examples, and category for any UI component | | Hooks | get_hook_info | Parameters, return types, and examples for React hooks | | API Queries | get_api_query_info | RTK Query endpoint details and usage patterns | | Providers | get_provider_setup | Correct provider hierarchy for each app type | | Page Templates | create_page_template | Generate new pages following IBL patterns | | Playwright | get_playwright_helper_info | E2E test helper documentation | | Guides | ibl://guides/* | Layout rules, RBAC patterns, theming, Playwright setup | | Package Docs | ibl://packages/* | Full package documentation for each subpath |

Usage with Other MCP Clients

The server uses stdio transport and follows the MCP specification. Any MCP-compatible client can use it:

# Run directly
npx @iblai/mcp

# Or if installed globally via @iblai/iblai-js
ibl-mcp-server

Relationship to Standalone Packages

@iblai/iblai-js is a convenience wrapper. Each subpath is a direct re-export from its standalone package:

| Subpath Import | Source Package | | -------------------------------------- | ---------------------------- | | @iblai/iblai-js/data-layer | @iblai/data-layer | | @iblai/iblai-js/web-containers | @iblai/web-containers | | @iblai/iblai-js/web-containers/next | @iblai/web-containers/next| | @iblai/iblai-js/web-containers/sso | @iblai/web-containers/sso | | @iblai/iblai-js/web-utils | @iblai/web-utils | | @iblai/iblai-js/playwright | Original source (not a re-export) |

You can use the standalone packages directly if you only need one module. This unified package is useful when you need multiple IBL libraries and prefer a single dependency. The playwright subpath is unique — it contains original source code rather than re-exporting a standalone package.

TypeScript

All subpath exports include TypeScript declarations. Types are co-located with their runtime exports:

import type { StorageService } from '@iblai/iblai-js/data-layer';
import type { SsoStorageKeys, HandleSsoCallbackOptions } from '@iblai/iblai-js/web-containers/sso';
import type { UserProfileDropdownProps, UserMetadata } from '@iblai/iblai-js/web-containers/next';

Build

pnpm build

Produces CommonJS, ESM, and TypeScript declaration files under dist/.

Publishing (Maintainers)

This package uses workspace:* references for its dependencies on @iblai/data-layer, @iblai/web-containers, and @iblai/web-utils. These are automatically converted to real version numbers during publish.

You must use pnpm publish (not npm publish) to publish this package. Only pnpm publish converts workspace: references to actual version numbers. Using npm publish will publish with raw workspace:* strings, which breaks installation for all external consumers.

# Correct — converts workspace:* to resolved versions
pnpm publish --no-git-checks

# Wrong — leaves workspace:* in published package.json
npm publish  # ← Never use this for workspace packages

Publish the underlying packages first (in dependency order), then this package:

  1. @iblai/data-layer — no internal deps
  2. @iblai/web-utils — depends on data-layer
  3. @iblai/web-containers — depends on data-layer and web-utils
  4. @iblai/iblai-js — depends on all three

Contributing

See CONTRIBUTING.md for the full development guide, including:

  • How to make changes to the underlying packages (data-layer, web-utils, web-containers)
  • How to test locally with pnpm link against consumer apps like skillsAI and mentorAI
  • How the CI publishing pipeline works (tag-based for iblai-js, changeset-based for underlying packages)
  • Troubleshooting common issues

License

ISC