Documentation
FluentOps takes a web app — a static front-end, a real backend, or something that renders its own pages — from your machine to a public URL with HTTPS. You never touch infrastructure. Every project gets your-project.fluentops.org, and your own domain whenever you want it.
How do you want to publish?
The three end the same way: your app on a public URL with HTTPS, free. Pick whichever is closest to hand.
- 1Create a project
In the dashboard, give it a name. That name becomes your URL.
- 2Drop your folder
Drag the project folder (or a
.zip) onto the deploy panel. Leavenode_modules,.gitand build output in — we skip them for you. Max 50 MB. - 3Watch it build
The build runs in the cloud and the log streams live. Your URL appears when it finishes. To update, drop again — it replaces the previous version at the same address.
- 1Choose Deploy from Git
In your project, pick Deploy from Git.
- 2Connect GitHub once
One click, and only for private repositories — public ones work without it.
- 3Paste the URL and deploy
We clone, install, build and publish. Deploy again anytime to pull the latest commit.
Copy this and paste it into Claude Code, Codex or Cursor. It installs the CLI, pauses for you to log in, and deploys.
Set up FluentOps — one-command hosting for AI-built web apps — and deploy this app. 1. Install the CLI if `fluentops version` fails: fetch and run https://fluentops.org/install.sh (curl, wget, or whatever download tool you have). 2. If `fluentops whoami` says I'm not signed in: run `fluentops login --device --no-wait --json`, show me the url and user_code so I can approve it, then run `fluentops login --resume`. 3. Run `fluentops init` so this repo keeps the deploy instructions (AGENTS.md). 4. From the app's directory run `fluentops deploy --json` and give me the live URL. If it comes back with warnings or an error, follow AGENTS.md: fix what you can, ask me for any secret values (never invent them), and deploy again. Reference for agents: https://fluentops.org/llms.txt
- 1Install
One command — it detects your platform and puts the binary on your PATH.
curl -fsSL https://fluentops.org/install.sh | bash - 2Log in
loginopens your browser and stores the token securely (macOS Keychain, or an encrypted file).fluentops login - 3Deploy
From your project directory:
cd my-app fluentops deployThe first run creates the project and writes
.fluentops/project.json, so later deploys reuse it without asking.
Once it is live
Everything else you can add, in the order people usually need it.
Environment variables
Add secrets under Project → Secrets (or fluentops secrets add KEY=VALUE). They're encrypted at rest and injected both at build time and into your backend at runtime, so code like process.env.OPENAI_API_KEY (or os.environ) just works.
- Prefix a variable with
VITE_to expose it to the browser bundle (safe for public keys/URLs). - Keep service-role and secret keys unprefixed — they stay server-side, and reach your backend at runtime.
- Connect a service lists the exact variables for Supabase, OpenAI, Stripe, Firebase and more.
Custom domains
Under Project → Domains, add your domain (e.g. www.mycompany.com). FluentOps issues a free certificate and shows the exact DNS records to add, in two steps:
- Verify ownership — add the CNAME validation record (one-time; auto-renewals reuse it).
- Point your domain — add the routing record at your DNS provider.
For a root/apex domain: if your DNS supports it (Cloudflare, Route 53…) you add the record at @ directly. If your registrar can't (e.g. Namecheap), connect www and add an Unmasked 301 redirect from the root — the UI detects this and shows the right records. HTTPS is provisioned and renewed automatically once DNS resolves.
Forms
FluentOps Forms turns a plain <form> on your static site into working lead capture — no backend, no code. Submissions land in your project’s inbox and email you instantly. It’s free (100 submissions/month per account). See the Forms overview.
1 · Enable it
In your project, open the Grow tab and click Enable forms. You get a unique endpoint URL for that project.
2 · Deploy again
Enabling doesn’t change the site that’s already live. On your next deploy we connect every <form> in your HTML that has no destination of its own (no action, #, a .php, or a Netlify form). Search boxes, logins and forms you pointed at another service are left alone. The panel tells you which forms it connected.
Writing the form yourself
<form action="https://api.fluentops.org/forms/<token>" method="POST">
<input name="email" />
<textarea name="message"></textarea>
<input type="text" name="_gotcha" style="display:none" tabindex="-1" />
<button>Send</button>
</form>Any field names work — they all arrive in your inbox. The hidden _gotcha field is a honeypot: a bot that fills it is kept marked as spam and doesn’t email you.
React, Vite, Bolt, Lovable (JavaScript apps)
In a JavaScript app the form is drawn by code, so a deploy can’t connect it. Send it with fetch — JSON or form data both work — or paste the prompt the panel gives you into your AI tool:
const res = await fetch('https://api.fluentops.org/forms/<token>', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...form, 'form-name': 'contact' }),
})
if (res.ok) { /* show your thank-you message */ }Optional fields
_redirect(or_next) — send the visitor to a thank-you page after submitting; without it they get a small JSON response.form-name(or_form) — label submissions when a project has more than one form.
Free includes 100 submissions/month across all your sites, kept 30 days. Pro raises it to 1,000/month with CSV export and unlimited retention. Over the limit, leads are still captured — we never drop one.
Backends & APIs
FluentOps runs a real backend for your app — an actual process in a container, not a serverless function. It keeps in-memory state, holds WebSocket connections, and connects to your database normally.
Zero config — we detect your stack
You don't write a Dockerfile. Just like the front-end, we read your project's files and build the image for you. Deploy the same way (CLI, drag & drop, or Git); if we find a server, we deploy it alongside your front-end in one step.
Where it lives
Deployed on its own, your backend answers every path at your project's URL — whatever routes you wrote, wherever you mounted them. Nothing else is competing for /, so we don't take it from you:
https://your-project.fluentops.org/usersWith a front-end alongside it, the front-end owns / and your backend answers under /api/* — one hostname, no CORS setup. Mount those routes under /api: in Express, app.use('/api', router); in FastAPI, @app.get("/api/...") (or an APIRouter with prefix="/api"). A request to /api/users arrives at your server as /api/users.
/api/* keeps working either way, so a URL you already wired up doesn't break. Your project's secrets are injected as environment variables at runtime, so process.env / os.environ just works.
Front + back in one project (monorepos)
Have your front-end and backend in one repo (say web/ and api/)? Deploy it as-is — we scan your folders, find both, and deploy them together: the front-end at /, the API at /api/*. You can also choose to deploy just one. If we find more than one front-end or more than one backend, we ask you which to deploy.
Apps that render their own pages
If your app renders its pages on the server — Next.js SSR, Nuxt, SvelteKit, Astro, Remix, Django, Rails, or an Express/Flask app with templates — deploy it as-is. We detect it, build it, and your app owns every route at /, not just /api/*. No output: "export", no splitting it in two, no changes to your code.
The trade-off is worth knowing: a static front-end is served from the CDN and stays up even while a Free backend naps, whereas a server-rendered app builds each page in your container. If your site is content that doesn't change per visitor, a static build is still faster and cheaper — but that's your call to make, not a limit we impose.
Databases: FluentOps doesn't host your database — point your backend at a managed provider (Supabase, Neon, PlanetScale…) via a secret. See Databases.
Run modes
Every backend is one artifact with a run mode you pick on the project page (next to Secrets). Change it anytime — no re-deploy.
- Always on — a service that keeps listening (an API, a web server). On Free it sleeps after a few minutes idle and wakes on the first request (a ~1–3s cold start); on Pro it never sleeps.
- On demand — a job that runs when triggered and stops. We give you a private activation URL (
POST) and a Run now button; each run's logs and exit code are kept in history. - On a schedule — the same job on a cron schedule (UTC). Free runs at most once a day; Pro allows per-minute schedules.
Run minutes for on-demand and scheduled jobs are metered against your plan's monthly quota; when you hit it, jobs pause until next month — you're never billed for overage.
Databases
FluentOps hosts your app, not your database — the same model as Vercel. Use a managed provider and connect to it from your backend with a secret:
- Supabase / Neon — Postgres
- PlanetScale — MySQL
- Upstash — Redis
- Any host — set the connection string as a secret (e.g.
DATABASE_URL)
The dashboard's Secrets section has copy-paste recipes for the common ones, with the exact variable names each expects.
CLI reference
Commands
| Command | What it does |
|---|---|
fluentops deploy | Detect → (auto-create) → upload → build → live URL |
fluentops deploy --front web --back api | Choose which apps to deploy when the project has more than one ("none" skips a kind) |
fluentops init | Write deploy instructions for AI agents into AGENTS.md (and CLAUDE.md if present) |
fluentops logs [-f] | Latest deployment logs; -f / --follow streams |
fluentops status | Recent deployments for the linked project |
fluentops open | Open the project's live URL |
fluentops projects | List your projects |
fluentops projects delete <slug> | Delete a project and its site (irreversible; asks you to type the slug, or --confirm <slug> without a terminal) |
fluentops secrets list|add|delete | Manage env vars (add KEY=VALUE, several at once) |
fluentops login / logout / whoami | Authentication |
fluentops login --device | Sign in by approving a short code from any browser — for SSH, containers and cloud agents (automatic there) |
fluentops version | Version / build info |
Agent & JSON mode
--json emits machine-readable output and --yes never prompts — both auto-enable when output isn't a terminal, so agents and CI work with zero flags.
fluentops deploy --json --yes
# {"status":"success","project_slug":"my-app",
# "url":"https://my-app.fluentops.org",
# "warnings":[{"kind":"missing_env","items":["VITE_SUPABASE_URL"],
# "fix":"fluentops secrets add VITE_SUPABASE_URL=<value> && fluentops deploy"}]}A deploy that doesn't go live exits non-zero with "status":"error" and a stable code: needs_selection (with the options found — re-run with --front/--back), build_failed (with error and the last log lines in log_tail) or unsupported_stack. Everything an agent needs to fix it and try again, without a second command.
Ignoring files
node_modules, .git, dist, build, out and .fluentops are always skipped. Add a .fluentopsignore (gitignore syntax) to exclude more.
Supported stacks
Front-end (static hosting)
- React (CRA or any bundler with a build script)
- Vite (including React + Vite)
- Next.js static export (
output: "export") - Static HTML / CSS / JS
Apps that render their own pages (server-side)
Deployed as-is: the app owns every route at /, and we build it the way its framework expects. No output: "export", no code changes.
- Next.js (SSR / App Router — dynamic routes, middleware and route handlers included)
- Nuxt, SvelteKit, Astro (server mode), Remix
- Django —
manage.pyplus your settings module; we runcollectstaticfor you - Rails with views, and Express / Flask / FastAPI apps that render templates (EJS, Pug, Jinja, ERB…)
Backend (auto-detected, no Dockerfile needed)
- Node — Express, Fastify, Hono, Koa, NestJS, Elysia (or any server with a
startscript) - Python — FastAPI, Flask, or a plain script/worker (
job.py,main.py…) run as a job - Go — any module with a
mainpackage - Ruby — Rails, or Rack apps (Sinatra/Roda) with a
config.ru - Jobs & cron — a script that runs and exits is a job: it defaults to On demand (trigger by URL/CLI) and can be switched to On a schedule. No server, no Dockerfile.
Any other language
FluentOps builds your app from its detected stack — it doesn't run an uploaded container, so a Dockerfile in your project is ignored (we tell you when we skip one). Stacks we don't build yet — Rust, Java, PHP, Deno and others — aren't supported at the moment; tell us what you need and we'll prioritize it.
If we can't tell how to start your backend, the build fails with a clear message (e.g. "add a start script to package.json").
FAQ
How do I generate a ZIP?
Zip the project folder itself (the one with package.json or index.html). On macOS: right-click → Compress. Leave node_modules in — we skip it — and keep the upload under 50 MB.
Why did my build fail?
Open the deployment and read the logs — the last lines say exactly what happened (unsupported stack, install/build error, or missing output). Fix locally and deploy again.
How do I update my site?
Deploy again — CLI, drag & drop or Git. Every deploy replaces the previous version at the same URL.
How do I add an API or backend?
You don't do anything special — if your project has a server (Node, Python, Go, or Ruby), we detect it and build it. On its own it answers every path at your project's URL; deployed with a front-end, the front-end takes / and your API answers under /api/*. Pick its run mode on the project page.
Do you host my database?
No — connect a managed provider (Supabase, Neon, PlanetScale…) by adding its connection string as a secret. Your backend reads it from the environment.
Is it really free?
Yes — hosting, HTTPS, custom domains and a backend are free during the beta. Free backends sleep after a few minutes idle and wake on the next request; Pro keeps them always on.
Still stuck? Use Send Feedback in the dashboard — include your WhatsApp and we'll reach out.