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

codicent-app-sdk

v0.4.26

Published

SDK for building AI-powered applications with Codicent

Readme

codicent-app-sdk

React SDK for building AI-powered, multi-tenant white-label applications on top of the Codicent platform.

Current version: 0.4.16 · License: MIT · Peer deps: React ≥16.8, Fluent UI v9, react-router-dom v6


What it provides

  • CodicentService — data CRUD, chat, file upload, token management
  • React components — Page, Content, Chat, ListView, Markdown, UploadFile, and ~25 more
  • Pages — AppFrame, Chat, Compose, Sales, Search, Snap, Login, Logout, and more
  • Hooks — useCodicentApp, useLocalization, useChat, useRealtimeVoiceAI, useAuthState, and more
  • Global config — initCodicentApp() initializer consumed by all SDK components
  • Full TypeScript types

This SDK is the primary dependency of codicentapp/ (the modern white-label Vite app) in the monorepo. See codicentapp/ for a complete real-world usage reference.


Installation

From npm

npm install codicent-app-sdk

Monorepo local dependency (recommended during development)

In your app's package.json:

"dependencies": {
  "codicent-app-sdk": "file:../codicent-app-sdk"
}

Then npm install in your app.

Peer dependencies

Install these alongside the SDK:

npm install react react-dom react-router-dom @fluentui/react-components mermaid

Usage

1. Initialize the SDK (once, at app startup)

Call initCodicentApp() before rendering your React tree. It stores config globally so all SDK components and hooks can read it.

// main.tsx
import { initCodicentApp } from 'codicent-app-sdk';
import { translations } from './services/translationService';
import { getAppConfig } from './appconfig';

initCodicentApp({
  API_BASE_URL: 'https://codicent.com/',
  APP_NAME: 'my-crm',
  APP_PREFIX: 'mycrm',
  USER_PREFIX: 'users',
  APP_CONFIG: getAppConfig(),      // buttons, listDefinitions, chatInstructions
  TRANSLATIONS: translations,      // { sv: {...}, en: {...}, ... }
  USE_REALTIME_SESSION_ENDPOINT: true,
});

2. Wrap with Auth0 and FluentProvider

The SDK components depend on these providers being present in the React tree:

// main.tsx (continued)
import { Auth0Provider } from '@auth0/auth0-react';
import { FluentProvider, webLightTheme } from '@fluentui/react-components';
import { createRoot } from 'react-dom/client';

createRoot(document.getElementById('root')!).render(
  <Auth0Provider domain={AUTH0_DOMAIN} clientId={AUTH0_CLIENT_ID} authorizationParams={{ redirect_uri: window.location.origin }}>
    <FluentProvider theme={webLightTheme}>
      <App />
    </FluentProvider>
  </Auth0Provider>
);

3. Use useCodicentApp() in your root App component

// App.tsx
import { useCodicentApp } from 'codicent-app-sdk';
import { useAuth0 } from '@auth0/auth0-react';
import { HashRouter, Routes, Route } from 'react-router-dom';
import { Chat } from 'codicent-app-sdk';
import { ListPage } from './pages/ListPage';

export default function App() {
  const auth0 = useAuth0();
  const state = useCodicentApp({ auth0 });

  if (!auth0.isAuthenticated) {
    auth0.loginWithRedirect();
    return null;
  }

  return (
    <HashRouter>
      <Routes>
        <Route path="/chat" element={<Chat state={state} title="Chat" />} />
        <Route path="/list" element={<ListPage state={state} />} />
      </Routes>
    </HashRouter>
  );
}

4. Build pages using SDK components

// pages/ListPage.tsx
import { Page, Content, ListView, useLocalization, CodicentAppState, DataMessage } from 'codicent-app-sdk';
import { useEffect, useState } from 'react';
import { APP_CONFIG } from '../appconfig';
import { APP_BUTTONS } from '../constants';

export const ListPage: React.FC<{ state: CodicentAppState }> = ({ state }) => {
  const { service } = state;
  const { t } = useLocalization();
  const [data, setData] = useState<DataMessage[]>([]);

  useEffect(() => {
    service.readDataMessages('customer2').then(setData);
  }, [service]);

  const columns = APP_CONFIG.apps[APP_BUTTONS].listDefinitions['customer2'];

  return (
    <Page title={t('Kunder')}>
      <Content>
        <ListView data={data} columns={columns} />
      </Content>
    </Page>
  );
};

initCodicentApp() configuration options

Required:

| Key | Type | Description | |-----|------|-------------| | API_BASE_URL | string | Codicent backend URL, e.g. "https://codicent.com/" | | APP_NAME | string | Application identifier |

Common optional:

