DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
Dependency-free web components for building chat interfaces — engagement, low cognitive load, modern web experiences, and user agency over their own conversation data.
Developer toolsJavaScriptGitHub @Mach-Five-GroupOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Dependency-free web components for prototyping complex chat interactions — engagement, low cognitive load, and user agency over their own data.
Loading the full README.
Read the full README ↗Chat is now the default interface for anything an AI touches, and most of it is assembled from scratch each time — the same bubble list, the same Enter-to-send textarea, the same autoscroll bug where the transcript yanks you to the bottom while you are reading something further up.
Machvive Chat Syncopation is that layer, built once: a collection of standards-based custom elements you compose into the surface your product actually needs. Four commitments shape every one of them.
User engagement. An empty prompt box is the highest-friction moment in any chat interface — the user has to invent both the task and the phrasing. The nudge component offers concrete openings, and fills the composer rather than sending, so the user stays the author.
Prompt cognitive load. A conversation is a reading surface. Turns stream into one node instead of re-rendering the list, autoscroll follows the bottom only when the reader is already there, and the send button becomes Stop rather than going disabled — you are never watching output you cannot interrupt.
Modern web experiences. Shadow DOM, custom properties that inherit through the
shadow boundary, prefers-color-scheme, prefers-reduced-motion, the Speech APIs
where they exist and an honest explanation where they do not. No framework, no build
step, no runtime dependencies — just custom elements that work anywhere
customElements does.
User data domain agency. The conversation lives in the user's own browser. Persistence is off until a page turns it on, and the history component gives the person whose words these are the three operations that make that meaningful: see what is stored, export it as JSON they keep, and delete it for real.
We are deliberately challenging where a chat surface is possible. Nothing in this
package calls a model: the daemon exposes transports as a uniform interface, and the
one that matters is local — a model running inside the user agent, via WebLLM or
similar.
A model in the browser has no per-token cost. That changes the arithmetic entirely for the cases usually ruled out as uneconomic: a long-tail support surface, a kiosk, a classroom, an internal tool nobody will fund an API bill for, a field application that has to work with no connection at all. Offline-first becomes a configuration rather than a rewrite, because no component knows where its text came from.
| Component | Tag | What it does |
|---|---|---|
| Services | <machvive-chat-syncopation-services> | Headless. The bus, conversation, daemon, cache and config every surface shares |
| Container | <machvive-chat-syncopation> | Layout, and nothing else. Everything inside it is slotted |
| Canvas | <machvive-chat-syncopation-canvas> | The transcript — append-only, streaming, reader-respecting autoscroll |
| Prompt | <machvive-chat-syncopation-prompt> | The composer. Enter sends, Shift+Enter newlines, Stop interrupts |
| Nudge | <machvive-chat-syncopation-nudge> | Suggested openings and a once-only idle prompt |
| CLI | <machvive-chat-syncopation-cli> | Keyboard-first surface with extensible slash commands |
| Voice | <machvive-chat-syncopation-voice> | Push-to-talk dictation and read-aloud, capability-gated |
| Inspector | <machvive-chat-syncopation-inspector> | Live bus traffic, for whoever is building the surface |
| History | <machvive-chat-syncopation-history> | Stored conversations, with export and real deletion |
📖 Read the full guide on the Wiki — how the components compose, how to write a transport, and the constraints worth knowing before you adopt.
🎮 Try the live playground — every component, every theme, running in the browser.
🤖 machvive-webmcp-ai — the sibling package. Chat Syncopation is the interface a person talks through; WebMCP is how an agent reaches your product without one. They compose well and neither depends on the other.
📝 MachFiveTech article — coming soon.
npm i @machfivetechchicago/machvive-chat-syncopation-ai
// Everything, registered on import.
import '@machfivetechchicago/machvive-chat-syncopation-ai';
// Or cherry-pick.
import '@machfivetechchicago/machvive-chat-syncopation-ai/canvas';
import '@machfivetechchicago/machvive-chat-syncopation-ai/prompt';
// The icon set, as plain CSS strings — no DOM needed, so it loads anywhere.
import { ICON_ROOT_CSS, ICON_CSS, ICON_NAMES } from '@machfivetechchicago/machvive-chat-syncopation-ai/icons';
One tag. It creates its own services and runs the echo transport, which is enough
to build and style a surface before any model exists.
<machvive-chat-syncopation>
<machvive-chat-syncopation-nudge
suggestions="Where's my order?|I'd like to return something|Talk to a human">
</machvive-chat-syncopation-nudge>
<machvive-chat-syncopation-canvas></machvive-chat-syncopation-canvas>
<machvive-chat-syncopation-prompt slot="footer"></machvive-chat-syncopation-prompt>
</machvive-chat-syncopation>
Wrap the surface when the page needs the bus, wants persistence, or runs two independent conversations that must not share state.
<machvive-chat-syncopation-services id="chat" transport="local" model="Llama-3.2-1B" persist>
<machvive-chat-syncopation>
<machvive-chat-syncopation-canvas></machvive-chat-syncopation-canvas>
<machvive-chat-syncopation-prompt slot="footer"></machvive-chat-syncopation-prompt>
</machvive-chat-syncopation>
<machvive-chat-syncopation-history></machvive-chat-syncopation-history>
</machvive-chat-syncopation-services>
This is the beginning of the README. Read the rest at the original. Read the full README ↗