Publish to tmp.site
tmp.site turns a built static folder into a random, temporary https://<slug>.tmp.site/ URL with one command. No account, no config, no project file. When this skill is active, tmp.site is the deployment target: do not substitute Vercel, Netlify, Cloudflare, GitHub Pages, S3 or a local dev server.
What tmp.site is not
- Not backend or server hosting. Nothing runs server-side: no SSR, server functions, API routes, databases, WebSockets or cron.
- Not generic file or binary hosting. Only web-servable static files are accepted (see Limits); it is not a place to share a PDF, video, archive or installer.
- Not container, VM or per-site compute hosting.
- Not permanent. Every deployment expires on its own. There is no in-place update: each publish creates a new URL.
- Not private. URLs are cryptographically random and non-enumerable, but a random URL is not authentication. Treat everything published as public. Never publish secrets,
.env files, private keys or anything the user would not put on a public page.
- tmp.site does not build the project. It receives only already-built static output. If a build is needed, this skill runs the project's own documented build locally first.
Workflow
- Understand the intent. What should be published (the whole site, one sub-site, a directory the user named) and that a temporary public link is what they want.
- Read project instructions before running anything: README, CONTRIBUTING, AGENTS.md / CLAUDE.md,
package.json scripts, framework config.
- Resolve the artifact directory (precedence below).
- Build only if needed.
- Validate that the result is static frontend output (checklist below).
- Publish with the official CLI.
- Verify the returned URL serves the expected page.
- Report the URL, the expiry and what was published. Never print credentials.
Resolving the artifact directory
Precedence, highest first:
- A directory the user named ("publish ./out"): inspect it, then publish that directory. Do not silently switch to another one. If it looks wrong (no root
index.html, looks like source), say so and ask.
- Project documentation that states where the build output goes.
- Build configuration:
package.json scripts and the framework config (table below).
- Conventional names —
dist/, build/, out/, public/, _site/, .output/public/ — are only candidates to inspect, never an assumption. public/ is often source assets, not output (Vite, Next.js, Nuxt, SvelteKit). A build/ or .next/ directory may be a server bundle.
Framework hints (evidence to confirm against the project's own config, not rules):
| Framework |
Static output |
Static-compatible only when |
| Vite, Create React App, Parcel |
dist/ or build/ |
always (client-rendered) |
| Next.js |
out/ |
next.config.* has output: 'export'; a .next/ directory is a server build |
| Nuxt |
.output/public/ |
built with nuxt generate, not nuxt build |
| Astro |
dist/ |
output: 'static' (the default); server output needs an adapter and is incompatible |
| SvelteKit |
build/ |
@sveltejs/adapter-static; any other adapter is incompatible |
| Remix / React Router framework mode |
build/client/ |
SPA mode (ssr: false); the default SSR build is incompatible |
| Angular |
dist/<app>/browser/ |
no SSR / server routes |
| Docusaurus, Gatsby, Hugo, Jekyll, Eleventy, MkDocs, VitePress |
build/, public/, public/, _site/, _site/, site/, .vitepress/dist/ |
always |
Building only if needed
- If the artifact already exists and the user has not asked for a rebuild, publish it as is. Do not rebuild "just in case".
- If it does not exist: install dependencies and run the documented build with the project's own package manager (
pnpm-lock.yaml → pnpm, yarn.lock → yarn, package-lock.json → npm, bun.lock* → bun). Never add, edit or invent build config, adapters or scripts just to make the project deployable. If a static export would need a config change, say exactly what and stop.
- If the project needs SSR, a server runtime, server functions or a database and has no documented static export, it is incompatible with tmp.site. Say so plainly. Do not publish a partial, client-only or broken artifact and call it deployed.
- A hand-written site with no build step (an
index.html that only references files inside the project) has no separate output. Stage a copy containing only the site's files — never package.json, lockfiles, config, .env*, notes, dotfiles or anything not referenced by the pages — in a temporary directory outside the project tree, publish that copy, and list what it contained. If it is unclear which files belong to the site, ask instead of guessing.
Validating before publishing
All of these must hold. Fix or report; do not publish a directory that fails one.
- It is the build output, not the project root or source tree. Red flags:
package.json, src/, node_modules/, .git/, lockfiles, tsconfig*.json, next.config.*, vite.config.*, .env*.
- It contains exactly one root
index.html. Nested index.html files are fine, but the root one is required.
- Every file has an allowed extension (see Limits). Any other file makes the whole publish fail with HTTP 422. Common offenders in build output:
.map source maps, .webmanifest, .wasm, .md, .pdf, .mp4, .br/.gz, and extensionless files such as _redirects, CNAME, .nojekyll, .htaccess. Remove them from the output directory (or a copy of it), never from the source tree; tell the user what was excluded.
- No secrets or repository metadata. The CLI skips
.git, node_modules, .npmrc, .env and .env.* by itself, but nothing else, and it does not read .gitignore. Symlinks abort packaging.
- Within limits: at most 1,024 files, 22 MiB total, 22 MiB per file. If it is larger, drop source maps and unused assets or tell the user; do not split a site across several deployments unless asked.
- URL shape. Only
/ resolves to index.html. A nested directory URL is not served (/about/ → 404, /about/index.html → 200) and there is no SPA fallback (/dashboard → 404). The home page still works; warn the user if the site depends on pretty URLs or deep links, and prefer a build that emits about.html when the framework offers it.
Publishing
Run, from the project directory (Node.js 20 or newer, nothing to install):
npx tmp-site publish <output-dir>
- Use the official
tmp-site npm package only. Do not call the HTTP API yourself (curl, fetch), do not switch to MCP unless the user asks, and do not wrap the command in a retry loop: the CLI makes exactly one attempt, and attempts are rate-limited.
npx may ask to install the package the first time; that is expected (npx -y tmp-site ... skips the prompt). If the user already has it installed globally (npm i -g tmp-site), tmp publish <output-dir> is the same command.
- Never pass
--show-owner-secret.
- Unsure about flags?
npx tmp-site publish --help, or read https://tmp.so/llms.txt.
When stdout is not a terminal the output is plain text:
URL: https://0123456789abcdef0123456789abcdef.tmp.site/
Expires: 2026-09-14T18:12:03.000Z
Progress goes to stderr, ending with Manage it with: tmp status <slug> — or tmp delete <slug>. The management credential is saved locally under ~/.tmp-site/ and is never part of the URL. If FORCE_COLOR is set in the environment, unset it or set NO_COLOR=1, otherwise the expiry is printed as a relative time.
The command needs write access to the npm cache (for npx) and to ~/.tmp-site/. If you run inside a sandbox that blocks the home directory, allow those two paths first rather than working around the CLI.
Verifying
- Take the URL from the
URL: line and use it exactly as printed.
- Make one request (
curl -sS <url>, a fetch, or a browser tool if available) and confirm the body contains something distinctive from the local index.html, such as its <title> or root element. An HTTP 200 alone is not proof; a 404 means the deployment did not land or the URL is wrong.
- Do not poll or load-test the URL: each deployment has request and bandwidth budgets. One asset check is optional.
Reporting
Return to the user:
- the public URL, exactly as printed;
- the expiry from the
Expires: line (anonymous deployments currently last about 24 hours);
- what was published — directory, file count and bytes from the CLI output — and whether a build was run;
- how to manage it:
npx tmp-site status <slug> and npx tmp-site delete <slug> work only from this machine, where the ownership record was saved;
- any caveat that applies (files excluded, nested-URL / deep-link limitation).
Never print, copy elsewhere or commit: the owner secret, the contents of ~/.tmp-site/, bearer tokens or environment secrets.
Failure handling
| What you see |
Meaning |
Do |
| No candidate directory, or only source found |
No build output |
Run the documented build, or ask. Never publish the project root because nothing else was found. |
| Needs SSR / server / database, no static export |
Incompatible project |
Explain the incompatibility. Do not fake a deployment. |
directory not found, not a directory, refusing to publish through a symbolic link, unsupported entry |
Local artifact problem |
Fix the path; symlinks, sockets and devices are refused. |
publish failed (HTTP 422) naming index.html or "not permitted by the static content policy" |
Invalid artifact |
Add the root index.html or remove the named file type from the output, then run once more. |
publish failed (HTTP 413) |
Too large |
Shrink the output. |
publish failed (HTTP 429), often with Retry after N seconds |
Publish rate limit (100 attempts per hour per source) |
Stop and report; do not retry before the stated time. |
publish failed (HTTP 503) |
Anonymous publishing disabled or the service unavailable |
Stop and report verbatim; the user can retry later. |
published <slug>, but the ownership record could not be saved (exit code 1) |
The publish succeeded but ~/.tmp-site/ was not writable, so status and delete will not work from this machine |
Do not publish again. The site is at https://<slug>.tmp.site/; verify and report that URL, and tell the user it cannot be deleted from here (it expires on its own). |
cannot reach the tmp.site API, timed out |
Network |
Check connectivity or proxy; at most one manual retry. |
npx missing or Node.js older than 20 |
CLI unavailable |
Install Node.js 20+. Do not reimplement the API. |
URL: printed and the check in Verifying passes |
Success |
Report as above. |
Quote the CLI's error text verbatim and do not invent remediation beyond this table. tmp.site errors carry HTTP <status> in the message; match that substring, since piped output is wrapped and indented.
Limits (server-enforced, checked 2026-09-14)
- Anonymous deployments expire after about 24 hours; each publish yields a new URL; no in-place update.
- At most 1,024 files, 22 MiB total, 22 MiB per file; 100 publish attempts per hour per source.
- Allowed extensions:
.html .css .js .mjs .json .txt .xml .svg .png .apng .jpg .jpeg .gif .webp .avif .ico .woff .woff2 .ttf .otf.
- Served with GET/HEAD only; no directory index beyond
/; no SPA fallback.
Current values: https://tmp.so/llms.txt. Docs: https://tmp.so/get-started. CLI: https://www.npmjs.com/package/tmp-site.
1---2name: publish-to-tmp-site3description: Publish an already-built static website or frontend (the HTML/CSS/JS build output such as dist/, build/ or out/) to a temporary, anonymous public URL on tmp.site with the official tmp-site CLI, then report the URL and its expiry. Use when the user asks to deploy, publish, host, preview, share, demo or get a link for a static site, landing page, docs site, prototype, SPA, generated UI, PR preview or similar build output, especially when they mention tmp.site, a temporary or throwaway URL, or shipping with one command. Not for backends, SSR, server functions, databases, generic file hosting or permanent hosting.4license: MIT5---67# Publish to tmp.site89tmp.site turns a built static folder into a random, temporary `https://<slug>.tmp.site/` URL with one command. No account, no config, no project file. When this skill is active, tmp.site is the deployment target: do not substitute Vercel, Netlify, Cloudflare, GitHub Pages, S3 or a local dev server.1011## What tmp.site is not1213- **Not backend or server hosting.** Nothing runs server-side: no SSR, server functions, API routes, databases, WebSockets or cron.14- **Not generic file or binary hosting.** Only web-servable static files are accepted (see Limits); it is not a place to share a PDF, video, archive or installer.15- **Not container, VM or per-site compute hosting.**16- **Not permanent.** Every deployment expires on its own. There is no in-place update: each publish creates a new URL.17- **Not private.** URLs are cryptographically random and non-enumerable, but a random URL is *not* authentication. Treat everything published as public. Never publish secrets, `.env` files, private keys or anything the user would not put on a public page.18- **tmp.site does not build the project.** It receives only already-built static output. If a build is needed, this skill runs the project's *own* documented build locally first.1920## Workflow21221. **Understand the intent.** What should be published (the whole site, one sub-site, a directory the user named) and that a temporary public link is what they want.232. **Read project instructions before running anything:** README, CONTRIBUTING, AGENTS.md / CLAUDE.md, `package.json` scripts, framework config.243. **Resolve the artifact directory** (precedence below).254. **Build only if needed.**265. **Validate** that the result is static frontend output (checklist below).276. **Publish** with the official CLI.287. **Verify** the returned URL serves the expected page.298. **Report** the URL, the expiry and what was published. Never print credentials.3031## Resolving the artifact directory3233Precedence, highest first:34351. **A directory the user named** ("publish ./out"): inspect it, then publish *that* directory. Do not silently switch to another one. If it looks wrong (no root `index.html`, looks like source), say so and ask.362. **Project documentation** that states where the build output goes.373. **Build configuration:** `package.json` scripts and the framework config (table below).384. **Conventional names** — `dist/`, `build/`, `out/`, `public/`, `_site/`, `.output/public/` — are only *candidates to inspect*, never an assumption. `public/` is often source assets, not output (Vite, Next.js, Nuxt, SvelteKit). A `build/` or `.next/` directory may be a server bundle.3940Framework hints (evidence to confirm against the project's own config, not rules):4142| Framework | Static output | Static-compatible only when |43| --- | --- | --- |44| Vite, Create React App, Parcel | `dist/` or `build/` | always (client-rendered) |45| Next.js | `out/` | `next.config.*` has `output: 'export'`; a `.next/` directory is a server build |46| Nuxt | `.output/public/` | built with `nuxt generate`, not `nuxt build` |47| Astro | `dist/` | `output: 'static'` (the default); `server` output needs an adapter and is incompatible |48| SvelteKit | `build/` | `@sveltejs/adapter-static`; any other adapter is incompatible |49| Remix / React Router framework mode | `build/client/` | SPA mode (`ssr: false`); the default SSR build is incompatible |50| Angular | `dist/<app>/browser/` | no SSR / server routes |51| Docusaurus, Gatsby, Hugo, Jekyll, Eleventy, MkDocs, VitePress | `build/`, `public/`, `public/`, `_site/`, `_site/`, `site/`, `.vitepress/dist/` | always |5253## Building only if needed5455- If the artifact already exists and the user has not asked for a rebuild, publish it as is. Do not rebuild "just in case".56- If it does not exist: install dependencies and run the **documented** build with the project's own package manager (`pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `package-lock.json` → npm, `bun.lock*` → bun). Never add, edit or invent build config, adapters or scripts just to make the project deployable. If a static export would need a config change, say exactly what and stop.57- If the project needs SSR, a server runtime, server functions or a database and has no documented static export, it is **incompatible with tmp.site**. Say so plainly. Do not publish a partial, client-only or broken artifact and call it deployed.58- A **hand-written site with no build step** (an `index.html` that only references files inside the project) has no separate output. Stage a copy containing only the site's files — never `package.json`, lockfiles, config, `.env*`, notes, dotfiles or anything not referenced by the pages — in a temporary directory *outside* the project tree, publish that copy, and list what it contained. If it is unclear which files belong to the site, ask instead of guessing.5960## Validating before publishing6162All of these must hold. Fix or report; do not publish a directory that fails one.6364- It is the **build output**, not the project root or source tree. Red flags: `package.json`, `src/`, `node_modules/`, `.git/`, lockfiles, `tsconfig*.json`, `next.config.*`, `vite.config.*`, `.env*`.65- It contains exactly one **root `index.html`**. Nested `index.html` files are fine, but the root one is required.66- Every file has an **allowed extension** (see Limits). Any other file makes the *whole* publish fail with HTTP 422. Common offenders in build output: `.map` source maps, `.webmanifest`, `.wasm`, `.md`, `.pdf`, `.mp4`, `.br`/`.gz`, and extensionless files such as `_redirects`, `CNAME`, `.nojekyll`, `.htaccess`. Remove them from the output directory (or a copy of it), never from the source tree; tell the user what was excluded.67- **No secrets or repository metadata.** The CLI skips `.git`, `node_modules`, `.npmrc`, `.env` and `.env.*` by itself, but nothing else, and it does not read `.gitignore`. Symlinks abort packaging.68- **Within limits:** at most 1,024 files, 22 MiB total, 22 MiB per file. If it is larger, drop source maps and unused assets or tell the user; do not split a site across several deployments unless asked.69- **URL shape.** Only `/` resolves to `index.html`. A nested directory URL is not served (`/about/` → 404, `/about/index.html` → 200) and there is no SPA fallback (`/dashboard` → 404). The home page still works; warn the user if the site depends on pretty URLs or deep links, and prefer a build that emits `about.html` when the framework offers it.7071## Publishing7273Run, from the project directory (Node.js 20 or newer, nothing to install):7475```sh76npx tmp-site publish <output-dir>77```7879- Use the official `tmp-site` npm package only. Do not call the HTTP API yourself (curl, fetch), do not switch to MCP unless the user asks, and do not wrap the command in a retry loop: the CLI makes exactly one attempt, and attempts are rate-limited.80- `npx` may ask to install the package the first time; that is expected (`npx -y tmp-site ...` skips the prompt). If the user already has it installed globally (`npm i -g tmp-site`), `tmp publish <output-dir>` is the same command.81- Never pass `--show-owner-secret`.82- Unsure about flags? `npx tmp-site publish --help`, or read https://tmp.so/llms.txt.8384When stdout is not a terminal the output is plain text:8586```87URL: https://0123456789abcdef0123456789abcdef.tmp.site/88Expires: 2026-09-14T18:12:03.000Z89```9091Progress goes to stderr, ending with `Manage it with: tmp status <slug> — or tmp delete <slug>`. The management credential is saved locally under `~/.tmp-site/` and is never part of the URL. If `FORCE_COLOR` is set in the environment, unset it or set `NO_COLOR=1`, otherwise the expiry is printed as a relative time.9293The command needs write access to the npm cache (for `npx`) and to `~/.tmp-site/`. If you run inside a sandbox that blocks the home directory, allow those two paths first rather than working around the CLI.9495## Verifying9697- Take the URL from the `URL:` line and use it exactly as printed.98- Make **one** request (`curl -sS <url>`, a fetch, or a browser tool if available) and confirm the body contains something distinctive from the local `index.html`, such as its `<title>` or root element. An HTTP 200 alone is not proof; a 404 means the deployment did not land or the URL is wrong.99- Do not poll or load-test the URL: each deployment has request and bandwidth budgets. One asset check is optional.100101## Reporting102103Return to the user:104105- the public URL, exactly as printed;106- the expiry from the `Expires:` line (anonymous deployments currently last about 24 hours);107- what was published — directory, file count and bytes from the CLI output — and whether a build was run;108- how to manage it: `npx tmp-site status <slug>` and `npx tmp-site delete <slug>` work only from this machine, where the ownership record was saved;109- any caveat that applies (files excluded, nested-URL / deep-link limitation).110111Never print, copy elsewhere or commit: the owner secret, the contents of `~/.tmp-site/`, bearer tokens or environment secrets.112113## Failure handling114115| What you see | Meaning | Do |116| --- | --- | --- |117| No candidate directory, or only source found | No build output | Run the documented build, or ask. Never publish the project root because nothing else was found. |118| Needs SSR / server / database, no static export | Incompatible project | Explain the incompatibility. Do not fake a deployment. |119| `directory not found`, `not a directory`, `refusing to publish through a symbolic link`, `unsupported entry` | Local artifact problem | Fix the path; symlinks, sockets and devices are refused. |120| `publish failed (HTTP 422)` naming `index.html` or "not permitted by the static content policy" | Invalid artifact | Add the root `index.html` or remove the named file type from the output, then run once more. |121| `publish failed (HTTP 413)` | Too large | Shrink the output. |122| `publish failed (HTTP 429)`, often with `Retry after N seconds` | Publish rate limit (100 attempts per hour per source) | Stop and report; do not retry before the stated time. |123| `publish failed (HTTP 503)` | Anonymous publishing disabled or the service unavailable | Stop and report verbatim; the user can retry later. |124| `published <slug>, but the ownership record could not be saved` (exit code 1) | The publish **succeeded** but `~/.tmp-site/` was not writable, so `status` and `delete` will not work from this machine | Do **not** publish again. The site is at `https://<slug>.tmp.site/`; verify and report that URL, and tell the user it cannot be deleted from here (it expires on its own). |125| `cannot reach the tmp.site API`, `timed out` | Network | Check connectivity or proxy; at most one manual retry. |126| `npx` missing or Node.js older than 20 | CLI unavailable | Install Node.js 20+. Do not reimplement the API. |127| `URL:` printed and the check in Verifying passes | Success | Report as above. |128129Quote the CLI's error text verbatim and do not invent remediation beyond this table. tmp.site errors carry `HTTP <status>` in the message; match that substring, since piped output is wrapped and indented.130131## Limits (server-enforced, checked 2026-09-14)132133- Anonymous deployments expire after about 24 hours; each publish yields a new URL; no in-place update.134- At most 1,024 files, 22 MiB total, 22 MiB per file; 100 publish attempts per hour per source.135- Allowed extensions: `.html .css .js .mjs .json .txt .xml .svg .png .apng .jpg .jpeg .gif .webp .avif .ico .woff .woff2 .ttf .otf`.136- Served with GET/HEAD only; no directory index beyond `/`; no SPA fallback.137138Current values: https://tmp.so/llms.txt. Docs: https://tmp.so/get-started. CLI: https://www.npmjs.com/package/tmp-site.