| Key | Type | Description | |-----|------|-------------| | APP_PREFIX | string | URL/namespace prefix for this app | | USER_PREFIX | string | User namespace prefix (default: "users") | | APP_CONFIG | AppConfig | Per-app config: buttons, listDefinitions, chatInstructions | | TRANSLATIONS | object | i18n map { sv: {...}, en: {...} }. Swedish strings are used as keys. | | DEFAULT_LANGUAGE | string | Default language code (e.g. "sv", "en") | | USE_REALTIME_SESSION_ENDPOINT | boolean | Use secure backend session token for voice AI (default: true) | | REALTIME_VOICE_MODEL | string | Voice model: "alloy", "shimmer", or "echo" (default: "alloy") | | SUBSCRIPTION_NEEDED | boolean | Redirect to purchase page if no active subscription | | BUTTON_BORDER_RADIUS | string | CSS border-radius for nav buttons | | BUTTON_BACKGROUND_COLOR | string | Background color for nav buttons |

Compose page GPS options:

| Key | Value | Behaviour | |-----|-------|-----------| | COMPOSE_HIDE_LOCATION | "true" | Hides GPS toggle button entirely | | COMPOSE_HIDE_LOCATION | "false" (default) | Shows GPS toggle; users opt-in per post | | COMPOSE_AUTO_LOCATION | "true" | Captures GPS automatically on page open |

When a location is attached, #gps(lat,lon) is appended to message content — queryable via tag search and readable by AI.


API Reference

CodicentService

The main service class for all data and chat operations. Access it via state.service from useCodicentApp().

Data message CRUD:

createDataMessage(tag: string, data: object, codicent?: string): Promise<string>

readDataMessages(
  tag: string,
  search?: string,
  codicent?: string,
  start?: number,
  length?: number,
  afterTimestamp?: string,
  beforeTimestamp?: string,
  dataFilters?: Record<string, string>
): Promise<DataMessage[]>

readOneDataMessage(id: string): Promise<DataMessage | null>

updateDataMessage(id: string, data: object, codicent?: string): Promise<string>

deleteDataMessage(id: string, codicent?: string): Promise<string>

getSchema(tag: string, codicent?: string): Promise<object | null>

Chat and messages:

sendMessage(message: string, parentId?: string, codicent?: string): Promise<Message>
chat(message: string, messageId?: string, codicent?: string): Promise<Message>
getMessages(tags: string[], codicent?: string, length?: number): Promise<Message[]>
getMessagesFast(tags: string[], search?: string, length?: number, publicCodicent?: string, codicent?: string, start?: number): Promise<Message[]>

Files:

uploadFile(filename: string, formData: FormData): Promise<string>
getFileInfo(fileId: string): Promise<FileInfo>
static getImageUrl(fileId: string, width: number): string
static getFileUrl(fileId: string, extension?: string): string

Auth and tokens:

getToken(): string
generateApiToken(expires?: Date, forUserNickname?: string): Promise<string>

useCodicentApp(options)

Core hook that bootstraps app state, authentication, and the CodicentService instance.

const state = useCodicentApp({
  auth0: useAuth0(),       // Required: Auth0 hook result
  toolsConfig?: object,    // Optional: custom AI tool handlers
  authOptions?: object,    // Optional: override auth behaviour
});

Returns CodicentAppState:

{
  service: CodicentService;   // Use for all data/chat operations
  context: StateContext;      // Project nickname, user info
  auth: UseAuthState;
  voice?: RealtimeVoice;      // Voice AI connection (when active)
  audio: AudioRecorderState;
  stateMachine: AppStateMachine;
  state: string;              // Current state machine state
  nickname: string;           // Active project nickname
  error: string;
  isBusy: () => boolean;
  html: string;               // AI-generated HTML output
  setHtml: (html: string) => void;
}

5. Use DataMessagePicker for tagged record lookup

import { DataMessagePicker } from 'codicent-app-sdk';

<DataMessagePicker
  service={state.service}
  tag="customer2"
  placeholder="Search customers"
  primaryKey="Company Name"
  displayKeys={["Company Name", "City"]}
  secondaryKeys={["Customer Number", "City"]}
  searchKeys={["Company Name", "Customer Number", "City"]}
  onSelect={(selection) => {
    console.log('Selected customer', selection.id, selection.data);
  }}
/>

The picker debounces lookups through readDataMessages(...), shows compact autosuggest results, and returns the raw DataMessage plus a normalized selection payload.


useLocalization()

const { t, tAsync, getLanguageInfo } = useLocalization();

t('Kunder')                       // → "Customers" (in English)
await tAsync('Kunder')            // → API-backed translation with fallback
getLanguageInfo()                 // → { code: 'en', name: 'English', ... }

Swedish strings are used as keys. Pass your translation maps via TRANSLATIONS in initCodicentApp().


Components

Page

Full-screen layout wrapper with optional header and footer.

<Page title="Customers" hideFooter={false} audio={state.audio} voice={state.voice}>
  <Content>...</Content>
</Page>

Content

Flex content container — use inside Page.

<Content>
  <ListView data={data} columns={columns} />
</Content>

Chat (page)

Full chat UI with message history, input, typing indicators, file uploads.

<Chat
  state={state}
  title="AI Assistant"
  codicent="my-project"     // Optional: override which project to chat with
  welcomeMessage="Hi!"      // Optional: shown when no messages exist
  hideFooter={false}
