ScopeScrape started as a CLI tool. Fast and accurate, but hard to explore results visually. You ran a scan, got a JSON file, and had to decode it yourself. That works for programmatic workflows, but it misses something critical: the ability to click through findings, filter by score tier, and dig into the four-dimension breakdowns in real time.
So I built a webapp. A FastAPI backend wrapping the existing pipeline, plus a single HTML frontend served locally. The result: zero external dependencies, no deployment friction, same dark theme and typography as the main site.
Why does a CLI tool need a webapp?
The pain was real. After running a scan, you had 119 posts with scores. Excel won't read results.json properly. You can't quickly filter by score range or signal tier without writing a Python script. You can't expand a single result and read the full breakdown of what contributed to its score.
The webapp solves this. Click "Run Scan," watch real-time progress updates, then click into any result to see the four dimensions that drove its score: frequency, intensity, specificity, recency. Toggle score tiers on and off. Export the filtered set back to JSON.
It also opens up a workflow I hadn't anticipated: uploading an old results.json file to explore it without re-scanning. Useful when you want to revisit data you collected weeks ago, or when someone shares their findings and you want to drill into it.
How does the architecture work?
The backend is FastAPI wrapping the existing ScopeScrape pipeline. When you POST a scan request, FastAPI launches the pipeline in a background thread and returns a scan ID. The frontend polls that ID every 500ms to check for progress updates and results.
The frontend is a single HTML file with embedded CSS and JavaScript. No build step. No npm. No node_modules. Just HTML, CSS, and vanilla JavaScript that talks to the FastAPI endpoints.
The entire app runs locally. scopescrape web starts a FastAPI server on localhost:8000. Your browser opens to the homepage. Everything happens on your machine.
What does the scan form do?
You fill in the same parameters you would pass to the CLI: platforms (Reddit, Twitter, etc.), keywords, filters. Hit "Start Scan." The form disables, the progress bar appears, and the frontend begins polling.
Each poll returns the current scan state: how many posts have been processed, how many passed the score threshold, what the highest score so far is, whether the scan is still running. The progress bar updates in real time. If a scan takes 30 seconds, you see the timeline as it happens, not after it completes.
When the scan finishes, the results appear below the form automatically. No page refresh needed.
How does the results explorer work?
Each result is a card showing the score prominently with a color-coded badge. 9.0+: red. 8.0-8.9: orange. 7.0-7.9: yellow. Below that: gray. The platform, post title, and snippet of text.
Click a card to expand it. The four dimensions appear: a small breakdown showing how much each dimension (frequency, intensity, specificity, recency) contributed to the final score. Click the dimension labels to sort or filter the results by that dimension alone.
At the top right of the results section are tier toggles. Click to filter: show only 9.0+, or 8.0+, or 7.0+. The list updates instantly. If you filter to 8.0+, only 38 results show instead of 119. From there you can export to JSON or continue exploring.
What about uploading existing results?
There is also an upload mode. Drag a results.json file onto the app, and it loads the results in the explorer. Same interface, same filtering, same dimension breakdowns. This lets you collaborate on findings without re-running scans, or revisit old data from archive.
What is the path to hosted deployment?
Right now it runs only locally. But the architecture is ready for hosting. The frontend will move to Vercel. The backend will move to Render. The frontend talks to the backend via a single API endpoint, so CORS is simple.
No database. Each scan is stateless. The backend stores results in memory during the scan, returns them when the frontend polls, and discards them when the scan completes or the server restarts. Users download their own results.json files if they want to keep them.
What is coming in v0.2?
I am adding five new platform adapters: Twitter, GitHub, Stack Overflow, Product Hunt, and Indie Hackers. Each platform has different data structures and APIs, so the backend is being refactored to make adapters pluggable.
The scoring engine is getting rebuilt. The frequency dimension broke in v0.1 because BM25 compared posts against themselves. That is fixed in v0.2 by using a proper negative corpus and intra-corpus term overlap. Intensity and specificity signals are being tuned. Recency is being added as a fresh dimension.
Airtable integration is coming. Scan results can be pushed directly to an Airtable base. Each result becomes a row with columns for score, dimensions, platform, and the extracted signals. This lets teams collaborate on findings without needing to download and share JSON files.
What design decisions did I make?
The webapp matches the main ScopeScrape site visually. Same dark background. Same accent red and cream palette. Same fonts: Playfair Display for headers, Source Serif 4 for body text, JetBrains Mono for code and score displays.
The interface is minimal. No sidebars, no modals, no dropdown menus. Just a form, a progress bar, and a results grid. The filter toggles are horizontal buttons above the grid. The expanded result details are inline within the card.
The scan form and results explorer live on the same page. You do not navigate between views. The form stays visible on the left as a sticky sidebar on desktop, and collapses into a collapsible section on mobile.