QuikChat is vanilla JavaScript — it works with any framework because it's just DOM manipulation.
The pattern is always the same: create a container element, call new quikchat(el) on mount, and optionally clean up on unmount.
No framework-specific packages needed.
new quikchat(el, onSend, options) in mount lifecycle →
3. Store the instance for API calls →
4. Clean up on unmount (optional)
Use a useRef for the container and useEffect to initialize on mount.
import { useRef, useEffect } from "react";
import quikchat from "quikchat";
import "quikchat/dist/quikchat.css";
function Chat() {
const el = useRef(null);
const chat = useRef(null);
useEffect(() => {
if (el.current && !chat.current) {
chat.current = new quikchat(el.current,
(c, msg) => {
c.messageAddNew(msg, "you", "right", "user");
// call your API, stream the response...
},
{ theme: "quikchat-theme-light",
titleArea: { title: "React Chat", show: true } }
);
}
}, []);
return <div ref={el} style={{ height: "400px" }} />;
}
A pre-built React wrapper is also available at dist/quikchat.react.js — see the React example for a live demo using it.
Use a template ref and onMounted to initialize.
<template>
<div ref="chatEl" style="height: 400px" />
</template>
<script setup>
import { ref, onMounted } from "vue";
import quikchat from "quikchat";
import "quikchat/dist/quikchat.css";
const chatEl = ref(null);
let chat = null;
onMounted(() => {
chat = new quikchat(chatEl.value,
(c, msg) => {
c.messageAddNew(msg, "you", "right", "user");
},
{ theme: "quikchat-theme-light",
titleArea: { title: "Vue Chat", show: true } }
);
});
</script>
Use a ref variable and onMount to initialize.
import { onMount } from "solid-js";
import quikchat from "quikchat";
import "quikchat/dist/quikchat.css";
function Chat() {
let el;
let chat;
onMount(() => {
chat = new quikchat(el,
(c, msg) => {
c.messageAddNew(msg, "you", "right", "user");
},
{ theme: "quikchat-theme-light",
titleArea: { title: "Solid Chat", show: true } }
);
});
return <div ref={el} style={{ height: "400px" }} />;
}
Bind the container element and use onMount.
<script>
import { onMount } from "svelte";
import quikchat from "quikchat";
import "quikchat/dist/quikchat.css";
let chatEl;
let chat;
onMount(() => {
chat = new quikchat(chatEl,
(c, msg) => {
c.messageAddNew(msg, "you", "right", "user");
},
{ theme: "quikchat-theme-light",
titleArea: { title: "Svelte Chat", show: true } }
);
});
</script>
<div bind:this={chatEl} style="height: 400px" />
Svelte's bind:this gives you the DOM element directly — same pattern as every other framework. Works with both Svelte 4 and Svelte 5.
Use ViewChild and ngAfterViewInit.
import { Component, ViewChild, ElementRef, AfterViewInit } from "@angular/core";
import quikchat from "quikchat";
@Component({
selector: "app-chat",
template: `<div #chatEl style="height: 400px"></div>`,
styleUrls: ["~quikchat/dist/quikchat.css"]
})
export class ChatComponent implements AfterViewInit {
@ViewChild("chatEl") chatEl!: ElementRef;
private chat: any;
ngAfterViewInit() {
this.chat = new quikchat(this.chatEl.nativeElement,
(c: any, msg: string) => {
c.messageAddNew(msg, "you", "right", "user");
},
{ theme: "quikchat-theme-light",
titleArea: { title: "Angular Chat", show: true } }
);
}
}
Angular's nativeElement gives you the DOM element. Import the CSS in your component or add it to angular.json styles array.
npm install quikchat works in any project.useEffect, onMounted, etc.). It won't run during server-side rendering.declare module "quikchat" or reference the JSDoc types in the source.