/>

ListView

Tabular data view with sorting, filtering, and column actions.

import { ListView } from 'codicent-app-sdk';

<ListView
  data={dataMessages}
  columns={[
    { key: 'name', title: 'Name', filterable: true },
    { key: ['offer_number', 'offerNumber'], title: 'Quote #', filterable: true },
    { key: 'grand_total', title: 'Total', format: formatNumber },
    { key: 'pdf', title: 'PDF', type: 'file' },
  ]}
  onSelect={(item) => navigate(`/chat?id=${item.originalMessageId}`)}
/>

Column definition options:

  • key: string | string[] — JSON field name; array = fallback chain
  • format: (value) => string — display transformer
  • filterable: true — per-column text filter
  • type: "file" — renders download link
  • type: "checkbox" — renders checkbox
  • action — icon button with click handler

AppFrame

Embeds an external URL in an iframe within the page layout.

<AppFrame src="https://example.com/embed" title="External view" showFooter={true} />

Markdown

Renders markdown content including GFM and Mermaid diagrams.

<Markdown content={message.content} />

UploadFile

File upload UI with progress.

<UploadFile service={state.service} codicent="my-project" />

Hooks summary

| Hook | Purpose | |------|---------| | useCodicentApp() | Core app state, service, auth | | useLocalization() | i18n translation | | useChat(service) | Chat message state and send | | useRealtimeVoiceAI(options) | Real-time voice AI connection | | useAuthState(auth0) | Auth lifecycle and token | | useTheme() | App theme/branding | | useToaster() | Toast notification helpers | | useStateWithLocalStorage() | Persistent local state | | useAudioRecorder() | Microphone recording | | useTemplateVariables() | Template string utilities | | useTools() | AI tool handler registration | | useEmbeddings() | Vector embedding operations |


TypeScript types

import type {
  CodicentAppState,
  ButtonConfig,
  ColumnDefinition,
  ListDefinitions,
  DataMessage,
  Message,
} from 'codicent-app-sdk';

ButtonConfig — navigation button with optional RBAC claims:

{
  title: string;
  url: string;          // "#/list?tag=customer2", "voice:...", "mailto:...", etc.
  claim?: string;       // Show only if user has this claim
  notClaim?: string;    // Hide if user has this claim
  subtitle?: string;
  options?: ButtonConfig[];
}

DataMessage — result from readDataMessages():

{
  id: string;
  originalMessageId: string;       // Stable ID across updates — use this for references/tags
  content: string;                 // Raw: "@project #data #tag\n{json}"
  data: Record<string, unknown>;   // Parsed JSON payload
  tags: string[];
  createdAt: string;
}

Alternative: createCodicentApp() factory

For standalone deployments where you do not control the React entry point, createCodicentApp() wraps the full initialization (including Auth0Provider, FluentProvider, HashRouter) and renders to a DOM element:

import { createCodicentApp } from 'codicent-app-sdk';

const app = createCodicentApp({
  name: 'My CRM',
  apiBaseUrl: 'https://codicent.com/',
  auth0: { domain: '...', clientId: '...' },
  buttons: [
    { title: 'Customers', url: './#/list?tag=customer2' },
    { title: 'Chat', url: './#/chat' },
  ],
  listDefinitions: {
    customer2: [
      { key: 'name', title: 'Name', filterable: true },
      { key: 'email', title: 'Email' },
    ],
  },
  chatInstructions: 'You are a helpful CRM assistant.',
  modules: { sales: true, voice: true },
});

app.render('#root');
// app.unmount();
// app.getConfig();

The codicentapp/ reference implementation uses initCodicentApp() + manual React tree setup, which gives more control over routing and layout. createCodicentApp() is appropriate for simpler or standalone deployments.


Local development workflow

Build the SDK

cd codicent-app-sdk
npm install
npm run build        # Output: dist/cjs/, dist/esm/, dist/index.d.ts
npm run dev          # Watch mode

Test in codicentapp (file: reference)

In codicentapp/package.json:

"codicent-app-sdk": "file:../codicent-app-sdk"

Then:

cd codicentapp
npm install
npm run build

Test with npm link

# In SDK directory
npm link

# In your app directory
npm link codicent-app-sdk

To restore npm version:

npm uninstall codicent-app-sdk
npm install codicent-app-sdk

Build output layout

dist/
  cjs/        CommonJS modules
  esm/        ES modules
  index.d.ts  TypeScript definitions

Release

npm version patch   # or minor / major
npm run build
npm publish --access public

Debugging

The SDK emits codicent-log custom events on window:

window.addEventListener('codicent-log', (event: CustomEvent) => {
  console.log(event.detail);  // { level, message, context }
});

Related

  • codicentapp/ — primary consumer; complete reference implementation
  • codicent-api-client/ — framework-agnostic fetch-based API client (shared with web components)
  • codicent-components/ — zero-build Web Components library using the same Codicent API
  • Voice Upgrade Guide — real-time voice AI setup and security

License

MIT © Codicent Inside AB