Getting Started

Publish HTML or deploy full-stack apps in seconds.

Install the CLI

$ npm install -g @roxer/cli

Publish a static HTML page

$ roxer publish index.html Published! https://roxer.com/abc123

Deploy a full-stack app

$ roxer login $ roxer deploy . Deployed! https://my-app.roxer.com
Two URL patterns. Server apps (Node, Python) get their own subdomain: https://<app>.roxer.com. Static publishes and static-site builds (dist/, build/, plain HTML) get a path: https://roxer.com/<slug>.
Login required for apps and domains. roxer publish still works without an account on the free tier. roxer deploy and roxer domain require roxer login.

Pages (HTML Hosting)

Host static HTML pages with a single command or through the web UI. Perfect for AI-generated sites, prototypes, landing pages, and quick demos.

Web UI

Paste your HTML at roxer.com and click Publish. You get a live URL instantly.

CLI

# Publish a single file $ roxer publish index.html # Update an existing page $ roxer update abc123 index.html # Delete a page $ roxer delete abc123

Multi-file / ZIP support

Publish directories or ZIP files that contain multiple HTML, CSS, JS, and image files.

# Publish a directory (auto-zipped) $ roxer publish ./my-site/ # Publish a ZIP archive $ roxer publish project.zip

Options

FlagDescriptionExample
--password Require a password to view the page roxer publish index.html --password secret
--slug Set a custom URL slug roxer publish index.html --slug my-demo
--ttl Auto-delete after N days (7, 30, 90, or 0 for permanent) roxer publish index.html --ttl 30

API

# Publish HTML via API $ curl -X POST https://roxer.com/api/publish \ -H "X-Api-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "<h1>Hello</h1>"}'
# Publish a ZIP with entry point $ curl -X POST https://roxer.com/api/publish \ -H "X-Api-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"zip": "base64...", "entry": "index.html"}'

Apps (Full-Stack Hosting)

Deploy Node.js and Python web apps with a single command. Roxer handles the build, packaging, and hosting.

Supported Runtimes

RuntimeSupported Frameworks
Node.js 20Express, Fastify, Hono, Koa
Python 3.12Flask, FastAPI, Django

How It Works

Upload your source code, Roxer builds it server-side, then deploys to an isolated Lambda function.

Upload
roxer deploy .
Build
npm/pip install
Deploy
Lambda function
Live
roxer.com

Auto-detection

Roxer automatically detects your framework, entry point, port, and whether you need a database. No config files required.

SQLite Persistence

Every app gets persistent SQLite storage via AWS EFS. Your data survives restarts and redeployments. Just write to /mnt/data or use your standard SQLite path.

Plan Requirements

  • App hosting requires a Hosting ($19/mo) or Max ($49/mo) plan
  • App hosting requires a Hosting or Max account (free, request access)
  • Auto-sleep after 15 minutes of inactivity
  • Wakes automatically on the first incoming request (cold start: ~2 seconds)

CLI Commands

# Connect the CLI to your account (one-time) $ roxer login # Deploy the current directory (lands at https://<dir-name>.roxer.com) $ roxer deploy . # Deploy with a custom app name (lands at https://my-api.roxer.com) $ roxer deploy . --name my-api # View logs (live tail) $ roxer logs my-api # Set an environment variable $ roxer env set my-api DB_PATH=/mnt/data/app.db # Check app status $ roxer status my-api

Custom Domains

Attach your own domain to any app or page. Hosting plan required. Login required.

CLI

# Walks you through two CNAME records (validation + live) $ roxer domain add preview.acme.com --app my-app # List your domains $ roxer domain list # Show DNS setup status (and the next CNAME to add) $ roxer domain status preview.acme.com # Remove a domain $ roxer domain delete preview.acme.com

How it works

  1. You add the domain. Roxer prints a validation CNAME for ACM to issue your SSL certificate.
  2. Once that CNAME is live, ACM issues the certificate and the CloudFront distribution deploys (~5 min).
  3. Roxer prints a live CNAME pointing your domain at the distribution. Add it.
  4. When that propagates, your site is live at https://your-domain.com.
Apex domains: most registrars don't support CNAME at the apex. Use a www. subdomain, or use a registrar with ALIAS/ANAME support (Cloudflare, Route 53, DNSimple).

Prefer a UI? Use the web flow at roxer.com/domains.

