Want the terminal instead of a frontend? The Quickstart covers the aomi client CLI. This page covers installing and using the chat widget in a Next.js app.
Install and run the Aomi chat widget in a Next.js project with a single CLI command, then use the AomiFrame component API to shape it.
Prerequisites
- Next.js 15 app with the App Router
- Tailwind CSS configured
- shadcn/ui initialized (
npx shadcn init already run, components.json present)
Starting from scratch:
npx create-next-app@latest my-app --typescript --tailwind --app
cd my-app
npx shadcn init
npx shadcn add https://aomi.dev/r/aomi-frame.json
This installs the AomiFrame component, all sub-components, and every dependency in one step.
What gets installed
npm packages:
| Package | Purpose |
|---|
@aomi-labs/react | Headless runtime, hooks, API client |
@assistant-ui/react | Chat primitives |
Component files:
your-project/
├── components/
│ ├── aomi-frame.tsx ← Main shell
│ ├── control-bar/
│ │ ├── index.tsx ← ControlBar component
│ │ ├── model-select.tsx ← Model dropdown
│ │ ├── app-select.tsx ← App/agent dropdown
│ │ ├── api-key-input.tsx ← API key dialog
│ │ ├── connect-button.tsx ← Wallet button
│ │ └── network-select.tsx ← Network dropdown
│ ├── assistant-ui/
│ │ ├── thread.tsx ← Chat thread
│ │ ├── thread-list.tsx ← Thread list
│ │ ├── threadlist-sidebar.tsx ← Sidebar wrapper
│ │ ├── tool-fallback.tsx ← Tool display
│ │ ├── markdown-text.tsx ← Markdown renderer
│ │ ├── tooltip-icon-button.tsx ← Icon buttons
│ │ └── attachment.tsx ← File attachments
│ ├── ui/
│ │ ├── button.tsx ← shadcn primitive
│ │ ├── sidebar.tsx ← shadcn primitive
│ │ ├── popover.tsx ← shadcn primitive
│ │ └── ... ← Other shadcn primitives
│ └── runtime-tx-handler.tsx ← Runtime transaction handler
├── lib/
│ └── utils.ts ← cn() utility
└── package.json ← npm deps added
Registry architecture
Components are pulled from three registries, all resolved automatically by the CLI:
| Source | What | Why |
|---|
| aomi.dev/r | Customized components (AomiFrame, Thread, ThreadList) | Aomi-specific features like wallet integration |
| r.assistant-ui.com | Unchanged upstream components (markdown, tooltips) | Maintained by assistant-ui, receives upstream fixes |
| ui.shadcn.com | Primitives (Button, Sidebar, Dialog) | Standard UI building blocks |
Since components are copied into your project, you own the source code and can edit anything.
Set environment variables
Create .env.local:
NEXT_PUBLIC_BACKEND_URL=https://api.aomi.dev
For wallet support, add:
NEXT_PUBLIC_PARA_API_KEY=your_para_api_key
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_walletconnect_project_id
Add AomiFrame to a page
import { AomiFrame } from "@/components/aomi-frame";
export default function ChatPage() {
return (
<div style={{ height: "100vh" }}>
<AomiFrame
backendUrl={process.env.NEXT_PUBLIC_BACKEND_URL!}
height="100%"
width="100%"
/>
</div>
);
}
Option A: via the ControlBar UI
The widget includes a ControlBar with an API key input. Click the key icon, paste your API key, and select your app from the dropdown. The key is stored in localStorage for subsequent visits.
Option B: programmatically
Set the API key and app in code using the useControl hook:
import { useControl } from "@aomi-labs/react";
import { useEffect } from "react";
function ConfigureOnMount() {
const { setState } = useControl();
useEffect(() => {
setState({
apiKey: "sk-your-api-key",
app: "mycoindex",
});
}, []);
return null;
}
Run your app
Open http://localhost:3000. You should see the full chat interface with a thread sidebar, a message composer, a ControlBar, and streaming AI responses when you send a message.
Namespace configuration
For shorter install commands, add a registry namespace to components.json:
{
"registries": {
"aomi": "https://r.aomi.dev"
}
}
Then install with:
npx shadcn add @aomi/aomi-frame
Updating components
Re-run the install with --overwrite to pull the latest versions:
npx shadcn add https://aomi.dev/r/aomi-frame.json --overwrite
Review changes before committing:
Component API
The rest of this page documents the AomiFrame component surface: props, the compound API for custom layouts, and ControlBar options.
Basic usage
import { AomiFrame } from "@/components/aomi-frame";
export default function ChatPage() {
return (
<div style={{ height: "100vh" }}>
<AomiFrame
backendUrl={process.env.NEXT_PUBLIC_BACKEND_URL!}
height="100%"
width="100%"
/>
</div>
);
}
Compound component API
Customize the layout using individual components:
<AomiFrame.Root height="100%" backendUrl={process.env.NEXT_PUBLIC_BACKEND_URL!}>
<AomiFrame.Header
withControl={true}
controlBarProps={{
hideWallet: true,
hideApiKey: true,
}}
/>
<AomiFrame.Composer />
</AomiFrame.Root>
AomiFrame props
| Prop | Type | Description |
|---|
backendUrl | string | Aomi backend URL |
height | string | Container height (e.g., “100%”, “600px”) |
width | string | Container width (e.g., “100%”, “400px”) |
Control bar
The ControlBar provides built-in controls for:
- ModelSelect: switch AI models at runtime
- AppSelect: switch between Aomi Apps
- ApiKeyInput: enter scoped API keys
- ConnectButton: connect a wallet
- NetworkSelect: select blockchain network
Theming
Customize colors using shadcn CSS variables in your Tailwind configuration.
Next Steps
Last modified on June 4, 2026