runs-on.dev README

The project's README from github.com/zordhalo/runs-on.dev. As one markdown file: README.md.

runs-on.dev

runs-on.dev

Free subdomains for developers. Claim yourname.runs-on.dev in seconds, then point it wherever you like.

Claim a name  ·  Quickstart  ·  Guides  ·  Records  ·  Policy

stars names claimed tests license: AGPL-3.0


Claiming a name writes one file to this repository. That file is the record. It is the only thing that makes the name resolve, and you can read it without asking anyone.

{
  "name": "yourname",
  "owner": { "github": "yourname" },
  "claimedAt": "2026-01-01T00:00:00.000Z",
  "records": {}
}

There is no hidden database. The registry is this directory, the history is the git log, and the rules are in lib/.

Why this exists

A real top-level domain means an ICANN application. The 2026 round's evaluation fee alone is $227,000, before you've built or run a registry to back it. That's not a plausible way to get a custom-looking address for a side project.

runs-on.dev gets the same feeling: a distinctive ending instead of vercel.app or github.io, for the price of one domain, about $10 a year, by giving away subdomains under it. This is a subdomain registry, not a TLD. Every name you claim lives under runs-on.dev, which Advance Labs registered and is responsible for. Saying that plainly, instead of dressing it up as something bigger, is the whole basis for trusting it. There's prior art doing exactly this: is-a.dev, js.org, eu.org.

Claim a name

Go to runs-on.dev, sign in with GitHub, and type the name you want. If it's available, claiming it writes a record to domains/<name>.json in this repo, as shown above, and the name is live within seconds. One name per GitHub account. See docs/claiming.md for eligibility rules, the per-account limit, and why they exist.

Point it at your own hosting

By default a claimed name serves a small profile card built from your GitHub account. To point it at your own site, forward email, or a plain redirect instead, there are two ways to change its record.

From the site. Sign in and open runs-on.dev/manage. Pick a record type, fill it in, and save. That writes a commit to domains/<name>.json in this repository, exactly as a merged pull request would, and DNS follows within seconds. The form offers the record types in the combinations DNS actually permits, so it cannot build a record the schema would reject.

By pull request. Still supported, and the right choice when you want the change reviewed before it lands:

  1. Fork this repo.
  2. Edit domains/<name>.json, adding a record under records (and optionally subdomains, for a one-level-deep entry like _atproto).
  3. Open a pull request. CI validates the change against schema/record.schema.json; once it's green and merged, a workflow pushes the record to DNS automatically.

Both paths enforce the same rules, from the same code in lib/edit.js: only the owner may change a record, and owner, claimedAt, and name are immutable once set.

Type Shape Coexistence
CNAME a hostname string Alone: cannot sit next to A, TXT, or MX.
A 1+ IPv4 addresses With TXT, MX.
TXT 1+ strings, up to 255 chars each With A, MX.
MX 1 to 5 { priority, value } entries With A, TXT.
URL one absolute http(s):// string Alone: cannot sit next to anything, not allowed under subdomains.

Nine hosting providers, a URL redirect, email forwarding, a Bluesky handle, and Discord verification, each with the exact record to copy, are in docs/guides.md. The same walkthroughs render on the site at /docs/guides/<provider> with more detail per provider; the markdown file is the compact version for reading here.

Once a name serves your own site, docs/seo.md covers what changes when that site lives on a subdomain: robots.txt and sitemaps are per host rather than per domain, redirect names cannot rank, and a name needs its own Search Console property.

Two worked examples

Vercel, the shortest path from claim to a live custom domain:

"records": { "CNAME": "cname.vercel-dns.com" }

Add you.runs-on.dev as a custom domain on the Vercel project; it shows you this same CNAME target.

A Bluesky handle, which needs no hosting at all, just a subdomain entry:

"subdomains": {
  "_atproto": { "TXT": ["did=did:plc:abc123"] }
}

Full record reference, the subdomains grammar, and why CNAME can't coexist with anything else: docs/records.md.

How it works

A single wildcard *.runs-on.dev DNS record points every possible subdomain at one Vercel project, so an unclaimed or record-less name still resolves with a valid HTTPS certificate and gets served the profile-card page. Claiming a name is therefore a git commit, not a DNS write. Pointing a name at your own hosting merges a record into domains/<name>.json, and a GitHub Actions workflow pushes that exact record to Vercel's DNS API on merge, which then takes priority over the wildcard for that one name. More detail, including the two write paths and the token split, in docs/architecture.md.

The rules