CLI Reference

Complete list of all CLI commands.

Pages Commands

CommandDescriptionExample
roxer publish <file> Publish an HTML page roxer publish index.html
roxer publish <dir> Publish a directory as ZIP roxer publish ./my-site/
roxer update <id> <file> Update an existing page roxer update abc123 index.html
roxer delete <id> Delete a page roxer delete abc123
roxer stats <id> View page analytics roxer stats abc123

Apps Commands

CommandDescriptionExample
roxer deploy [path] Deploy a Node.js/Python app roxer deploy .
roxer deploy --name <n> Deploy with a custom name roxer deploy . --name my-api
roxer logs <app> View app logs (live tail) roxer logs my-api
roxer logs --no-follow Show recent logs only roxer logs my-api --no-follow
roxer env list <app> List environment variables roxer env list my-api
roxer env set <app> K=V Set an environment variable roxer env set my-api DB=sqlite
roxer env unset <app> <key> Remove an environment variable roxer env unset my-api DB
roxer status <app> Show app status roxer status my-api
roxer apps List all deployed apps roxer apps
roxer apps delete <id> Delete a deployed app roxer apps delete my-api
roxer init [template] Scaffold a new project (express, fastify, hono, flask, fastapi, react, svelte) roxer init express --name my-api

Domain Commands

CommandDescriptionExample
roxer domain add <domain> Attach a custom domain to an app or page roxer domain add preview.acme.com --app my-app
roxer domain list List all your custom domains roxer domain list
roxer domain status <domain> Show DNS setup status and next step roxer domain status preview.acme.com
roxer domain delete <domain> Remove a custom domain roxer domain delete preview.acme.com

Account Commands

CommandDescriptionExample
roxer login Connect the CLI to your Roxer account roxer login
roxer logout Disconnect the CLI (removes the local key) roxer logout
roxer account Show current plan and limits roxer account
roxer activate <token> Redeem an activation token (invite mode) roxer activate abc123...
roxer request-access Request access to a plan (invite mode) roxer request-access --plan launch

MCP Setup (Claude Code)

Use Roxer directly from Claude Code, Cursor, or any MCP-compatible AI tool. One command to set up, then just ask Claude to deploy.

Setup

Add this to ~/.claude.json under the top-level mcpServers key:

{ "mcpServers": { "roxer": { "command": "npx", "args": ["-y", "@roxer/mcp"] } } }

Verify It Works

In a new Claude Code session, run /mcp and confirm roxer appears in the list. Then just ask Claude to build and deploy.

Available Tools

ToolDescription
pages_publishPublish HTML or a ZIP as a hosted page
pages_publish_filesPublish multiple files (auto-zipped)
pages_updateUpdate an existing page
pages_deleteDelete a page
apps_deployDeploy a full-stack app (Node.js or Python)
apps_statusCheck app deployment status
apps_deleteDelete a deployed app

Usage

Just ask Claude. "Publish this HTML to Roxer," "Deploy this Express app," or "Build me a todo app and put it on Roxer." The MCP tools handle the rest.

API Reference

All endpoints require an X-Api-Key: YOUR_KEY header. Base URL: https://roxer.com/api

Pages

POST /api/publish

Publish a new HTML page.

$ curl -X POST https://roxer.com/api/publish \ -H "X-Api-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "<h1>Hello World</h1>"}' # Response { "id": "abc123", "url": "https://roxer.com/abc123", "created": "2026-04-27T10:30:00Z" }
PUT /api/pages/{id}

Update an existing page's content.

$ curl -X PUT https://roxer.com/api/pages/abc123 \ -H "X-Api-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "<h1>Updated</h1>"}' # Response { "id": "abc123", "url": "https://roxer.com/abc123", "updated": "2026-04-27T11:00:00Z" }
DELETE /api/pages/{id}

Delete a page.

$ curl -X DELETE https://roxer.com/api/pages/abc123 \ -H "X-Api-Key: YOUR_KEY" # Response { "deleted": true }
GET /api/pages/{id}/stats

Get analytics for a page.

$ curl https://roxer.com/api/pages/abc123/stats \ -H "X-Api-Key: YOUR_KEY" # Response { "id": "abc123", "views": 1423, "unique_visitors": 892, "last_viewed": "2026-04-27T14:22:00Z" }

Apps

POST /api/apps/deploy

