The Problem
Developers building AI‑driven chat UIs spend time wiring together low‑level UI primitives, handling theming, and keeping type safety across message schemas. Without a reusable, well‑typed component set, each project re‑implements the same atoms, molecules and layout logic, leading to duplicated code and inconsistent accessibility.
What This Does
@gravity-ui/aikit supplies a React component library organized by Atomic Design. The core UI lives under src/components/ with the hierarchy atoms → molecules → organisms → templates → pages.
- Example entry:
src/components/pages/ChatContainer/ChatContainer.tsxrenders a full chat surface and delegates to hooks (useChatContainer.ts) and shared utilities (src/utils/cn.ts). - The theming system resides in
src/themes/and uses CSS variables, while type definitions are centralized insrc/types/(e.g.,src/types/messages.ts). - Storybook (
.storybook/) and Playwright component tests (playwright/) provide interactive documentation and visual regression coverage.
How It Is Wired
- Runtime start – A consumer imports a top‑level component, e.g.
import {ChatContainer} from '@gravity-ui/aikit'. The compiled entry point issrc/components/pages/ChatContainer/ChatContainer.tsx. - Component composition –
ChatContainerrenders a layout of atoms and molecules, pulling styles viasrc/utils/cn.ts(the most‑connected module, imported by 59 other files). - State & logic –
ChatContainercalls the hooksrc/components/pages/ChatContainer/useChatContainer.ts, which manages message lists, active chat selection, and callbacks passed from the parent. - Message typing – All message shapes flow through
src/types/messages.ts, imported by both UI components and the hook, ensuring a single source of truth forTChatMessage. - Theming – UI components read CSS variables defined in
src/themes/via thecnutility; no runtime theme‑switching code lives elsewhere, keeping the visual layer isolated. - Export surface –
src/components/atoms/index.ts,src/components/molecules/index.ts, etc., re‑export their sub‑modules, giving consumers a flat import path while the internal graph remains acyclic (0 circular dependencies).
The import graph shows no cycles and a clear hub (src/utils/cn) whose stability is critical because any change propagates to 59 dependents. Deeply nested components (e.g., src/components/molecules/BaseMessage/index.tsx) have up to nine indentation levels, indicating high cognitive load.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/aikit
cd aikit
# Install dependencies
npm ci
# Run the library's test suite
npm test
# Launch Storybook for interactive exploration
npm run storybook # script defined in package.json
No additional configuration files are required; the library reads no environment variables at runtime. For component‑level testing, Playwright can be invoked:
npx playwright test
(see playwright/README.md).
Real‑World Use
A SaaS product that embeds a multi‑chat UI can import the library and plug its own backend:
import {ChatContainer} from '@gravity-ui/aikit';
import type {ChatType, TChatMessage} from '@gravity-ui/aikit';
function App() {
const [messages, setMessages] = useState<TChatMessage[]>([]);
const [chats, setChats] = useState<ChatType[]>([]);
const [active, setActive] = useState<ChatType | null>(null);
return (
<ChatContainer
chats={chats}
activeChat={active}
messages={messages}
onSendMessage={msg => api.send(msg)}
onSelectChat={setActive}
onCreateChat={() => api.create()}
onDeleteChat={chat => api.delete(chat.id)}
/>
);
}
The component handles UI rendering, theming, and accessibility out of the box; the application only needs to supply data and callbacks.
Code Health & Issues
Critical – Secrets in .github/workflows/pr-preview-deploy.yml (GRAVITY_UI_BOT_GITHUB_TOKEN, etc.). Move secret‑using steps to a workflow_run job or restrict to approved reviewers. High – GitHub Action versions are pinned to tags (@v1). Replace each with a full 40‑character commit SHA. Medium – No least‑privilege permissions declared for GITHUB_TOKEN in CI workflow. Add explicit read/write scopes. Medium – Dependabot not configured; add .github/dependabot.yml. Medium – No dependency‑vulnerability scan in CI; integrate dependency-review-action or osv-scanner. Medium – Large binary (docs/assets/aikit_cover.png, 5 MB) in repo; migrate to Git LFS or external storage. Medium – Checkout step retains token; set persist-credentials: false and pass token only where needed. Low – CI jobs lack timeout-minutes; define reasonable limits to avoid runaway runs.
Additional findings from static analysis:
- Hub module
src/utils/cn.ts(59 dependents) should stay minimal. - Deep nesting (max depth 9) in several components; refactor with early returns or extract sub‑logic.
- Repeated 6‑line story blocks across many
__stories__files; consolidate into shared helpers. - Oversized story file
ChatContainer.stories.tsx(1 072 lines); split by responsibility. - High branching density in
ChatContainer.tsxand its hook; consider strategy tables.
The Bottom Line
aikit delivers a well‑typed, themable React UI kit for AI chat interfaces, with solid test coverage and Storybook documentation. The codebase is healthy overall but contains a few high‑impact maintenance hotspots (the cn utility and deeply nested components) and several CI/security hygiene gaps that should be addressed before production deployment. It is suited for teams needing a reusable chat UI foundation and are comfortable managing the identified CI improvements.