@aparte/core

AI chat and agent UI components as Web Components, with the agent loop inside — zero third-party dependencies
12,040
Install
npm install @aparte/core
Latest Version:0.19.3
License:MIT
Last Updated:Oct 21, 2026
Links: GitHub  ·  npm
Maintainer: paulrichez

@aparte/core

Published on webcomponents.org

AI chat and agent UI components as vanilla Web Components, with the agent loop inside — zero third-party dependencies, ESM-only, usable in any framework or none.

The conversation, messages, reasoning, tool calls a human approves, the questions an agent asks, the composer, the layout around the chat (app shell, sidebar, conversation list) and a UI kit for the rest of the app — each one shown live with its variants, and assembled into templates you can copy.

Beta. On npm, released in lockstep with every other @aparte/* package — the version number is a plain 0.x, and the declared surface is frozen as of 0.17.0: it leaves only through a notice release. Part of the aparté monorepo; what changed when is at apartejs.dev/changelog.

Install

npm install @aparte/core

Quick start

import '@aparte/core';               // registers the <aparte-*> custom elements
import '@aparte/core/styles.css';    // theme variables + component styles
import { aparteGlobalConfig, AparteClient } from '@aparte/core';

// Drop the shell in your HTML:  <aparte-chat placeholder="Ask anything…"></aparte-chat>

// Give it a provider + transport (see the docs), then construct the client and call
// .start() — it echoes your user message, streams the reply into the conversation,
// and listens for retry/edit. (Without .start(), nothing listens and nothing streams;
// a host that appends its own user bubble passes `echoUserMessage: false`.)
new AparteClient().start();

// The retry / edit buttons only do something with a host like the client above, so
// core ships them off. One line turns them on:
aparteGlobalConfig.setBubbleActions({ retry: true, edit: true });

No key yet? npm i @aparte/provider-scenario and register createScenarioProvider({ scenarios: showcase }) as the provider above: a real streaming reply — markdown, reasoning, a tool round-trip — with no backend and no network. It is what this repository's own examples run on, and the docs' live frames that answer. Scenario provider.

The built-in segment renderers install themselves the first time a segment needs one, so there is nothing to call for text, code or thinking blocks to appear. Calling registerDefaultRenderers() yourself still works and makes the moment explicit.

Node / SSR

@aparte/core imports cleanly on the server. A node export condition resolves to a DOM-free entry, so import '@aparte/core' works in Node, an Electron main process, or an SSR pass (Next / Nuxt / SvelteKit / Angular Universal) without a DOM shim:

// Node — same specifier, DOM-free entry
const { AparteClient, createAparteChatHandler, contentToText } = await import('@aparte/core');

You keep the client, the chat host, transports + createAparteChatHandler, the conversation/message runtime, config, parsers and every type. You lose the custom elements themselves — they extend HTMLElement, so they're browser-only, and registerAllComponents() is a safe no-op there.

Reading src/index.ts is misleading on this point: that's the browser entry (it defines the custom elements), and the workspace resolves it first by design. The contract is enforced by pnpm check:node-import, which imports the built packages in real Node on every CI run.

What's in it

  • <aparte-chat> — a drop-in shell (viewport + composer), or compose the primitives yourself (<aparte-chat-viewport>, <aparte-composer>, <aparte-chat-bubble>, …).
  • AparteClient — an optional driver that turns composer events into a streamed reply, and the host that makes the retry / edit buttons real: retry forks the conversation into a branch (with a built-in ‹ 1/2 › picker), edit rewrites the message in place. Both buttons are off by default — without a host they would answer to nobody — so switch them on next to the client: aparteGlobalConfig.setBubbleActions({ retry: true, edit: true }).
  • Transports — AparteDirectTransport (browser → provider, BYOK / local model) or AparteBackendTransport (browser → your endpoint, API key stays server-side).
  • Theming — restyle everything through --aparte-* CSS variables (Light DOM, no forking).
  • Customization — icons, render hooks, and a zoned action registry via aparteGlobalConfig.

Zero third-party dependencies (the agent loop, @aparte/engine, is the one first-party dependency): Markdown, syntax highlighting, etc. are opt-in providers you inject. ESM-only (CJS consumers use await import()).

Docs

Full guides and a generated API reference are at apartejs.dev — Getting started, Theming, Customization, Attachments, Conversations & branching, Tools, Backend transport, Bring your own loop, The agent engine, and Troubleshooting. Source under apps/docs.

The two most-asked-for pages, directly:

  • Customization — every render hook, the action registry, the composer toolbar.
  • CSS variables — the full token catalogue, GENERATED from the stylesheet, so it cannot drift from it.

(This package used to carry CUSTOMIZATION.md and THEMING.md alongside these. They were never published — files is dist, README.md, LICENSE — nothing linked to them, and both had drifted: one taught a registerBubbleAction that does not exist, the other listed six --aparte-bubble-* variables that the stylesheet never defined. A wrong orphan a coding agent finds by grepping the repo is worse than no orphan, so they are gone rather than fixed twice.)

License

MIT

Related Packages

@useago/sdk

Create In-APP AI agents that answers question and performs actions. Works with R...

10,336 5
artifactuse

The Artifact SDK for AI Agents - Turn AI outputs into interactive experiences

7,162 2
deep-chat

Customizable chat component for AI APIs

953,081 3,737
deep-chat-dev

Customizable chat component for AI APIs

26,827 3,738
@perusall/deep-chat

Customizable chat component for AI APIs

8,086 3,738

Version History

Version Released License
0.19.3 MIT
0.19.2 MIT
0.19.1 MIT
0.19.0 MIT
0.18.0 MIT
Pre-releases (4)
Version Released License
0.5.0-alpha.0 MIT
0.4.0-alpha.0 MIT
0.3.0-alpha.0 MIT
0.2.0-alpha.0 MIT