(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!
Before you can start building extensions, you need to have the following installed:
And set up time tracking with Hackatime in your favorite editor!
You need to be signed in to access the developer features.
Simply run the store command: 
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:

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”!
The green drive icon means that npm run dev is active.
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.

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!
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 Built with ♥︎ by Hack Club. cmd + k is not affiliated or endorsed by Raycast