Building WorkRemotely: A Month as a Product Builder
In October I went to two conferences in Munich. At Just Product, GitHub’s former VP of Product for Copilot said it has never been easier to build something nobody wants. At PUSH UX my main takeaway was that designers, engineers and product managers are turning into product builders: one person who carries a product from the idea to the running system.
WorkRemotely.eu is my attempt at being one. It is a remote job board for people who live in the EU. It reads the job boards of 1,270 companies, checks every remote job for which EU countries can hire you, and shows a quote from the posting as evidence. I started it on October 4, launched it on October 6 and have run it since. Claude Code agents wrote the code. I made the product, design, copy and technical calls.
The case study has the product and the numbers. This is how the first month went, and where the time went.
Three days to launch
The first evening was research. I bought workremotely.eu and workremotely.world, then mapped 48 competitors, each with a note on what its users write in reviews, on Reddit and in forums. The most common complaint, in about 13 of 26 threads, was that “remote” can’t be trusted. One user wrote about We Work Remotely: “99% require US citizenship despite ‘work anywhere’.”
That gave the product one question to answer for every job: can I apply from where I live?
By eight in the evening the core idea was a clickable prototype: search as a sentence. “I live in Germany and want design jobs that pay at least €70k, as an employee.” Each part of the sentence is a choice. It reads faster than a filter sidebar, and it says the visitor’s situation back to them. Before midnight a crawler was reading company job boards straight from Greenhouse, Lever, Ashby, Workable and Personio, and Gemini was reading every posting for who can apply. Its answer only counted with a word-for-word quote from the posting, checked against the text.
On day two a background agent added five more hiring systems and three discovery sources while I worked on the product. The jobs open to the EU went from 324 to 2,404.
On launch day a separate model audited security. It found that a job posting with an injected prompt could steer the local agent I used for reading postings, run commands on my Mac and leak the result into the public list. That workaround never touched production.
The afternoon went to hosting. I had planned a Hetzner server and switched to Vercel and Neon, because a server is one more thing to run on your own. For the switch I wrote a contract first: the target architecture, which agent owns which files, the environment variables and the schedule. Four agents then rebuilt the backend in parallel, each in its own git worktree, and the result was checked against a copy of the real data before anything went live. The first signup was confirmed at 17:04.
The data is the product
I expected to spend the month on screens. Most of it went into rules about data.
Remote flags are unreliable. A heat pump company listed its service technicians as remote, and a shipping company its tanker crews. Companies post one role many times: Bjak posted some roles 36 times, once per country, and Speechify one role 81 times, once per city. A title says “Spain or Portugal-based role” while the location field says Berlin. Each of these needed a rule, and each rule was checked against every open job before it shipped. A rule that fixes one listing can quietly break forty others.
The hardest problems only showed when I put the site next to the postings. In early November I found that whenever the rules and the reading model disagreed on who can apply, the narrower answer won. The location field usually names an office, so 162 jobs open to the whole EU were shown to about 3.6 countries each. The fix lets a broader reading win when its quote says so, and a weekly check now has the model judge 40 disagreements. It also changed the first monthly report before it went out: its headline finding, that whole-EU hiring had dropped to 18%, came from the old rule.
Pay went the same way. The site showed “€0 a year” for a role paying €115,000 to €130,000. Job boards hand over pay in shapes nobody would guess: Recruitee’s “65.00” for €65,000, yearly pay in thousands without the zeros, monthly pay with no period. Now the model’s quoted reading of the posting wins when the quote is in the posting, the board’s own fields are checked for period and plausibility, and an implausible figure is not shown at all. Jobs with pay on the site went from 662 to 1,194. The rule I wrote down for it is that no data beats wrong data.
On November 7 a sample of 40 jobs showed the remote check getting a quarter of them wrong. It read travel as a place to live, or let a company’s boilerplate outweigh the role’s own line. I decided travel is not a place, and that went into the prompt with a test set of 13 cases.
None of this shows on a screen, and all of it decides whether someone in Portugal trusts the list.
Watching what people do
In the first days 233 of 305 Apply clicks came from the job title. It sent people to the employer before they had seen who can apply, which is the one thing the site exists to tell them. A click on the title now opens a details panel, and Apply on the card still goes straight to the posting.
Nine days in, 70% of searches and 90% of Apply clicks happened with the default “I live in Europe”, which only shows jobs open across the whole EU. The country is the point of the product, so the start page now preselects the visitor’s country from the IP address and uses it only until they change anything.
Some numbers took features away. At launch a small drawer asked returning visitors whether a job was still open, and a “no” made the crawler recheck that company’s board. After 101 answers, 18 said the job was gone, and only 3 of those jobs closed within a day. I removed the question on November 6.
Others showed where to push. Alert signups sat at about 23 per 1,000 visitors. Every signup now ends in an “Almost there” window with a button that opens the mailbox, and a small notification offers the alert on every screen. In the first week of November 131 people signed up, against 44 the week before.
Being found
I built the search pages for Google. ChatGPT found them first.

