paste-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev 01fdb2b1f66e
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 6eca480d6447d873e2e5eed9
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
AGENTS.md
# Paste

Paste shares text, code and logs by link, and is a free alternative to Pastebin, GitHub Gist for quick shares, and paid snippet tools. It is an OpenApp in the OpenApps free apps store (https://free-apps.openapps.xyz/), owned by the OpenApps team.

## What it promises

- Free, with no limit on pastes, no ads and no paid tier. Never add a cap, an upsell or tracking.
- No sign-up. Every visitor who makes a paste is a guest account created in the browser. Reading a paste needs no account at all.
- Every paste is unlisted: anyone with the link can read it, and nobody can list, browse or search pastes. Ids are 12 random characters from an alphabet without look-alikes.
- Expiry (10 minutes up to a year, or never) is enforced by the data rules: past its expiry nobody can read a paste, not even its owner.
- Burn after reading means exactly one reader gets the paste, then it is deleted.
- A locked paste is encrypted in the browser with AES-GCM, two ways: with a random key in the link's #fragment, or with a password (PBKDF2, 600,000 rounds; the stored text starts with `pw1.`). The server only ever holds ciphertext, so a lost link or password means a lost paste. Never add anything that sends the fragment or the password to a server, and never store the password.
- Rendered Markdown never loads anything from another site: raw HTML is cleaned and images become links.
- AI assistants can do everything a person can, except encrypting, through the public API (`functions/api.ts`): JSON, or a file sent as it is with content-type text/plain. It is documented in `public/llms.txt` and `public/openapi.json`; `public/index.md` is the landing page in Markdown. Keep all three true whenever the API changes.

## How it is built

- `index.html` is the static landing page that search engines and AI crawlers read. Keep its copy, FAQ and JSON-LD in sync with what the app does. The inline script at the top of `<head>` hides the landing on paste routes; its pattern must match `ROUTE` in `src/main.tsx`.
- `src/` is the React app. `/` mounts the editor into the hero and "Your pastes" (from localStorage) below it. `/<id>` is the paste page (`#L<n>` marks a line, except on pastes whose link carries a key), `/<id>/admin#k=<owner key>` (plus `&e=<key>` for pastes with a key in the link) is the admin page, and `/<id>/raw` hands over to the API's plain text.
- The paste page reads through the public API (`GET /pastes/<id>?peek=1`), so it never loads the Bounded SDK. The SDK (`src/lib/store.ts`) loads only when someone makes or manages a paste. highlight.js (one language at a time) and marked with DOMPurify load only when needed.
- `functions/lib/paste.ts` holds ids, owner keys, size and expiry limits, the language list and the small language detector, shared by the app and the API.
- `functions/lib/config.ts` holds the app id, the site address (`SITE_URL`) and the API base.
- `policy.json` holds the data rules, and `policy-tests/pastes.json` checks them (`bounded tests run --app-id <app id>`). `pastes/<id>` is readable only by its owners and by the public `api` function, and by nobody once `createdAt + ttl` has passed. Owners are the creator, or anyone who presents the owner key (`pastekeys/<id>`, readable only by the API) through `pasteclaims`. The API may mark a burn paste `opened` once (the rule refuses a second time), then delete it.
- Size: pastes hold up to 512 KB. The web app writes through the SDK; the API's request body is capped at 128 KiB by the platform. The rules allow up to 720,000 characters so encrypted pastes (base64) fit.

## Working on it

`npm install && npm run build` typechecks and builds `dist/`. Ship changes through previews and releases as your runtime instructions describe; the app is an OpenApp, so nobody deploys it directly. A change to anything in `functions/lib` needs the functions redeployed as well as the site.

Check a change by making a paste of each kind in the web app (plain, expiring, burn after reading, password, key in the link, Markdown), opening its link in a fresh browser, using Copy, Download, Copy link, the line links and the More menu (raw text, edit a copy, print), editing and deleting it from the admin link on another browser, and calling every API route with curl (JSON and text/plain bodies), including a wrong owner key.

## Voice

Plain words, short sentences, no jargon, no em dashes. Say what happens, not how clever it is.

Change history

Quality pass: password lock, year expiry, line links, text/plain API
01fdb2b1f6 · 4 hours ago
Bounded source sync
fe5788c2d2 · 1 day ago
Bounded source sync
ac6f7dbc95 · 1 day ago
Bounded source sync
0a45926293 · 1 day ago