2026

Brave Search Companion

A privacy-first Raycast extension wrapping Brave Search with AI answers, suggestions, and searchable local history. No accounts, no API keys, no analytics, no external backend. History stays local with configurable retention.

AI toolingDeveloper toolingTiny toolsPublic tool
Brave Search Companion Raycast search surface concept

Most Raycast search extensions assume you have an API key and are fine with your queries leaving your machine. This one does not. Brave Search Companion wraps Brave's public search surfaces, including AI answers and suggestions, into a local-first Raycast utility with no accounts, no paid API key, no analytics, no telemetry, and no external backend. Your search history lives in Raycast's local storage with configurable retention, and nothing about your queries touches a server that is not Brave's own public page.

Public repository: github.com/1Pio/raycast-brave-search-companion

What it does

Three commands cover the surface. Search Brave live-searches with AI answers, web results, and suggestions. Search History searches your locally stored query, answer, and result history. Search Settings controls retention and completion suggestion visibility.

The AI answer integration is where the interesting work happened. Brave can rate-limit AI answer streaming, so the extension degrades gracefully: normal search results and suggestions still work, and the user can open the full AI conversation in Brave Search directly.

The empty-state discipline

The detail I spent the most time on was status honesty. The user who commissioned this work was precise about one thing: the message "No AI answer is available for this query" should appear only when an AI answer genuinely does not exist. It should not appear during loading, idle states, blank input, rate limiting, parse failures, or generic errors. Each of those conditions got its own specific title and description.

This sounds pedantic until you use an extension that tells you nothing is available when it is actually still thinking. Status-specific copy is the difference between a tool that feels broken and one that communicates honestly about what is happening.

Working within platform limits

A key platform finding shaped the interaction model. Raycast's Detail and List.Item.Detail components expose markdown render surfaces, not a documented selectable plain-text mode. Form.TextArea is editable text, which is wrong for a read-only answer view. So the accepted UX became Enter on the AI item to open a plain-text-looking Detail view, and Cmd+Enter to copy the full answer. The exploration that led there involved testing Form.TextArea, TextEdit fallbacks, and temp-file approaches before settling on the cleanest path the platform actually supports.

The process pattern was also deliberate. Before implementing the final UX, I rolled back to a known clean commit, removed only the exploratory files, left proof artifacts untouched, and then built the narrower behavior on a clean base. Rollback-before-new-edits is a workflow I trust for any exploration that might not pan out. The final pass was backed by tests around AI answer details, copy actions, empty states, and Raycast component mocks, plus build and lint checks.

What I take from it

Small tools reveal care through their edge cases. The interesting work in this extension was not the search itself. It was making sure every possible state, from empty input to rate limiting to genuine unavailability, communicates honestly without misleading the user.