Everything CI checks on a domains/** pull request, so you can verify a PR yourself before opening it:

See lib/pr.js for the implementation CI actually runs, and docs/contributing.md for the full breakdown of what it checks.

Self-hosting

This is an open registry, not a hosted product with a private backend. Running your own copy under a domain you own means:

  • Fork this repo and rename it; REGISTRY_REPO in .env.example points at wherever the fork lives.
  • Register your own domain, point a wildcard record at your deployment, and add it to Vercel (or adapt scripts/sync-dns.mjs and lib/dns.js for a different DNS provider).
  • Change ROOT in proxy.js and the hostname literals in app/page.jsx and app/sites/[name]/page.jsx from runs-on.dev to your domain.
  • Create your own GitHub OAuth app and set GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET.
  • Review data/reserved-*.json and adjust lib/eligibility.js for your own abuse tolerance.
Local development
npm install
npm run dev

The claim flow needs a signed-in GitHub session, and the session and OAuth cookies are set Secure (see app/api/auth/github/route.js and .../callback/route.js). A Secure cookie is dropped by the browser over plain HTTP, so the GitHub sign-in flow cannot be exercised on http://localhost. This is correct for production: runs-on.dev is on the HSTS preload list, so it's always HTTPS there, and a cookie that only ever travels over HTTPS shouldn't get a Secure-free code path just for local convenience.

To exercise sign-in locally, serve the app over HTTPS with a locally-trusted certificate, mkcert being the simplest way:

mkcert -install
mkcert localhost

Then run next dev behind a TLS-terminating proxy pointed at it, and set APP_ORIGIN to the https:// URL you're serving from so the OAuth redirect URI matches. Everything that doesn't touch sign-in, name validation, schema checks, the blocklist, the record UI, works over plain http://localhost without any of this. See .env.example for every variable the app reads.

Star the registry

Every name claimed here is one commit in this repo, authored under the claimant's own GitHub account. If you have a name, you're already in the log — a star keeps the registry easy for the next person to find.

Contributing

Bug fixes, blocklist additions, and doc improvements are welcome. See docs/contributing.md for how to add to the blocklists, run the tests, and what CI checks.

npm install
npm test

License

The code in this repository is AGPL-3.0 licensed. It is a network service, so section 13 applies: run a modified copy and let other people use it over a network, and you owe those users your source. Using the registry, or claiming a name, carries no such obligation — this binds people who fork and host the software, not people who point a subdomain at their site.

Up to commit 3492bf7 the code was MIT, and that grant still stands for the code as it was then; see NOTICE.

The bundled profanity blocklist (data/reserved-words.json) is seeded from LDNOOBW/List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words (English list) and keeps its own CC BY 4.0 license; see data/README.md.

Credits

The idea of giving away free subdomains under one registered domain isn't new; credit to is-a.dev for the prior art, and to js.org and eu.org for more of it.


Operated by Advance Labs, which registered runs-on.dev and is the party responsible for what runs under it. See POLICY.md.

runs-on.dev (zordhalo/runs-on.dev)

Searching Database…

Что это?Бесплатный реестр субдоменов — можно за секунды занять субдомен yourname.runs-on.dev и направить его куда угодно, а сама заявка хранится файлом в этом GitHub-репозитории.
Это настоящий регистратор доменов верхнего уровня или что-то другое?Это реестр субдоменов, а не TLD: каждое занятое имя живёт под единым доменом runs-on.dev, которым оператор (Advance Labs) действительно владеет и зарегистрировал через ICANN.
Как занять своё имя?Зайдите на runs-on.dev, войдите через GitHub и введите желаемое имя; если оно свободно, занятие запишет JSON-запись в папку domains/ этого репозитория, и имя начнёт резолвиться в течение секунд.
Что нужно, чтобы иметь право занять имя?Только аккаунт GitHub: ему должно быть не меньше 30 дней, у него должен быть хотя бы один публичный репозиторий, и он ещё не должен держать имя в этом реестре.
Можно ли занять несколько имён или переименовать одно позже?Нет — строго одно имя на аккаунт GitHub, а переименование существующей записи отказывается на корню; придётся занимать совершенно новое имя.
В чём подвох лицензии AGPL-3.0?Код под AGPL-3.0, поэтому если вы форкнете и запустите изменённую копию как сетевой сервис для других людей, вы обязаны показать им исходники; само по себе занятие имени или использование публичного реестра таких обязательств не налагает.
Как занятие имени устроено на самом деле под капотом?По умолчанию одна wildcard DNS-запись направляет все возможные субдомены на один проект Vercel, так что занятие имени — это по сути просто git-коммит в domains/*.json. Когда вы направляете имя на свой хостинг, GitHub Actions workflow при мерже отправляет эту конкретную запись в DNS API Vercel, перекрывая wildcard только для этого одного имени.
Какие типы записей можно использовать для занятого имени?CNAME, A, TXT, MX или простой URL-редирект, каждый с правилами сосуществования, которые проверяет схема — например, CNAME не может соседствовать с A, TXT или MX, а URL не может сосуществовать ни с чем.
Можно ли запустить свою версию этого реестра под другим доменом?Да — форкните репозиторий, зарегистрируйте свой домен, направьте wildcard DNS-запись на своё развёртывание, создайте своё GitHub OAuth-приложение и подстройте правила зарезервированных слов и допуска под свои нужды модерации.
Почему бы просто не зарегистрировать настоящий домен верхнего уровня?Настоящий TLD требует заявки в ICANN, где одна только плата за оценку в 2026 году — $227 000, и это ещё до запуска реестра; runs-on.dev получает столь же заметный адрес примерно за $10 в год, раздавая субдомены под одним доменом, которым владеет оператор.
Creator
zordhalo
Size
5.4 MB
Stars
453
Updated
CommitOct 18
Age
1mo
Commits · 90 Days