@link1987/llm-byok-react
v0.1.0
Published
React headless hooks + TailwindCSS UI components for LLM config
Downloads
70
Maintainers
Readme
@link1987/llm-byok-react
React headless hooks + TailwindCSS UI components for LLM provider/model selection and API key management. Companion to @link1987/llm-byok.
Two import paths:
@link1987/llm-byok-react— UI components + hooks (requires TailwindCSS)@link1987/llm-byok-react/headless— hooks only, zero UI dependency
Install
npm install @link1987/llm-byok-react @link1987/llm-byokPeer dependencies: react ^18 or ^19.
Headless Hooks
useApiKeys()
Manage all API keys stored in localStorage.
import { useApiKeys } from "@link1987/llm-byok-react/headless";
function App() {
const { keys, setKey, removeKey } = useApiKeys();
return (
<div>
<p>Configured: {Object.keys(keys).length} providers</p>
<button onClick={() => setKey("openai", "sk-...")}>Set OpenAI key</button>
<button onClick={() => removeKey("openai")}>Remove</button>
</div>
);
}Returns: { keys: Record<string, string>, setKey: (providerId, apiKey) => void, removeKey: (providerId) => void }
useApiKey(providerId)
Convenience hook for a single provider.
import { useApiKey } from "@link1987/llm-byok-react/headless";
function Chat() {
const [apiKey, setApiKey] = useApiKey("openai");
// apiKey: string, setApiKey: (key: string) => void
}UI Components
All components use TailwindCSS utility classes by default. Override styling via the className prop.
Important: Add the package to your
tailwind.config.tscontentarray so the classes are included:
content: [
"./app/**/*.{ts,tsx}",
"./node_modules/@link1987/llm-byok-react/dist/**/*.js",
],LLMConfigPanel
All-in-one panel: provider selector + model selector + API key input.
import { LLMConfigPanel } from "@link1987/llm-byok-react";
import { useApiKey } from "@link1987/llm-byok-react";
import { createRegistry } from "@link1987/llm-byok";
const registry = createRegistry();
function ConfigForm() {
const [providerId, setProviderId] = useState("openai");
const [modelId, setModelId] = useState("gpt-4o");
const [apiKey, setApiKey] = useApiKey(providerId);
return (
<LLMConfigPanel
providerId={providerId}
modelId={modelId}
apiKey={apiKey}
onProviderChange={setProviderId}
onModelChange={setModelId}
onApiKeyChange={setApiKey}
registry={registry}
/>
);
}| Prop | Type | Default | Description |
|------|------|---------|-------------|
| providerId | string | — | Current provider ID |
| modelId | string | — | Current model ID |
| apiKey | string | — | Current API key |
| onProviderChange | (id: string) => void | — | Provider change callback (auto-resets model) |
| onModelChange | (id: string) => void | — | Model change callback |
| onApiKeyChange | (key: string) => void | — | API key change callback |
| registry | Registry | createRegistry() | Custom registry |
| className | string | "space-y-4" | Root container classes |
| showApiKey | boolean | true | Show/hide API key input |
LLMConfigDialog
Modal dialog for managing API keys across all providers. Uses useApiKeys() internally for localStorage persistence.
import { LLMConfigDialog } from "@link1987/llm-byok-react";
function App() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Manage API Keys</button>
<LLMConfigDialog open={open} onClose={() => setOpen(false)} />
</>
);
}| Prop | Type | Default | Description |
|------|------|---------|-------------|
| open | boolean | — | Whether the dialog is visible |
| onClose | () => void | — | Close callback (backdrop click or X) |
| providers | ProviderDef[] | From registry | Custom provider list |
| registry | Registry | createRegistry() | Custom registry |
| className | string | — | Dialog content container classes |
| title | string | "API Keys" | Dialog title |
ProviderSelector
Standalone provider dropdown.
| Prop | Type | Description |
|------|------|-------------|
| value | string | Selected provider ID |
| onChange | (id: string) => void | Selection callback |
| providers | ProviderDef[] | Provider list |
| className | string | Override classes |
ModelSelector
Standalone model dropdown.
| Prop | Type | Description |
|------|------|-------------|
| value | string | Selected model ID |
| onChange | (id: string) => void | Selection callback |
| models | ModelDef[] | Model list |
| className | string | Override classes |
ApiKeyInput
Password input for API keys.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | — | Current value |
| onChange | (key: string) => void | — | Change callback |
| placeholder | string | "Enter your API key" | Placeholder text |
| className | string | — | Override classes |
Full Exports
// @link1987/llm-byok-react
export {
ProviderSelector,
ModelSelector,
ApiKeyInput,
LLMConfigPanel,
LLMConfigDialog,
useApiKey,
useApiKeys,
};
export type { UseApiKeysReturn };
// @link1987/llm-byok-react/headless
export { useApiKey, useApiKeys };
export type { UseApiKeysReturn };License
MIT
