Skip to content

Getting Started

This guide walks through creating a mini-app, from the basic setup to adding persistence and a backend.

Mini-apps are created by Kins using AI tools. You interact with them through conversation:

“Create a todo list mini-app”

The Kin calls create_mini_app and the app appears in your sidebar. But understanding the internals helps you guide the Kin effectively.

Every mini-app needs:

  1. An app.json declaring React dependencies
  2. An index.html with a root div and JSX script
{
"dependencies": {
"react": "https://esm.sh/react@19",
"react-dom/client": "https://esm.sh/react-dom@19/client",
"@kinbot/react": "/api/mini-apps/sdk/kinbot-react.js"
}
}

Add the component library (optional but recommended):

{
"dependencies": {
"react": "https://esm.sh/react@19",
"react-dom/client": "https://esm.sh/react-dom@19/client",
"@kinbot/react": "/api/mini-apps/sdk/kinbot-react.js",
"@kinbot/components": "/api/mini-apps/sdk/kinbot-components.js"
}
}
<div id="root"></div>
<script type="text/jsx">
import { useState } from "react";
import { createRoot } from "react-dom/client";
import { useKinBot } from "@kinbot/react";
function App() {
const { ready } = useKinBot();
if (!ready) return <div>Loading...</div>;
return <h1>Hello, Mini-App!</h1>;
}
createRoot(document.getElementById("root")).render(<App />);
</script>

Important: Always call useKinBot() at the root of your app and wait for ready before rendering content. The hook calls KinBot.ready() internally and sets ready to true once the SDK bridge is initialized.

Instead of writing HTML from scratch, Kins can use built-in templates:

"Create a dashboard mini-app using the dashboard template"

Available templates: dashboard, todo-list, form, data-viewer, kanban, responsive.

Use get_mini_app_templates to see all templates with descriptions.

Use useStorage to persist data across sessions:

import { useKinBot, useStorage } from "@kinbot/react";
function TodoApp() {
const { ready } = useKinBot();
const [todos, setTodos, loading] = useStorage("todos", []);
if (!ready || loading) return <div>Loading...</div>;
const addTodo = (text) => {
setTodos(prev => [...prev, { id: Date.now(), text, done: false }]);
};
// ... render todos
}

useStorage works like useState but persists to KinBot’s key-value storage. It returns [value, setValue, loading]. The loading flag is true while fetching the initial value. setValue accepts either a direct value or an updater function (like React’s useState).

For server-side logic, create a _server.js file:

export default function(ctx) {
const app = new ctx.Hono();
app.get("/stats", async (c) => {
const keys = await ctx.storage.list();
return c.json({ totalKeys: keys.length });
});
return app;
}

Access it from the frontend:

import { useApi } from "@kinbot/react";
function Stats() {
const { data, loading } = useApi("/stats");
if (loading) return <Spinner />;
return <p>Total keys: {data.totalKeys}</p>;
}

See Backend for the full backend guide.

Mini-apps can have multiple files. Use write_mini_app_file to add CSS, JavaScript, images, or additional JSX files:

app-files/
├── index.html # Entry point
├── app.json # Dependencies
├── _server.js # Backend (optional)
├── styles.css # Custom styles
├── components/
│ └── header.jsx # Additional components
└── img/
└── logo.png # Static assets

Reference files with relative paths in your HTML:

<link rel="stylesheet" href="styles.css">
<script type="text/jsx" src="components/header.jsx"></script>

Before making risky changes, create a snapshot:

"Create a snapshot of the todo app before the redesign"

The Kin calls create_mini_app_snapshot. If something breaks, roll back:

"Roll back the todo app to the previous version"

Max 20 snapshots per app (oldest are auto-pruned).