Browse docs
Integrations

AI Integration (Claude + OpenAI)

Use the pre-wired Anthropic and OpenAI SDKs, with secure key storage and streaming responses — or swap in your own provider.

Updated Jul 2026
On this page

The boilerplate ships with both the Anthropic Claude Agent SDK and the OpenAI SDK pre-wired, plus a working demo screen, secure API key storage, and a streaming-response parser. You can have a working AI feature in your app in under an hour.

What's already in the box

  • A fully functional AI Demo screen at src/features/ai-demo/ — pick a provider, paste your API key, send a prompt, watch it stream back.
  • Secure key storage via Electron's safeStorage (macOS Keychain, Windows Credential Manager, Linux libsecret).
  • Server-Sent Events parser for streaming LLM responses with backpressure handling.
  • A clean provider interface in src/main/ai/ so adding a third provider is one new file.

Where API keys live

Never store keys in your renderer code. The boilerplate exposes a typed hook:

import { useApiKey } from '@/renderer/hooks/useApiKey'

const { key, set, clear, isSet } = useApiKey('anthropic')

// Store
await set('sk-ant-...')

// Read (only on user action — never on render)
const k = await key()

Behind the scenes, the key is encrypted with the OS keychain via safeStorage and never leaves the main process unless the user explicitly requests it.

Calling Claude

// src/main/ai/claude.ts — already in the boilerplate
import Anthropic from '@anthropic-ai/sdk'

export async function* streamClaude(prompt: string, apiKey: string) {
  const client = new Anthropic({ apiKey })
  const stream = await client.messages.stream({
    model: 'claude-sonnet-4-5',
    max_tokens: 4096,
    messages: [{ role: 'user', content: prompt }],
  })
  for await (const event of stream) {
    if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
      yield event.delta.text
    }
  }
}

In your renderer, consume the stream over IPC:

// in any React component
import { useAi } from '@/renderer/hooks/useAi'

const { stream, isStreaming } = useAi('claude')

async function ask() {
  for await (const chunk of stream('Summarize this PDF in 5 bullets...')) {
    setOutput((prev) => prev + chunk)
  }
}

Adding your own provider

Three files. That's the pattern:

  1. src/main/ai/<provider>.ts — the SDK client + a generator that yields tokens
  2. src/shared/ipc/ai-channels.ts — add 'ai:stream:<provider>' channel name
  3. src/renderer/hooks/useAi.ts — add <provider> to the discriminated union

The boilerplate uses Claude 4.5 by default

When you copy the demo code, update the model ID to whatever you're shipping. Anthropic and OpenAI both deprecate older models; pin to a version that's covered by your prompt cache strategy.

Ask your AI assistant

"I want to add a feature that summarizes the user's clipboard with Claude. Following the patterns in src/features/ai-demo/, scaffold the IPC channel, main-process handler, and React hook. Use streaming. Don't write the UI yet — I want to design that part."

Where to go from here

  • All the deep technical docs live in the repo at /docs/ (read after purchase).
  • Stuck? Read CLAUDE.md once — it gives any AI coding tool the full context to help you extend the boilerplate.

Want everything wired up?

Get the full Desktop App Boilerplate — auto-update, code-signing, license activation, AI primitives, 26 UI components — for $49.

Get it for $49 →