Legacy Concept Migration Guide
After zhin.js 4.x completed the Plugin Runtime consolidation, the following legacy concepts are no longer used in public-facing documentation. This page explains each old concept -- "what it was then and where it went" -- for reference when maintaining old plugins, reading legacy code, or consulting old docs. For the API-level deprecation list, see Public API Surface.
usePlugin() Plugin System -> Convention-based plugin.ts + definePlugin
- Old approach:
usePlugin()from@zhin.js/core-- a React Hooks-like design that uses AsyncLocalStorage to locate the calling file and automatically build the plugin tree. The constraint is that it must be called at module top level (gate:pnpm check:use-plugin-top-level). This function still exists inpackages/im/core/src/plugin.tsfor backward compatibility with the legacy app layer (packages/im/zhin). - New approach: A convention-based
plugin.tsat the plugin package root that default-exportsdefinePlugin(...)(@zhin.js/plugin-runtime). Commands, middleware, adapters, etc. go in convention directories (commands/,middlewares/,adapters/...) for auto-discovery. See definePlugin and Convention Directories.
ts
// Old: const plugin = usePlugin(); plugin.command('ping', ...);
// New (plugin.ts):
export default definePlugin({
name: 'my-plugin',
setup(context) { /* context.resources / context.lifecycle assembly */ },
});"Host Plugin" Narrative -> basic/cli Assembly + Host Tokens
- Old approach:
@zhin.js/hostseries router / api plugin packages that installed HTTP routing and Console API as "plugins" (these packages have been deleted). - New approach: The Host is a composition root --
basic/cli'szhin runtime startassembles IM / Agent / Console Host uniformly. Plugins do not install Hosts; instead they consume Host capabilities through Host tokens insetup(@zhin.js/plugin-runtimeexports six tokens likedatabaseHostToken,@zhin.js/host-httpexportshttpHostToken). When a token is not assembled, usehas()to check and degrade gracefully.
ts
// Old: Install host plugin to get HTTP capability
// New (inside plugin.ts setup):
if (context.resources.has(httpHostToken)) {
context.resources.use(httpHostToken).route('GET', '/hello', handler);
}Old Manifest / plugin.yml -> package.json zhin Field
- Old approach: A
plugin.ymlmanifest at the plugin root (PluginManifest, marked deprecated; legacyPluginandzhin buildstill recognize it, seebasic/cli/src/libs/plugin-package-build.ts). - New approach: The
zhinfield inpackage.json, parsed and strictly validated by@zhin.js/runtime(packages/im/runtime/src/manifest.ts). For field-by-field documentation, see definePlugin - package.json zhin field.
jsonc
// Old: plugin.yml describes plugin entry and metadata
// New (package.json):
{ "zhin": { "protocol": 1, "type": "plugin", "entry": "./plugin.ts" } }extends Adapter Class Adapter -> defineAdapter
- Old approach: Extending the
Adapterbase class from@zhin.js/coreto implement platform adapters (the class still exists inpackages/im/core/src/adapter.tsfor the legacy app layer). - New approach: Default-export
defineAdapter({ capabilities, create })(@zhin.js/adapter) from a file in the conventionadapters/directory, declaring IO capabilities viacapabilities(inbound/outbound). Endpoint instance configuration comes from the app configplugins.<instanceKey>, with the structure described by the plugin package'sschema.json.
ts
// Old: class MyAdapter extends Adapter { /* ... */ }
// New (adapters/my.ts):
export default defineAdapter<MyConfig>({
capabilities: ['inbound', 'outbound'],
create(context) { /* return EndpointInstance */ },
});Old Console loginAssist -> Removed (QR code login via CLI / logs / wizard)
- Old approach: The loginAssist page/route provided by the Console plugin -- adapters posted pending tasks like QR code scans and slider verifications, and users consumed/confirmed them in the Web Console. Console-side code has been entirely removed (zero residue in
packages/console). - Current status: QR code login is handled out-of-band via CLI and log guidance -- e.g. ICQQ uses
icqq login <uin>to start a daemon process for QR code scanning, then restart zhin to take effect. New project platform configuration goes through thezhin setupconfig wizard. The IM kernel still retains theLoginAssistproducer-consumer service (@zhin.js/corebuilt-in,packages/im/core/src/built/login-assist.ts), but only the legacy app layer (packages/im/zhin's Node startup) registers a stdin consumer. The Plugin Runtime (basic/cli) path does not assemble it.
text
Old: Open the Web Console login assist page to confirm QR code scan
New: icqq login <uin> to complete QR scan -> restart zhin (or follow terminal log instructions)Related Reading
- Plugin Model: Conceptual overview of the Plugin Runtime
- definePlugin: New plugin declaration and
package.jsonzhinfield - Repo Structure: Layered architecture and dependency direction