Vicinae

Introduction

Vicinae extensions are written in TypeScript using React components. There is no browser involved: your code produces a serialized UI tree that the C++ core renders natively.

How it works

You write declarative React components using the @vicinae/api package. When state changes, components rerender and Vicinae handles the rest. All standard Node.js APIs are available.

import { ActionPanel, Action, List } from "@vicinae/api";
import { fruits } from "./data";

export default function FruitList() {
  return (
    <List isShowingDetail searchBarPlaceholder="Search fruits...">
      {fruits.map((fruit) => (
        <List.Item
          key={fruit.emoji}
          title={fruit.name}
          icon={fruit.emoji}
          detail={<List.Item.Detail markdown={fruit.description} />}
          actions={
            <ActionPanel>
              <Action.CopyToClipboard title="Copy emoji" content={fruit.emoji} />
            </ActionPanel>
          }
        />
      ))}
    </List>
  );
}

Search, markdown rendering, and keyboard navigation all work automatically.

Raycast compatibility

Our API closely follows the Raycast API, and our long-term goal is compatibility with most existing Raycast extensions. We also offer exclusive APIs where it makes sense.