Asked where to find a remote job in Portugal, ChatGPT lists WorkRemotely.eu first, as the best starting point, and further down links straight to the page for remote design jobs in Portugal. Those pages came from the data. I read the Google Ads search terms and the Umami events side by side and built 85 pre-rendered pages by country, field and topic. When visitors from AI search started landing on countries that had no page yet, they grew to 150, and in November to about 350, each with its numbers written out as a paragraph and three to five answered questions.
In the third week ChatGPT showed We Work Remotely’s logo next to my site’s name, because my icon was an emoji inside an SVG and a crawler draws that as blank. And Google had never fetched the sitemap. By November 2 it had indexed 28 pages. Both came down to the same habit I lacked: looking at the site the way a crawler does, with curl and no JavaScript, as well as in a browser.
Free tiers and one server
Vercel and Neon were right for launch week. They were the wrong shape for a product that is one long-running job reading 1,270 job boards.
Two days after launch, Neon’s 5 GB of monthly data transfer was nearly gone. The cause was one line: the insights page loaded every job’s full text, about 130 MB, on each of six daily builds. Measuring what each query read took minutes, and five fixes took it from about 1.2 GB a day to 130 MB. A week later the prepaid Gemini credit ran out. The API answered 402, and the analyzer stored that answer as a failed reading for 218 postings, as if they were unreadable. A quota error says nothing about the data, so a 402 now waits and retries. Then the crawl alone used up the four hours of CPU a month that Vercel’s free plan gives, and Umami Cloud’s free plan was full.
On October 30 everything moved to one Hetzner server in Nuremberg after all: the website, the API, the crawler, the analyzer on one timetable instead of 33 cron entries, Postgres and a self-hosted Umami. I ran a full copy next to production for two days first, wrote a runbook the evening before and kept the old stack as a way back. The switch took 27 minutes, with no downtime and no row lost. The server costs €4.49 a month, and on its first day it averaged 3.5% CPU.
A new look in two days
For four weeks the design got tidier in small rounds: one type scale, six spacing steps, an accessibility pass. It kept its launch parts, though: the 🇪🇺 emoji as the logo, the EU’s blue, gold stars and Montserrat headlines. On November 4 it got a new visual language, built next to the live site and shown on a preview address.

Xmind sets the headlines and the figures, and Inter the text. The interface went monochrome, with one ink blue and yellow as the highlighter in charts. An asterisk replaced the flag, and twelve of them still form the flag’s ring behind the Insights header.
The first round was built in an evening. The second came from going through the preview and pointing at what did not hold up. Chips stretched into eggs when a label wrapped. The arrow marking a reposted job read as a browser’s reload button and stood out more than it should; my note was “make it normal font color, does not need to stand out.” The ”≈” in front of converted pay looked wrong, and a currency tag in front of a euro figure read as that figure’s currency. Pay in the list now shows as the posting states it, “US$170–210K”, with the euro figure in the job panel. For the reposted mark and the pay I had six versions put side by side on one page, and each was settled in a single look. Phosphor icons were too thin and round beside Xmind, so Carbon replaced them for its square ends. On spacing I kept saying the same thing: “Either break it or use the same rhythm.”
The new design went live on November 6.
A design system under it
The redesign held because it sat on a system. Within two days it became the Asterisk Design System. It has semantic tokens for colour, spacing, type, motion and elevation, and seven colour scales of nine steps in OKLCH where a step number has the same job in every scale and both themes. About 170 dark-mode overrides became eight. Components come with guides, and seven patterns describe situations, such as an empty state or loading. A token check rejects raw palette values in the code, so a change that reaches past the system fails before it ships. Five principles sit on top, in order: honest, clear, quiet, exact, considerate.

The Storybook is public at workremotely.eu/asterisk. On November 6 the Figma library followed on the same tokens, most of it built by five agents in parallel: 22 components and 206 variants. The agents now read Asterisk before they touch a screen.
Running it as a team of one
By November the product had outgrown the way I had been working, one long session pushing to main. Since November 5 every change is a pull request, and a merge is the release. Checks on GitHub run the backend tests and compare screenshots of the design on four machines, only for what a pull request touches, in about three and a half minutes. I ran 1,014 screenshots without retries before I trusted them.
There are seven project agents: an orchestrator, and six for design, engineering, copy, the crawler, research and design system checks. Hooks ask before a push, a merge, a deploy or a connection to the server. The first push still went through without asking, because in bypass mode a hook’s question is approved without being shown. In that mode the hook now refuses and hands me the command to run myself.
GitHub issues became the open list, and an agent reads an issue as its brief. On November 7 four read-only code reviews, of the pipeline, the server, the website and the data model, turned into ten issues across four milestones.
Before the job pages went live, a QA agent in a fresh context got the acceptance criteria and the running site, without my conclusions. It found five problems I would have shipped. I keep doing that for anything that matters, because a reviewer briefed with my conclusions mostly confirms them.
What the month showed me
The first version of almost everything took an evening. The time went into deciding what is true and what to keep: which postings count as jobs, what a posting says about who can apply and what it pays, which feature earns its place and which question gives nothing back. An agent writes a rule in minutes. Choosing the rule the product should have, or noticing that a report’s headline came from the last rule’s mistake, stayed with me.
That is the line from Just Product, seen from the inside. Building got cheap for everyone, and so did building something wrong. WorkRemotely stays useful through the checking: a quote behind every answer, every rule run against every open job, a reviewer who has not seen the work, and the numbers read every morning.
Next is a report every month, pages in German, and workremotely.world.
I shape how people interact with technology. Product designer in Hamburg, 15+ years on the systems behind consumer and enterprise software.