Codync
A free, open-source 1:1 alternative to Grok Bot and Muse. Message Claude Code, Codex, Cursor and 40+ coding agents as persistent bots from your iPhone, Mac or Linux desktop. Group chats, threads, appr
A lightweight TypeScript library for interactive videos: branching stories, questions and animated hotspots, in a Web Component under 9.5 KiB gzip.
Developer toolsTypeScript · JavaScriptGitHub @Daniel-GlzOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Lightweight TypeScript library for interactive videos with branching stories, questions, and animated hotspots
Taken from the repository README
Loading the full README.
Read the full README ↗Turn any video into an interactive one. Viewers answer questions, choose where the story goes and click animated hotspots, all with a single <ivkit-player> tag. No dependencies, under 9.5 KiB gzip.
IVKit works with its ready-made player or without it. Both read the same story format, so a story written for one plays in the other.
| Package | What you get | Use it when |
|---|---|---|
@ivkit/player | The <ivkit-player> Web Component: videos, questions, hotspots, controls, fullscreen and theming. | You want a player that works out of the box, in plain HTML or any framework. |
@ivkit/react | A React component around the player, with typed props and event callbacks, for React 18 and 19. | You use the player in React. |
@ivkit/core | The DOM-free engine, media controller and validator the player is built on. | You want your own interface: React or Vue components, a canvas, a game engine. |
@ivkit/player includes the engine from @ivkit/core, so you don't need both. To import story types or validateStory next to the player, add @ivkit/core at the same version.
This page plays a video that stops at second 4 and asks where to go, using the example videos of the documentation. It loads the player from a CDN, so it needs no build step:
<script type="module" src="https://cdn.jsdelivr.net/npm/@ivkit/[email protected]/dist/ivkit-player.min.js"></script>
<ivkit-player id="player" controls></ivkit-player>
<script type="module">
const videos = "https://daniel-glz.github.io/ivkit/examples/videos";
document.getElementById("player").story = {
version: "0.1",
start: "intro",
scenes: {
intro: {
src: `${videos}/adventure-intro.mp4`,
events: [
{
type: "question",
id: "path",
at: 4,
text: "Where do you want to go?",
options: [
{ id: "forest", label: "Into the forest", goto: "forest" },
{ id: "city", label: "To the city", goto: "city" },
],
},
],
},
forest: { src: `${videos}/adventure-forest.mp4` },
city: { src: `${videos}/adventure-city.mp4` },
},
};
</script>
With a bundler, install the package and import it once instead of the CDN script:
npm install @ivkit/player
import "@ivkit/player";
npm install @ivkit/core
The engine tells you what to show based on playback time, and you draw it however you like:
import { StoryEngine } from "@ivkit/core";
const engine = new StoryEngine(story);
engine.on("scene", ({ scene, time }) => {
video.src = scene.src;
video.currentTime = time;
video.play();
});
engine.on("interaction", ({ question }) => {
video.pause();
showQuestion(question); // calls engine.answer(choice.id) on click
});
engine.on("resume", ({ time }) => {
video.currentTime = time;
video.play();
});
engine.on("hotspots", ({ hotspots }) => renderHotspots(hotspots));
video.addEventListener("timeupdate", () => engine.update(video.currentTime));
video.addEventListener("ended", () => engine.mediaEnded());
engine.start();
Add MediaController to preload the next scene and change scenes without a black frame. See Custom players with core and a player built in Vue.
renderHotspot::part() and slots@ivkit/corevalidateStory errors as you typeShowcases on real footage:
@ivkit/core<ivkit-player>See CONTRIBUTING.md for setup, commands and size budgets.
Apache-2.0 © Alexis Gonzalez