Deploy a new app or update an existing one. Send source as a ZIP.

$ curl -X POST https://roxer.com/api/apps/deploy \ -H "X-Api-Key: YOUR_KEY" \ -F "source=@project.zip" \ -F "name=my-api" # Response { "id": "app_x7k9m2", "name": "my-api", "url": "https://roxer.com/my-api", "status": "deploying" }
GET /api/apps/{id}/status

Get the current status of an app.

$ curl https://roxer.com/api/apps/app_x7k9m2/status \ -H "X-Api-Key: YOUR_KEY" # Response { "id": "app_x7k9m2", "name": "my-api", "status": "running", "runtime": "node20", "url": "https://roxer.com/my-api", "last_deployed": "2026-04-27T10:30:00Z" }
GET /api/apps/{id}/logs

Retrieve recent logs for an app.

$ curl https://roxer.com/api/apps/app_x7k9m2/logs \ -H "X-Api-Key: YOUR_KEY" # Response { "logs": [ { "ts": "2026-04-27T10:30:01Z", "msg": "Server listening on port 3000" }, { "ts": "2026-04-27T10:30:05Z", "msg": "GET / 200 12ms" } ] }
GET /api/apps/{id}/env

List all environment variables for an app.

$ curl https://roxer.com/api/apps/app_x7k9m2/env \ -H "X-Api-Key: YOUR_KEY" # Response { "env": { "DB_PATH": "/mnt/data/app.db", "NODE_ENV": "production" } }
PUT /api/apps/{id}/env

Set one or more environment variables.

$ curl -X PUT https://roxer.com/api/apps/app_x7k9m2/env \ -H "X-Api-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"DB_PATH": "/mnt/data/app.db"}' # Response { "updated": true }
DELETE /api/apps/{id}/env/{key}

Remove an environment variable.

$ curl -X DELETE https://roxer.com/api/apps/app_x7k9m2/env/DB_PATH \ -H "X-Api-Key: YOUR_KEY" # Response { "deleted": true }
DELETE /api/apps/{id}

Delete an app and all its data.

$ curl -X DELETE https://roxer.com/api/apps/app_x7k9m2 \ -H "X-Api-Key: YOUR_KEY" # Response { "deleted": true }

Auth & Billing

POST /api/checkout

Create a Stripe checkout session to upgrade your plan.

$ curl -X POST https://roxer.com/api/checkout \ -H "X-Api-Key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"plan": "pro"}' # Response { "checkout_url": "https://checkout.stripe.com/c/pay_..." }
POST /api/auth/api-key

Generate or rotate your API key.

$ curl -X POST https://roxer.com/api/auth/api-key \ -H "X-Api-Key: YOUR_KEY" # Response { "api_key": "rxr_live_abc123..." }
GET /api/auth/plan

Get your current plan and usage.

$ curl https://roxer.com/api/auth/plan \ -H "X-Api-Key: YOUR_KEY" # Response { "plan": "pro", "pages_today": 42, "pages_limit": 1000, "apps_count": 3, "apps_limit": 10 }

Pricing

Simple, transparent pricing. Start free, upgrade when you need more.

Free plans. Request access to unlock Hosting and Max.

Quick Sharing Hosting (invite only, free) Max (invite only, free)
Pages per hour 20 1,000 1,000
Page size 2 MB 10 MB 10 MB
Apps No 5 100
Page lifetime 30 days Permanent Permanent
Custom domains No Yes Yes
Roxer branding Yes Removed Removed
SQLite persistence No Yes Yes
View Pricing & Upgrade
Request Access (free)

Architecture

Roxer is built entirely on AWS. Every component is managed, serverless, and scales automatically.

Lambda (compute)
📦 S3 (storage)
🌐 CloudFront (CDN)
📊 DynamoDB (metadata)
📁 EFS (SQLite persistence)
🔗 API Gateway (routing)

Isolation Model

Each deployed app runs in its own Lambda function. No shared processes, no shared memory. One app cannot affect another.

Build Pipeline

Server-side builds run in a sandboxed builder Lambda. Dependencies install with npm install --ignore-scripts (Node.js) or pip install (Python) in a clean environment. Build artifacts are packaged and deployed to the app's Lambda function.

Built on AWS. Not a weekend project. Production-grade infrastructure from day one. The same services that run Netflix, Airbnb, and Stripe.