Korin UI

Korin UI is a collection of AI‑first UI components built on top of shadcn/ui and Tailwind CSS. It ships a remote shadcn registry, so you can pull components directly into your app via the shadcn CLI. Components cover a full chat experience: providers, page chat, floating chat button, input with attachments, rich message bubbles, reasoning, file selector, upload flow, and more.

Quick Start

Add everything at once:

bash
npx shadcn@latest add https://ui.korinai.com/all.json

Add just one component by replacing all.json with a specific file:

bash
# Single component examples
npx shadcn@latest add https://ui.korinai.com/page-chat.json
npx shadcn@latest add https://ui.korinai.com/chat-input.json
npx shadcn@latest add https://ui.korinai.com/floating-chat.json

Where files go:

  • Components will be placed under @/components/korin-ui/*.
  • Dependencies on shadcn primitives will use your local @/components/ui/* setup.

Prerequisites:

  • Next.js 14+ (App Router) or React 18+
  • Tailwind CSS and shadcn/ui configured
  • Icons: lucide-react

If you use chat‑related components, add:

bash
pnpm add ai lucide-react @korinai/libs
# or: npm i ai lucide-react @korinai/libs

Reference

Showcase and registry

Browse the Korin UI component showcase and the remote shadcn registry entries at:

Explore live previews and copy the shadcn add commands directly from the site.

Provider setup

Most higher‑level components rely on app‑wide providers for configuration, authentication, and agent context. Wrap your app with KorinProvider.

tsx
// app/providers.tsx (Next.js) or your root layout
"use client";

import { KorinProvider } from "@/components/korin-ui/korin-provider";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <KorinProvider
      config={{
        baseUrl: "https://your.cdn.or.assets.base/url", // used for logos/images
        chatApi: "/api/chat", // your chat endpoint compatible with Vercel AI SDK
      }}
      // Option A: static token (for testing)
      // authToken="<JWT or API token>"

      // Option B: async token resolver (recommended)
      getAuthToken={async () => {
        // fetch or compute an access token for your chat API
        return "<JWT or API token>";
      }}
      language="en"
      // translations={customTranslations}
    >
      {children}
    </KorinProvider>
  );
}

Use in root layout

tsx
// app/layout.tsx
import { Providers } from "./providers";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

Examples

PageChat — Embed chat on your page

PageChat renders a complete chat surface with header, history, message list, input, file attachments, and agent selection.

tsx
"use client";
import { PageChat } from "@/components/korin-ui/page-chat";

export default function ChatPage() {
  return (
    <div className="container mx-auto p-4">
      <PageChat
        title="Chat with KorinAI"
        // optional UI tuning
        ui={{ showStop: true, showAttach: true, showActions: true }}
        // optional branding
        branding={{
          logoLightUrl: "/logo/KorinAILogo-Black.svg",
          logoDarkUrl: "/logo/KorinAILogo-White.svg",
          headerLogoSize: { width: 28, height: 28 },
        }}
      />
    </div>
  );
}

FloatingChat — Floating chat button + overlay chat window

FloatingChat — Floating chat button + overlay chat window — places a floating button at the bottom‑right and opens a chat window overlay.

tsx
"use client";
import { FloatingChat } from "@/components/korin-ui/floating-chat";

export default function FloatingExample() {
  return (
    <>
      {/* Your page content... */}
      <FloatingChat
        title="Chat with KorinAI"
        chatProps={{
          ui: { showStop: true, showAttach: true },
          branding: {
            logoLightUrl: "/logo/KorinAILogo-Black.svg",
            logoDarkUrl: "/logo/KorinAILogo-White.svg",
          },
        }}
      />
    </>
  );
}

ChatInput — Compose your own chat UI

ChatInput — Compose your own chat UI — if you want to build a custom chat surface. It manages textarea sizing, file attachments, agent selection, and submit/stop buttons.

tsx
"use client";
import { useState } from "react";
import { ChatInput } from "@/components/korin-ui/chat-input";

export default function CustomInput() {
  const [status, setStatus] = useState<"submitted" | "streaming" | "ready" | "error">("ready");
  const [error, setError] = useState<string | null>(null);

  async function handleSubmit(text: string) {
    try {
      setStatus("submitted");
      // Call your chat API here, stream response, etc.
      await new Promise((r) => setTimeout(r, 800));
      setStatus("ready");
    } catch (e: any) {
      setError(e?.message || "Failed to send message");
      setStatus("error");
    }
  }

  return (
    <div className="max-w-2xl mx-auto p-4">
      <ChatInput
        isLoading={status === "submitted"}
        status={status}
        error={error}
        showTemplate={false}
        handleSubmit={handleSubmit}
        onStop={() => setStatus("ready")} 
      />
    </div>
  );
}

ChatBubble (render messages)

ChatBubble renders rich message parts (text, reasoning, tools, attachments). You can wire it with your own message objects or reuse what PageChat composes for you.

tsx
import { ChatBubble } from "@/components/korin-ui/chat-bubble";

// ... inside a component
<ChatBubble
  message={{ id: "1", role: "assistant", parts: [{ type: "text", text: "Hello!" }] }}
  isStreaming={false}
/>

Component inventory

All components available under packages/korin-ui/src/. Use the command to install a single component via shadcn CLI.

