Studio
A visual interface for your model overrides: list, set, and clear them per feature, and view live SDK usage snippets. Fully responsive — works on desktop and mobile.
Zero-install — served by the SDK router
RecommendedIf you already use the Hono or Express router, Studio is served automatically. No separate package, no React app, no extra config. Just mount the router and open the URL.
Hono
import { Hono } from "hono";
import { createModelKit, createRedisAdapter } from "@benrobo/modelkit";
import { createModelKitHonoRouter } from "@benrobo/modelkit/hono";
const modelKit = createModelKit(
createRedisAdapter({ url: process.env.REDIS_URL || "redis://localhost:6379" })
);
const app = new Hono();
app.route("/api/modelkit", createModelKitHonoRouter(modelKit));
// Studio is now live at: http://localhost:3000/api/modelkit/studio
Express
import express from "express";
import { createModelKit, createRedisAdapter } from "@benrobo/modelkit";
import { createModelKitExpressRouter } from "@benrobo/modelkit/express";
const app = express();
app.use(express.json());
const modelKit = createModelKit(
createRedisAdapter({ url: process.env.REDIS_URL })
);
app.use("/api/modelkit", createModelKitExpressRouter(modelKit));
// Studio is now live at: http://localhost:3000/api/modelkit/studio
Studio is enabled by default. To disable it or change the path:
createModelKitHonoRouter(modelKit, { studio: false })
createModelKitHonoRouter(modelKit, { studioPath: "/admin/ui" })
// Studio will be at: /api/modelkit/admin/ui
Protecting Studio (auth)
Studio exposes write access to all your overrides — you should protect it in production. Add your own middleware on the mount path before the router:
// Hono — register middleware on the same path before app.route()
app.use("/api/modelkit/*", async (c, next) => {
if (c.req.header("Authorization") !== `Bearer ${process.env.MODELKIT_SECRET}`) {
return c.json({ error: "Unauthorized" }, 401);
}
await next();
});
app.route("/api/modelkit", createModelKitHonoRouter(modelKit));
// Express — pass middleware as a second arg to app.use()
const authGuard = (req, res, next) => {
if (req.headers.authorization !== `Bearer ${process.env.MODELKIT_SECRET}`) {
return res.status(401).json({ error: "Unauthorized" });
}
next();
};
app.use("/api/modelkit", authGuard, createModelKitExpressRouter(modelKit));
How it works
The Studio UI (React + all dependencies) is bundled into the SDK at build time as a self-contained HTML string. When a request hits /studio, the router serves that HTML directly. No filesystem reads, no external CDN, no React install required in your app.
React component
OptionalIf you want to embed Studio directly inside an existing React app (e.g. an internal dashboard), install the package and render the component.
npm install @benrobo/modelkit-studio
# or: bun add @benrobo/modelkit-studio
import { ModelKitStudio } from "@benrobo/modelkit-studio";
import "@benrobo/modelkit-studio/styles";
function AdminPage() {
return (
<ModelKitStudio
apiUrl="http://localhost:3000/api/modelkit"
theme="dark"
/>
);
}
Use your production backend URL for apiUrl — the same route where you mounted createModelKitHonoRouter or createModelKitExpressRouter. Make sure CORS is enabled on the backend if the frontend is on a different origin.
Props
interface ModelKitStudioProps {
/** URL of your ModelKit API endpoint (required) */
apiUrl: string;
/** Preset theme name or custom theme object (default: "dark") */
theme?: "light" | "dark" | StudioThemeOverride;
/** Base theme to merge custom overrides into */
themeBase?: "light" | "dark";
/** Additional className for the root container */
className?: string;
/** Per-element className overrides */
classNames?: ClassNameOverrides;
/** Bring your own TanStack Query client */
queryClient?: QueryClient;
}
Themes
Built-in presets: dark, light, choco, ocean, sunset, forest, purple, crimson, cyan, amber. Or pass a StudioThemeOverride object for full control.
import { ModelKitStudio, type StudioThemeOverride } from "@benrobo/modelkit-studio";
const customTheme: StudioThemeOverride = {
colors: { primary: "#7c3aed", background: "#0c0c0d", text: "#fff" },
fonts: { body: "Inter", mono: "JetBrains Mono" },
};
<ModelKitStudio apiUrl="..." theme={customTheme} />
Styling
Import @benrobo/modelkit-studio/styles once in your app entry. Studio uses the mk: Tailwind prefix so styles won't clash with your app's own Tailwind classes.
import "@benrobo/modelkit-studio/styles";
// Override individual element class names
<ModelKitStudio
classNames={{
container: "max-w-7xl",
buttonPrimary: "bg-indigo-600 hover:bg-indigo-500",
}}
/>