Making our API more powerful

How we're making it even easier for developers to extend Raycast

Written by
AvatarThomas Paul Mann
Published on

From day one, we knew that Raycast would only work if developers could extend the app. So in October 2021, we released the beta of our Extensions API and Store, where developers can build and publish extensions for everyone.

Since then, 300 developers have contributed over 500 extensions that people have installed over half a million times! These numbers humble us 😌 And today, we're still making it easier for developers to extend Raycast, so it's even more powerful for everyone.

Breaking out of Raycast with Menu Bar Commands

For a long time, Commands could only live in the Raycast window. From today, Commands can put glanceable information in the Menu Bar 💪

Unread Linear notifications in the menu bar
Unread Linear notifications in the menu bar

When we put the option to show upcoming events in the Menu Bar to the My Schedule Command, your responses were so overwhelming that we couldn't keep this feature to ourselves. New APIs allow putting a title, icon, and menu in the Menu Bar. It builds on top of our excellent developer experience with React and TypeScript.

Here's a simple Command that shows unread GitHub notifications in the menu bar:

import { getPreferenceValues, MenuBarExtra } from "@raycast/api"; export default function MenuBarCommand() { const { data, isLoading } = useNotifications(); return ( <MenuBarExtra icon="github.svg" isLoading={isLoading}> {data?.map((notification) => ( <MenuBarExtra.Item key={notification.id} title={notification.subject.title} /> ))} </MenuBarExtra> ); }

To keep Menu Bar Commands up-to-date, we ported Background Refresh from Script Commands to Extensions. Background Refresh is configured with a new interval option in the Extension's package.json.

After you configure a Command, Raycast takes care of the rest. We repeatedly execute the Command in the background by using the system to determine the most efficient time. We also show when a Command was last refreshed. New Commands can't run in the background automatically; a user needs to activate them after a fresh installation from the Store.

Menu Bar Commands are great for showing frequently pulled information, like open GitHub issues, unread Linear notifications, or your current Slack status. Both features are in beta, and we're excited to see what you'll build with them. Follow this guide for your first Menu Bar Command.

Make simple things simple and complex things possible

We designed Raycast's user interface to be as intuitive as possible. Once you learn the basics, you can apply them to everything. The main goal for our API is to make it easy for developers to build on top of this foundation. By using our built-in components, developers can concentrate on their business logic.

We've released new React hooks to make it faster to build extensions that follow best practices. To do this, we looked at the Extension's repository for use cases and how we can improve them. Most Extensions connect to APIs: they make network requests, show a toast to handle errors, and add caching and optimistic updates to speed up interactions.

Drum roll, please…🥁 you can now get all this free with a single hook: useFetch. Here's an example:

import { getPreferenceValues } from "@raycast/api"; import { useFetch } from "@raycast/utils"; export type Notification = { id: string; subject: { title: string; }; }; export function useNotifications() { return useFetch<Notification[]>("https://api.github.com/notifications", { headers: { Accept: "application/vnd.github+json", Authorization: `token ${getPreferenceValues().token}`, }, }); }

In our example, we halved the lines of code needed to search npm packages with the useFetch hook. The hook builds on top of other custom hooks. This structure makes it flexible to integrate with your needs, for example, using Octokit to connect to the GitHub API. Run npm install @raycast/utils to use the new hooks in your project.

We're excited to see how you use the hooks! We hope they'll push the boundaries while keeping our Extensions platform consistent. We're also planning to make other common use cases more straightforward, so stay tuned for updates.

Open-sourcing the Linear extension

Another mention is that we converted the native Linear extension to TypeScript and now open source it. We're proud that the API can power such complex extensions.

New and open source Linear extension
New and open source Linear extension

We collaborated with Thomas Lombart, the developer of the Todoist Extension, to convert the Linear extension. Here's what he had to say about our API:

"Working with Raycast's API is delightful in every way. You can clearly see it's something made by developers. No matter what you use from the API, it's always thought through, reliable, intuitive and documented extensively. After months of working with the API on various Raycast extensions, I'm confident it's possible to build one with a great UX in less than a day."

By converting the Extension, we also added a Menu Bar Command to show unread notifications, a new Command that uses arguments to create issues for yourself quickly, and improved more things.

After Launch Week, we've also open-sourced the Google Workspace, Zoom and Asana extensions and we are working on more of them. This is one of the ways of giving back to our community. Plus, it's a great showcase of all the features the API offers.

And one more thing while you're here…

We also ported more functionality from Script Commands. Extensions can now define arguments, which enable simple forms that live in the root search of Raycast.

Developers can modify the subtitle of a Command dynamically. Combined with Background Refresh, this is another way to present information to the user as dashboard-like items in the root search.

That's probably enough updates, for now 😅 Safe to say, we're constantly blown away by what you build. We can't wait to see what you'll create next with these additions to our developer platform. See you in the pull request reviews 😉