TL;DR
- Context: A side project next to my full-time job as UX Lead at a bank. Raycast is my everyday Mac tool, a Spotlight replacement.
- Problem: The Raycast extension store has over 1,700 entries, no meaningful categories and 10 results per page.
- What I did: I built a script that pulls data from Raycast’s official repository, categorizes extensions through the OpenAI API and publishes a ready catalog as a separate GitHub repo.
- Result: 1,716 extensions in 18 categories, 600 stars and 12 forks. Maintained for ~5 months; today the repo is an archive.
Diagnosis
Raycast’s extension store has over 1,700 entries and no sensible way to browse them: no categories, 10 results per page. I could have worked around it by pulling data straight from the website (web scraping). But I didn’t want to break the terms of service or rely on something that would fall apart with the next change to the site’s layout. So I found the official GitHub repository where Raycast keeps data for all extensions. I forked it and wrote a script around it that pulls the data, categorizes it with GPT and publishes a ready catalog as a README.
flowchart TD
subgraph Before["Before"]
A1["Looking for an extension<br/>in the Raycast store"] --> A2["No categories,<br/>10 results per page"]
A2 --> A3["Scroll through pages<br/>or guess the name"]
end
subgraph After["After"]
B1["Fork of raycast/extensions<br/>+ a script merging the data"] --> B2["Categorization<br/>via the OpenAI API"]
B2 --> B3["Catalog on GitHub,<br/>18 categories"]
end
classDef good fill:#e6f2ea,stroke:none,color:#1f4d33,rx:14,ry:14
classDef bad fill:#faeaea,stroke:none,color:#5f2626,rx:14,ry:14
classDef accent fill:#27272a,stroke:#3f3f46,stroke-width:1px,color:#fafafa,rx:14,ry:14
class A1,A2,A3 bad
class B1,B2 good
class B3 accent
style Before fill:#fdf5f5,stroke:#e0c3c3,stroke-width:1px,color:#5f2626,rx:14,ry:14
style After fill:#f2f8f3,stroke:#c2dcc8,stroke-width:1px,color:#1f4d33,rx:14,ry:14
linkStyle default stroke:#a8a8b3,stroke-width:1.5px
What I did
- I forked the official
raycast/extensionsrepository and wrote a script that merges thepackage.jsonfiles of every extension into one data array. - I categorized the extensions through the OpenAI API: first with GPT-3.5-Turbo-0125 (one of the first models with controlled JSON output), then with GPT-4-turbo, using a prompt that kept the model to a closed list of categories.
- I automated the whole pipeline in practically one script: syncing the fork, detecting new extensions compared with the previous version, categorizing, generating the README, publishing.
- I published the result as a public GitHub repo: 1,716 extensions in 18 categories.
Results
| Metric | Value |
|---|---|
| Extensions categorized | 1,716 |
| Categories | 18 |
| GitHub stars | 600 |
| Forks | 12 |
| Active maintenance | ~5 months (May–September 2024) |
- 1,716 extensions categorized automatically. I didn’t have to go through each entry by hand.
- 600 stars and 12 forks on GitHub, so people really used it.
- Official data only. Everything was based on Raycast’s repository, without pulling anything from the website.
- Each update meant running a single script.
The problem
Why is the Raycast extension catalog hard to browse?
The store has no proper categories and shows only 10 extensions per screen. With over 1,700 entries, you have to scroll through dozens of pages or type the exact name into search. And if you don’t know what you’re looking for (which is often the case, because you’re only just discovering what Raycast can do), you have no sensible way to browse the store.
Why not web scraping?
Because it’s a fragile solution and borderline against the terms of service. The site can change at any moment and the scraper stops working. I also didn’t want to pull data from someone else’s website when the company publishes it itself. The official GitHub repository, where Raycast keeps the package.json of every extension, gave me the same data, and I could rely on it.
My role / scope
- Solo side project, next to my full-time job as UX Lead at a bank.
- I designed the whole pipeline and the categorization prompt, wrote the scripts and maintained the repository for ~5 months.
Process
- Finding the data source: I found and forked the official GitHub repository with data for all extensions.
- Iterating on the prompt: several attempts before the model stuck to the given categories and stopped inventing its own.
- Automation, step by step: sync the fork → new dated folder → compare with the previous version → categorize via the API → generate the README → publish.
- Maintenance: 11 commits between May and September 2024, as new extensions appeared.
Key decisions & trade-offs
- The official repository. The start was slower, because I had to find the right repository and understand its structure. In return, the solution was stable and within the rules, and a change to the site’s look didn’t break anything.
| Approach | Risk | Decision |
|---|---|---|
| Scraping the Raycast website | breaks the terms of service, fragile when the layout changes | rejected |
| Forking the official GitHub repo | depends on the package.json structure in the repo | chosen |
- The model’s response as JSON. GPT-3.5-Turbo-0125 returned controlled JSON, so I didn’t have to write a separate parser for its responses. It was one of the first times I tested structured output in practice, before it became standard in most models.
- In September 2024 I stopped updating the catalog. I have to admit that without dedicated time next to a full-time job, I couldn’t keep up with tracking new extensions and fixing categories. Today the repository is archived.
How it turned out
The repo has 600 stars and 12 forks, but the last commit is from September 2024. Today it’s archived. Raycast’s official store still has no real browsing by category, only search and a few links in the footer, so the problem I was solving still exists. I didn’t continue, because maintaining the categorization next to a full-time job stopped being worth it. I ended this project deliberately.
What I took away
- Automation needs maintaining too. Even a well-designed pipeline needs someone to look after it as the data grows.
- Choosing a data source is a design decision too. The official repository cost me more time at the start, but nothing fell apart for 5 months.
- Structured output saves hours of work. In my view, testing it in practice before it became standard gave me a good feel for when AI really speeds up work and when it only looks that way.