Button guide

Share a local Python app with coworkers ngrok, Cloudflare Tunnel, Tailscale or Button, compared on limits and login

To share a local Flask, Streamlit or Gradio app with colleagues, you can expose your localhost server through a tunnel like Cloudflare Tunnel, Tailscale or ngrok, or use a framework feature like Gradio share links. If you only wrote the web wrapper so colleagues could feed inputs into a Python script and download the output, Button (https://button.bitgate.dev) skips the web server and turns the script itself into a login-protected web form, with a $0 Free plan for 1 tool, 3 people and 100 runs per month (or Pro at $15/month for 50 tools and 250 people).

Tunnels and built-in sharing options

When you run a web framework on your laptop, a tunnel forwards traffic from a URL to your local port. You still have to keep the Python web server running, and you have to figure out how to keep strangers out.

Cloudflare Tunnel and Cloudflare Access

Cloudflare Tunnel (cloudflared) is free on all plans. By itself, a tunnel puts your local Flask, Streamlit or Gradio server onto the public internet, which means anyone with the link can use it. To put a login in front of the tunneled app, you pair it with Cloudflare Zero Trust (Access), which is free for up to 50 users.

Tailscale Serve and Tailscale Funnel

Tailscale gives you two ways to expose a local port, and its free Personal plan covers up to 6 users.

Tailscale Serve shares a local service only with devices on your tailnet. That solves the login problem without touching your Python code, but every colleague who wants to open your app needs Tailscale installed and signed in on their device. Tailscale Funnel exposes the local service to the public internet instead, so colleagues don't need Tailscale installed, but then you're back to needing your own login inside the app.

ngrok

ngrok Free gives you one auto-assigned dev domain and 1 GB of data transfer per month, and it shows an interstitial warning page to browser visitors before they reach your app. The cheapest paid plan (Hobbyist) is $10/month. Like a raw tunnel, it forwards traffic to your local server, so you still have to handle logins in your app or plan.

If your app is already in Gradio, launch(share=True) creates a public *.gradio.live link tunneled to your own machine. It only works while your computer and the Python process stay on.

A share link lasts at most about a week and can drop earlier. By default each event handler processes one request at a time.

For logins, launch(auth=...) accepts one username/password pair, a list of pairs, or a function. There is no invite-by-email, so you end up messaging passwords to your coworkers and rotating them in code when someone leaves.

Streamlit local network and Community Cloud

Running streamlit run app.py serves the app at a Local URL and a Network URL on your LAN IP. Anyone on the same network can open the Network URL, and there is no login by default.

If you expose a local Streamlit app over a tunnel, st.login() adds sign-in through an OpenID Connect provider such as Google or Microsoft Entra ID. It authenticates but does not authorize: you write the email allowlist check yourself with st.user.email and st.stop().

You can also move off your laptop. Streamlit Community Cloud is free and deploys apps from GitHub; you get one private app at a time, viewers are invited by email and sign in with Google or an emailed link, and apps sleep after 12 hours without traffic until the next visit.

When you only have a web app to run a script: Button

A lot of internal Flask, Streamlit and Gradio apps only exist because someone wrote a Python script and needed a way for colleagues to pass in a file or a couple of parameters without touching the terminal. If your app isn't really interactive - if people just put inputs in, wait for the script to finish and grab the output - you don't need a web framework or a tunnel at all.

Button turns a script on your own computer into a web form your colleagues can run. Any program works: Python, Node, R, PowerShell, shell scripts, compiled binaries.

Jobs still run on your computer, never in Button's cloud, while Button's servers relay the form values and files between the browser and your machine. Your computer has to be on and online, and tool pages show Ready, Busy or Offline so coworkers know if they can run a job.

Colleagues open the link from their invite email, sign in with Google or a one-time email code, fill in the form, press Run and download the results. They install nothing and never pay. Every run is logged with who ran it and when, and you can revoke access or set it to expire at any time.

The runner only executes the exact command you approved on that computer, pinned by hash, and passes every form value as its own argument with no shell; a value can't start with -. If you change a tool, people have to confirm the new version before running it.

How to share a Python script on Button

  1. Update your Python script so it takes its inputs as command-line arguments with argparse instead of web UI widgets: each input file path, plus an output folder where it writes the results:
import argparse
import pathlib

parser = argparse.ArgumentParser()
parser.add_argument("--input-file", required=True)
parser.add_argument("--threshold", type=float, required=True)
parser.add_argument("--out-dir", required=True)
args = parser.parse_args()

out_path = pathlib.Path(args.out_dir) / "result.csv"
# run your logic on args.input_file and write to out_path
  1. Sign in at button.bitgate.dev.
  2. Install the Button runner on your computer (macOS, Linux or Windows) with the one-line command the site shows you (curl on macOS and Linux, PowerShell on Windows). You get one computer (runner) per workspace on every plan, and pairing a new computer replaces the previous one.
  3. Pick your program in the local setup page and describe its inputs (text, number, yes/no, choice, files).
  4. Publish the tool and invite your colleagues. Button gives the tool its own page.

Comparison of limits, logins and pricing

Facts checked in October 2026.

Tool Cost Login and access Transfer, file and run limits
Button Free: $0 (1 tool, 3 people, 100 runs/mo). Pro: $15/mo or $144/yr ($12/mo) for 50 tools, 250 people, 5,000 runs/mo. Recipients never pay. Invite by email; colleagues sign in with Google or a one-time email code. Access can be revoked or set to expire. Free: 1 GB/mo transfer. Pro: 50 GB/mo transfer. Per run: up to 8 files, 25 MB per file, 100 MB total, 30 minutes, 1 MB logs. One run at a time per computer.
Cloudflare Tunnel + Access Tunnel (cloudflared) is free on all plans. Zero Trust (Access) is free for up to 50 users. Cloudflare Access puts a login in front of the tunneled app. Set by your own web app.
Tailscale Serve / Funnel Free Personal plan covers up to 6 users. Serve limits access to devices signed into your tailnet. Funnel exposes the port to the public internet with no login. Set by your own web app; every colleague needs Tailscale for Serve.
ngrok Free: $0. Hobbyist (cheapest paid): $10/mo. Free shows a browser interstitial warning page; you handle app login yourself in Flask, Streamlit or Gradio. Free: 1 auto-assigned dev domain, 1 GB data transfer per month.
Gradio launch(share=True) Free, open source. launch(auth=...) checks username/password pairs or a function; no invite-by-email. Link lasts at most about a week and can drop earlier; one request at a time per event handler by default.

Which tool should you pick?

Pick Cloudflare Tunnel with Cloudflare Access if you have an interactive Flask, Streamlit or Gradio app - something where users explore data live on screen - and up to 50 people need to reach it in a browser without installing client software.

Pick Tailscale Serve if your app is interactive, your group is 6 people or fewer, and everyone is fine installing Tailscale and signing into the same tailnet.

Pick Streamlit Community Cloud if you have a Streamlit app in GitHub that fits in about 2.7 GB of memory, you only need one private app, and your dependencies don't require files or hardware on your laptop.

Pick Button if you don't need a live web app - you have a Python script (or Node, R, PowerShell, shell script or compiled binary) that takes parameters and files, runs for up to 30 minutes on your machine, and produces output files for colleagues to download.

FAQ

Does my data stay on my laptop when using Button?

The jobs themselves run on your computer and never in Button's cloud, but form values and files pass through Button's servers to get between your colleague's browser and your machine. Button deletes inputs 24 hours after a run ends, and deletes outputs after 7 days.

What happens if my computer is asleep or running another job on Button?

Your computer has to be on and online for colleagues to run your tool, and each computer runs one job at a time. The tool's page shows Ready, Busy or Offline so people can see its status before pressing Run.

How does Button count "people" and "runs" on the Free and Pro plans?

"People" counts the distinct colleagues you have invited, and you don't count toward that limit (3 people on Free, 250 on Pro). Runs per month (100 on Free, 5,000 on Pro) include your own runs as well as your colleagues' runs, and downgrading your plan deletes nothing.

Last updated

Put your script behind a form

Button turns a script on your computer into a web form. Colleagues sign in, fill it in, press Run and download the results. Free for 1 tool and 3 people.