What Zhin.js Is
In one line: Zhin.js is a multi-channel TypeScript IM bot and AI assistant runtime — millisecond leak-free hot reload on file save, write-once JSX that auto-degrades across 20+ chat platforms, a <10MB IM core, and an optional governed multi-model AI Agent.
To start building right away, jump to Getting Started or Directory Conventions. This page explains why developers choose Zhin.js and what happens to a message inside the runtime.
Four reasons developers choose Zhin.js
1. Convention-Driven Capabilities & Leak-Free Hot Reload
Drop files into commands/, components/, middlewares/, tools/, or schedules/ and Zhin discovers them automatically — no central routing boilerplate required.
Every time you save a file or edit configuration, Zhin builds a complete new Generation in the background:
- If new code throws a syntax error or fails to connect, the candidate generation is discarded and the previous version keeps serving without interruption;
- In-flight messages finish on the generation snapshot they started with, while new messages use the new generation;
- Timers, listeners, and connections registered on
context.lifecycleare disposed automatically when an old generation retires — eliminating duplicate timers and memory leaks across hot reloads.
See Plugin Model and Generation and Lifecycle.
2. Write JSX Once, Auto-Degrade Across 20+ IM Platforms
Chat platforms differ wildly in rich-media support (Discord and Telegram have native buttons, plain group chats only support text, and some platforms work best with rendered images). In Zhin, commands and components simply return JSX:
return (
<card title="Deploy Confirmation">
<text>Ready to release v1.2.0 to production</text>
<button onClick={async (msg) => '✅ Deployment started'}>Deploy Now</button>
</card>
);- Native interactions with automatic fallback: Platforms with native interactive buttons render real buttons; plain-text group chats automatically fall back to a numbered text menu (replying with the number triggers the exact same
onClickhandler, scoped safely to that conversation and generation). - HTML to crisp images: Visual components inside
<html>...</html>(@zhin.js/components) are rendered into images on the fly via@zhin.js/html-renderer.
3. Unified Inbound/Outbound Pipeline & Multi-Endpoint Routing
Whether you connect to QQ (ICQQ / NapCat / OneBot 11·12 / Official Bot), Discord, Telegram, Feishu, DingTalk, Slack, KOOK, WeCom, or the built-in local /sandbox:
- One message and conversation contract: Plugins always work with the same
Message,Segment, and structuredConversationRef. - Single auditable outbound pipeline: Every reply (
message.$replyor command return value) flows throughrender → outbound middleware → platform endpoint, so logging, moderation, and rate-limiting apply everywhere. - 1:N multi-account expansion: Configure multiple entries under
endpoints: [{ id: ... }]inzhin.config.ymlto run several bot accounts side by side on a single adapter instance.
See Message Flow and Config as Data.
4. Lightweight IM Core (<10MB) + Governed AI Agent on Demand
By default, Zhin installs only the IM core (under 10MB in production node_modules) with zero LLM SDK dependencies. When you want AI capabilities, run npx zhin setup --ai to add @zhin.js/agent:
- Multi-model routing (
ai.plan.yml): Routechat,compaction,ambientgroup listening, and mediaperceptionto different model profiles (OpenAI, DeepSeek, Qwen/DashScope, SiliconFlow, Volcengine, Anthropic, or local Ollama). - Progressive tool & skill disclosure: Tools and
SKILL.mdinstructions are tiered by scene and loaded on demand, keeping the system prompt prefix byte-stable to maximize LLM prompt cache hits. - Trust tiers & dangerous-action hard gates: Group members, trusted users, and bot owners get strictly separated tool permissions. High-risk actions (kicking, muting, group announcements, self-change) require fresh human approval via Console cards or owner
/approvecommands.
See AI Capabilities Overview and Agent Deep Dive.
How the runtime is divided
┌──────────────────── Platforms (QQ / OneBot / Discord / Feishu / …) ───────────┐
│ │
Adapter ── declares a capability profile (supported segments, actions, interactions) │
── implements ports ── maps raw platform events to canonical events │
▼ │
Zhin runtime ─ contracts: Generation transactions · JSX/component rendering · capability │
negotiation · audit trail · dangerous-action hard gate │
▼ │
Plugins / Agent ─ focus on features: commands, JSX components, middleware, tools & skills ┘The rule: Zhin provides the contract; adapters declare what each platform can do; plugins and the Agent act on the combined capabilities for the current turn without hard-coding if (platform === '...') branches.
What happens to one message
- Ingress & normalization: The adapter converts a raw platform event into a canonical
Messagewith sender roles and scene metadata. - Capability negotiation: The adapter's capability profile is narrowed by the conversation kind (group / private / channel) and current bot state (admin role, mute status).
- Middleware & command dispatch: Inbound middleware runs first; if a command prefix matches, the command executes. Otherwise
ai.triggerdecides whether the AI Agent should handle the message. - AI reasoning & tools (when AI is enabled): The system prompt is assembled with a cache-friendly stable prefix and token-budgeted history; the model calls permitted tools, and dangerous actions pause for hard-gate approval.
- Outbound rendering & delivery: JSX, components, or structured AI replies are normalized into canonical segments, adapted or auto-degraded for the target platform, passed through outbound middleware, and delivered.
Where to read next
- Build your first plugin: Getting Started → Directory Conventions → Plugin Model
- Connect an LLM and write tools: AI Capabilities Overview → Agent Tools and Skills
- Understand hot reload & config transactions: Config as Data → Generation and Lifecycle
- Write a platform adapter: Adapters
Architecture Decision Records (ADR Index)
The following internal Architecture Decision Records (ADRs, written in Chinese) document the design behind Zhin's group behavior, controlled operations, token budgets, and adapter capability profiles:
| ADR | Topic | Key mechanism |
|---|---|---|
| 0034 | Activity feedback service | Typing indicators, emoji reactions, and progress messages in chat |
| 0035 | Comment-reply adapter contract | Canonical inbound/outbound contract for comment-based platforms |
| 0036 | Controlled landing phase 0: audit, control plane, hard gate | Per-turn decision audit, emergency stop / mute control plane, fresh human approval |
| 0037 | Phase 1: group operations | Welcome flows, approved announcements, quiet-field cooling, moderation cooldowns |
| 0038 | Continuous input merge (busy groups, danmaku) | Merging simultaneous mentions into one reply and live danmaku windows |
| 0039 | Dynamic group-ops rules | Owner-approved violation ladders with automatic mutes and per-call kick approval |
| 0040 | Controlled self-change | Agent draft → sandbox trial → human approval → apply with automatic rollback |
| 0041 | Prompt segments and message headers | Byte-stable five-segment system prompt prefix and compact speaker headers |
| 0042 | First-turn token budget | Cache breakpoints, scene-tiered tools with call-to-load, SOUL.md scope tags |
| 0043 | Conversation-only history, token-budget window, quotes | Token-budgeted sliding window, trimmed old tool results, inline quote excerpts |
| 0044 | Adapter capability profile | Seven capability groups, dynamic narrowing, shared OneBot event mapping |
| 0045 | Current-message runtime context after the body | Placing per-turn runtime context after the message body to preserve prompt cache |
| 0046 | Personal Sessions, model catalog and scope policy | Per-user session isolation, model Profile routing, and scoped overrides |