A Small Deployment Plane for Static Sites
Yeeet takes an already-built file or folder and publishes it as an atomic HTTPS release. It combines direct-to-bucket uploads, immutable versions, a movable live alias, SPA refresh support, private review links, custom domains, automatic social cards, and edge-aware caching behind one browser workflow and one CLI.
It is intentionally focused: Yeeet serves static output and never executes an untrusted build. Run your framework's build locally or in CI, then hand Yeeet the resulting dist, build, out, or public directory.
Developers
Ship a portfolio, documentation build, prototype, or client-side app with a generated Yeeetling preview card when you do not provide one.
Review Teams
Keep immutable previews, roll back instantly, and share protected work through a revocable one-click link.
Agents & CI
Use API keys, stable JSON, predictable exit codes, LLM-readable guidance, and an OpenAPI contract.
Platform Operators
Run the complete MIT-licensed control plane on Railway with Postgres and private S3-compatible storage.
Open source and self-hostable. Read the architecture, configuration, Railway setup, contribution guide, security policy, and MIT license in the Yeeet GitHub repository.
Deploy Your First Site
Bring Node.js 20.19+ or 22.12+, a Yeeet account, and a folder containing static files. The CLI handles the manifest, parallel uploads, atomic activation, and URL.
-
Install the CLI
Install the public package once so yeeet is available from any project.
npm install --global @yeeet.dev/cli -
Log In from Your Terminal
A one-time device flow opens in your browser. Your terminal never asks for or stores your password.
yeeet login -
Point at the Output Folder
Yeeet creates a readable random subdomain when you do not specify a name.
yeeet deploy ./dist
Need an account? Yeeet is invitation-only while the platform is young. Use an invitation at yeeet.dev/login, then return to yeeet login.
Random When Quick. Named When Stable.
Skip a name for an instant throwaway URL, or choose a name when the URL should remain stable across releases. Either way, the upload becomes visible only after every file is ready.
Quick Preview
yeeet deploy ./dist
Creates a readable URL such as swift-comet-a1b2c3.site.yeeet.dev.
Stable Project URL
yeeet deploy ./dist --name comet
Creates or updates comet.site.yeeet.dev.
Single-Page App
yeeet deploy ./dist --spa
SPA refresh support is already the default. Missing client routes serve index.html; missing assets stay 404s.
Strict Static Files
yeeet deploy ./public --static
Returns 404 unless a path maps to a real file, HTML file, or directory index.
Save Project Defaults
Run yeeet init comet to create .yeeet.json. From then on, the project name and routing mode travel with the project.
yeeet init comet
yeeet deploy ./distShip Headers and Redirects With the Site
Add _headers and _redirects at the deployed root. Yeeet validates them, keeps them private, and versions them with the files, so rollback restores the complete delivery behavior.
# _headers
/assets/*
Cache-Control: public, max-age=604800
# _redirects
/old/:page /new/:page 308
/app/* /index.html 200Every Launch Is Recoverable
A named site is a movable pointer to an immutable release. List history, preview any version, or atomically make an older version live again.
yeeet versions comet
yeeet rollback comet 52eabb5f
# Or roll back to the previous ready release
yeeet rollback cometVersion commands accept a full deployment ID or an unambiguous prefix of at least 8 characters. Live aliases revalidate at the edge in about 10 seconds; immutable preview URLs never change.
See the Diff Before Takeoff
A dry run hashes the local folder and reports added, changed, removed, and unchanged paths without creating a deployment or touching storage.
yeeet deploy ./dist --name comet --dry-run
yeeet deploy ./dist --name comet --dry-run --jsonStage Without Moving Production
Channels are mutable, no-index aliases under the same wildcard certificate. A channel deploy leaves the normal production URL untouched.
yeeet deploy ./dist --name comet --channel staging
yeeet channel list comet
yeeet channel set comet staging 52eabb5f
yeeet channel remove comet stagingSee Traffic, Not Visitors
Cookie-free analytics count HTML page responses by UTC day, normalized path, and status. Yeeet never stores IP addresses, user agents, referrers, cookies, or visitor IDs, and does not pretend page views are unique people.
yeeet analytics comet --days 30
yeeet analytics comet --days 7 --jsonRemove What You No Longer Need
yeeet version remove comet 52eabb5f --yes
yeeet remove comet --yesDeletion is permanent. The --yes flag confirms removal of stored objects. If you delete the live version, Yeeet promotes the newest remaining ready version.
Protect It. Share It in One Click.
Password protect a launch, then send a signed share URL. Reviewers need no Yeeet account and do not have to type the password.
export YEEET_DEPLOY_PASSWORD="a long private password"
yeeet deploy ./dist --name review
yeeet share reviewChange access without re-uploading files. Rotating the link revokes both the previous URL and existing viewer cookies.
yeeet access protect review <version> --password "a new password"
yeeet access rotate-link review <version>
yeeet access public review <version>Bring a Custom Hostname
Attach a hostname from the CLI. Yeeet returns the routing and ownership-verification records; Railway provisions and renews TLS once DNS verifies.
yeeet domain add comet www.example.com --json
# After adding every returned DNS record
yeeet domain refresh comet www.example.com --json
yeeet domain list comet --jsonAdd every returned DNS record exactly as shown. Propagation time depends on your DNS provider. Use domain list to inspect routing, verification, and certificate status.
Predictable for Agents & CI
Create an API key in the dashboard, provide it through the environment, and request JSON. The same CLI works interactively, in CI, or as an agent tool.
export YEEET_TOKEN="yeeet_…"
yeeet whoami --json
yeeet deploy ./dist --jsonSecret handling: never print, commit, or place YEEET_TOKEN in a prompt. Inject it from your CI secret store or agent environment.
Pull Request Previews
Use nearbycoder/yeeet.dev@main in GitHub Actions. Each trusted pull request gets a stable <site>-pr-<number> URL, an updated PR comment, and cleanup when the PR closes.
- uses: nearbycoder/yeeet.dev@main
with:
token: \${{ secrets.YEEET_TOKEN }}
github-token: \${{ github.token }}
site: docs
directory: distGive an Agent Native Yeeet Tools
The first-party @yeeet.dev/mcp server exposes typed planning, deploy, rollback, channel, domain, sharing, and confirmed cleanup tools over stdio. Keep the API key in the MCP host environment.
{
"mcpServers": {
"yeeet": {
"command": "npx",
"args": ["-y", "@yeeet.dev/mcp"],
"env": { "YEEET_TOKEN": "yeeet_..." }
}
}
}Signed Deployment Events
Webhooks use a durable outbox and retry failed public HTTPS endpoints. The secret appears once. Verify HMAC-SHA256 over the timestamp and raw body, reject stale requests, and deduplicate the delivery ID.
yeeet webhook add https://example.com/yeeet \\
--events deployment.ready,deployment.activated
yeeet webhook deliveries
yeeet webhook rotate-secret <id>Start with One Plain-Text URL
/llms.txt is the concise operational contract. Use the full document for detailed behavior and OpenAPI when direct HTTP orchestration is necessary.
curl -fsSL https://docs.yeeet.dev/llms.txt- Exit 0: deployment succeeded and stdout contains the final JSON object.
- Exit 2: authentication is required; provide YEEET_TOKEN.
- Exit 1: validation, upload, or network failure; stderr explains the next action.
Command Map
Use yeeet --help or yeeet <command> --help for every option.
| Command | Purpose |
|---|---|
| login / logout / whoami | Manage the local device session and verify identity. |
| deploy|up [path] | Upload a file or folder and atomically activate the ready release. |
| sites | List live sites owned by the current account. |
| versions <site> | List immutable releases, preview URLs, status, routing mode, and privacy. |
| rollback <site> [version] | Promote an older ready release, or the previous release when omitted. |
| analytics <site> | Inspect aggregate daily views, normalized paths, and response statuses without visitor tracking. |
| version remove … | Permanently remove one release and its stored objects. |
| remove <site> | Permanently remove a site, its releases, domains, and stored objects. |
| share <site> [version] | Print the signed one-click URL for a protected release. |
| access … | Protect a release, make it public, or rotate its private link. |
| domain … | Add, list, refresh, or remove custom-domain mappings. |
| init [name] | Create a project-level .yeeet.json. |
Quick Fixes
Not Authenticated
Run yeeet whoami. Humans can repeat yeeet login; automation should verify YEEET_TOKEN is present.
Wrong Output Folder
Run your framework build, then deploy the folder that actually contains index.html, such as dist, build, or out.
SPA Refresh Returns 404
SPA fallback is the default. Check that index.html exists and remove --static or set spaFallback to true.
Custom-Domain TLS Is Pending
Add every DNS record returned by domain add, wait for propagation, then run domain refresh.