Quickstart
Install
# bun
bun add hudsonkit
# npm
npm install hudsonkit
react and react-dom ≥ 19 are peer dependencies — they should already be present in your Next.js 16 project.
Add the CSS bundle
In app/globals.css:
@import "tailwindcss";
@import "hudsonkit/styles";
Define a minimal HudsonApp
Create app/counter/index.tsx:
'use client';
import { createContext, useContext, useState, useMemo, type ReactNode } from 'react';
import type { HudsonApp, CommandOption } from 'hudsonkit';
// --- context ---
const Ctx = createContext<{ count: number; increment: () => void } | null>(null);
const useCounter = () => {
const ctx = useContext(Ctx);
if (!ctx) throw new Error('outside CounterProvider');
return ctx;
};
function CounterProvider({ children }: { children: ReactNode }) {
const [count, setCount] = useState(0);
const value = useMemo(() => ({ count, increment: () => setCount(c => c + 1) }), [count]);
return <Ctx.Provider value={value}>{children}</Ctx.Provider>;
}
// --- slots ---
function CounterContent() {
const { count, increment } = useCounter();
return (
<div className="flex flex-col items-center justify-center h-full gap-4">
<div className="text-[72px] font-mono tabular-nums">{count}</div>
<button
onClick={increment}
className="px-4 py-2 rounded border border-border bg-accent/10 hover:bg-accent/20 text-accent"
>
Increment
</button>
</div>
);
}
// --- hooks ---
function useCommands(): CommandOption[] {
const { increment } = useCounter();
return useMemo(() => [
{ id: 'counter:increment', label: 'Increment', action: increment, shortcut: 'Cmd+I' },
], [increment]);
}
function useStatus() {
const { count } = useCounter();
return { label: `count: ${count}`, color: 'emerald' as const };
}
// --- app ---
export const counterApp: HudsonApp = {
id: 'counter',
name: 'Counter',
mode: 'panel',
Provider: CounterProvider,
slots: { Content: CounterContent },
hooks: { useCommands, useStatus },
};
Mount AppShell
In app/page.tsx:
'use client';
import { AppShell } from 'hudsonkit/app-shell';
import { counterApp } from './counter';
export default function Page() {
return <AppShell app={counterApp} />;
}
Run it
bun dev
# or: npm run dev
Open http://localhost:3000. You should see the Hudson chrome: a nav bar with "COUNTER", a status bar showing count: 0, and the counter UI in the content area. Press Cmd+K to open the command palette and run Increment.
Next steps
- Building apps — the full
HudsonAppcontract: slots, hooks, panels, tools, takeover - API reference — every
hudsonkitexport organized by subpath - Theming — runtime theme/template switching, token surface, custom templates
- Systems — Intents, Services, and Ports for LLM/voice integration and inter-app data piping