Build a Raycast extension

(macOS edition)

Extensions allow you to add extra features to Raycast. Let’s build your first Raycast extension to check the weather!

A lot of this guide is derived from the official Raycast Developer Documentation, so be sure to check that out!

Setup

Before you can start building extensions, you need to have the following installed:

  • Raycast 1.26.0 or higher
  • Node.js 22.14 or higher. (nvm is a helpful tool to switch between versions)
  • npm 7 or higher (should come installed with Node.js)

And set up time tracking with Hackatime in your favorite editor!

Sign in

You need to be signed in to access the developer features.

Simply run the store command: Sign in

Extension setup

Raycast has a few built in tools that make it super easy to make an extension.

Run the “Create Extension” command to get started. In the popup that shows, enter some details about your extension. I’m creating an extension to check the weather, so I’ll do that. I’ll use the “Show Detail” template:

create an extension, pt. 1 create an extension, pt. 1

No worries if it isn’t perfect, You can edit these in package.json after.


We can now open the folder that Raycast just created (it’ll be called your project name). Since I named my command “weather”, Raycast made a src/weather.tsx.

Here’s what’s in our file:

import { Detail } from "@raycast/api";

export default function Command() {
  return <Detail markdown="# Hello World" />;
}

If you’ve used React before, this might look familiar, because it is React. Essentially, Raycast extensions use pre-made React components. You can still make a Raycast extension if you’ve never used React, though!


We still need to run a few terminal commands before we can run our extension.

First, in the terminal install the required packages

npm install

And actually run it

npm run dev

Your extension will automatically reload and update as you change your code!

You can actually stop this script with control + c, and the extension will still be available on Raycast.


Let’s go back to Raycast, if you search up run your command, it should appear and say “Hello World”!

your command in Raycast your command running The green drive icon means that npm run dev is active.

Write the code

If you’ve used React before, you can probably skip this step.

Here’s some basic code to fetch the weather in Berlin.

import { Detail } from "@raycast/api"; 
import { useEffect, useState } from "react";

type WeatherData = {
  temperature: string;
  wind: string;
  description: string;
};

export default function Command() {
  const [weather, setWeather] = useState<WeatherData | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetch("https://goweather.xyz/weather/berlin")
      .then((res) => {
        if (!res.ok) throw new Error("Network response was not ok");
        return res.json();
      })
      .then((data) => {
        const weatherData = data as { temperature: string; wind: string; description: string };
        setWeather({
          temperature: weatherData.temperature,
          wind: weatherData.wind,
          description: weatherData.description,
        });
      })
      .catch((e) => setError(e.message));
  }, []);

  if (error) {
    return <Detail markdown={`# Error\n${error}`} />;
  }

  if (!weather) {
    return <Detail markdown="Loading weather..." />;
  }

  return (
    <Detail
      markdown={`# Berlin Weather\n\n**${weather.description}**\n\n- Temperature: ${weather.temperature}\n- Wind: ${weather.wind}`}
    />
  );
}

We’re using Typescript, so we first define what type of data we expect from goweather.xyz.

useState allows us to save values that allow other elements to respond to it’s changes. Notice how we put {weather.description} or if (weather) but never explicitly write code to update it after we get the weather data? React handles that for us because weather is a state.

useEffect is used to run code as a result of another action. In our case, we want our code to run when our command is loaded. Notice at the end, we put }, []);. The empty array tells React to run it on load.

The rest is pretty standard JavaScript, we’re just using fetch to get data from an API.

Finally, we use Raycast’s <Detail> component to show stuff to the screen.

the weather extension showing up in Raycast

Check out the Raycast examples and documentation

Raycast has a few awesome examples of how to implement things, you should check them out here: https://developers.raycast.com/examples/hacker-news

There are so many other possibilities. Raycast provides a ton of UI elements, and because it’s React, you can write your own!

(Optional) Publish your extension to the store!

First, if you want your extension to support Windows, grab a Windows friend/laptop and test it on there.

Then, this to your package.json

"platforms": [
  "macOS",
  "Windows"
]

Raycast makes it super easy to publish, run the following command and follow the instructions:

npm run publish


Once you’re done, submit your extension!

Built with ♥︎ by Hack Club. cmd + k is not affiliated or endorsed by Raycast