ComponentCommandDescription
AvatarKorinnpx shadcn@latest add https://ui.korinai.com/avatar-korin.jsonAvatar component with Korin-specific fallback and styling.
ChatBubblenpx shadcn@latest add https://ui.korinai.com/chat-bubble.jsonRenders message parts (text, reasoning, tools, file attachments) with confirmations and status pills.
ChatInputnpx shadcn@latest add https://ui.korinai.com/chat-input.jsonMultiline input with auto-resize, file attach, agent selector, send/stop controls.
ChatLimitednpx shadcn@latest add https://ui.korinai.com/chat-limited.jsonCredit limit warning/notice component.
CodeBlock / CodeBlockCopyButtonnpx shadcn@latest add https://ui.korinai.com/code-block-with-copy.jsonPretty code block with copy-to-clipboard action.
CodeBlock (base)npx shadcn@latest add https://ui.korinai.com/code-block.jsonBase code block renderer used by Response and others.
FilePreviewDialognpx shadcn@latest add https://ui.korinai.com/file-preview-dialog.jsonDialog/overlay for previewing images, video, audio, and documents; supports select mode.
FileSelectornpx shadcn@latest add https://ui.korinai.com/file-selector.jsonGallery selector with tabs (images, videos, audio, documents) + search + upload integration.
FloatingChatnpx shadcn@latest add https://ui.korinai.com/floating-chat.jsonFloating button + overlay chat window (wraps PageChat).
KorinProvidernpx shadcn@latest add https://ui.korinai.com/korin-provider.jsonApp-level provider that wires KorinAIProvider and AgentProvider.
SimpleMemoizedMarkdownnpx shadcn@latest add https://ui.korinai.com/memoized-markdown.jsonMemoized markdown rendering for simple content.
PageChatnpx shadcn@latest add https://ui.korinai.com/page-chat.jsonFull chat surface with header, history list, message list, and input area.
Reasoning (and friends)npx shadcn@latest add https://ui.korinai.com/reasoning.jsonCollapsible “reasoning” disclosure UI.
Responsenpx shadcn@latest add https://ui.korinai.com/response.jsonHardened Markdown renderer with KaTeX, GFM, streaming-friendly parsing.
ScrollAreaExtendednpx shadcn@latest add https://ui.korinai.com/scroll-area-extended.jsonConvenience wrapper around shadcn ScrollArea with tweaks.
ToolResultsnpx shadcn@latest add https://ui.korinai.com/tool-results.jsonRenderers for tool outputs (web search, knowledge, image generation).
TypingLoadernpx shadcn@latest add https://ui.korinai.com/typing-loader.jsonTyping/streaming loader indicator.
UploadButtonnpx shadcn@latest add https://ui.korinai.com/upload-button.jsonDrawer-based upload flow with preview and progress.
UserConfirmationnpx shadcn@latest add https://ui.korinai.com/user-confirmation.jsonGeneric confirmation UI for tool actions (e.g., git commit/push).

Notes:

  • Replace all.json with <component-name>.json to install only that component.
  • Output paths are set to @/components/korin-ui/* for tidy imports like @/components/korin-ui/page-chat.

Minimal chatApi endpoint (Next.js + Vercel AI SDK)

A minimal streaming chat endpoint compatible with PageChat and the Vercel AI SDK.

Install dependencies:

bash
pnpm add ai @ai-sdk/openai
# or: npm i ai @ai-sdk/openai

Create app/api/chat/route.ts:

ts
import { NextRequest } from "next/server";
import { openai } from "@ai-sdk/openai";
import { streamText } from "ai";

export const runtime = "edge"; // recommended for streaming

export async function POST(req: NextRequest) {
  // Optional: read auth header
  const authHeader = req.headers.get("authorization");
  // Validate if needed

  const { messages } = await req.json();

  const result = await streamText({
    model: openai("gpt-4o-mini"),
    messages,
  });

  return result.toAIStreamResponse();
}

Environment variable:

bash
OPENAI_API_KEY=sk-...

Then set config.chatApi in KorinProvider to /api/chat. The DefaultChatTransport used by PageChat will POST messages and render the streamed response.

Recipes

Branding

Most chat surfaces accept a branding prop to override logos and sizes:

tsx
branding={{
  logoLightUrl: "/logo/KorinAILogo-Black.svg",
  logoDarkUrl: "/logo/KorinAILogo-White.svg",
  logoSize: { width: 50, height: 50 },
  headerLogoSize: { width: 28, height: 28 },
  showHeaderLogo: true,
}}

Requests and auth

KorinProvider passes authToken (string) or getAuthToken (async) to chat transports. Implement either method and validate the Authorization header in your backend.

File uploads and gallery

ChatInput, FileSelector, and UploadButton integrate with hooks from @korinai/libs (e.g., useGallery, useGalleryUpload, useUser). Ensure your project provides compatible endpoints and auth.

Troubleshooting

  • Missing or invalid token: Pass authToken or implement getAuthToken. A 401 usually means token is absent/expired.
  • Wrong baseUrl or chatApi: Double‑check config values; hit the URL directly to verify.
  • CORS errors: Allow your app’s origin in the backend; in dev, use permissive CORS or a proxy.
  • SWR not updating: Call mutate() after actions like uploads to revalidate data.
  • Type errors: Ensure compatible TypeScript and @types/react for React 18.