Everything you can do with Berth.
A project in Berth is a unit of code you want to run. Projects can be created in several ways:
Paste code directly into the app. Berth saves it to disk, detects the runtime and entrypoint, and creates the project. Optionally auto-runs on creation.
Select an existing directory on disk. Berth scans for runtime markers and configures the project automatically.
Browse and install pre-built templates. See Template Store below.
Berth automatically detects the runtime by scanning for marker files:
| Runtime | Marker Files | Default Entrypoint | Dependency Install |
|---|---|---|---|
| Python | *.py, requirements.txt, pyproject.toml |
main.py, app.py, or first .py |
pip install -r requirements.txt |
| Node.js | package.json, *.js, *.ts |
package.json main field, or index.js |
npm install |
| Go | go.mod, *.go |
main.go |
go mod download |
| Rust | Cargo.toml, *.rs |
cargo run |
cargo build |
| Shell | *.sh, shebang |
First .sh file |
None |
You can override the detected runtime and entrypoint when creating a project.
Click Run in the project detail view. Select a target (local or remote) from the dropdown. Logs stream in real-time in the terminal panel with full ANSI color support and 10K line scrollback.
Every run is recorded with start time, end time, exit code, and trigger (manual, scheduled, or auto-restart). View history in the project detail view.
Store per-project secrets and configuration values. Environment variables are passed to the process at runtime and their values are masked in all logs.
Open the environment variables panel by clicking the Key icon in the project detail toolbar.
.env files by pasting content into the import textarea# Set a variable
berth env set my-project API_KEY sk-abc123
# List all variables (values masked)
berth env list my-project
# Remove a variable
berth env remove my-project API_KEY
# Import from a .env file
berth env import my-project .env
berth_env_set(project_id, key, value)
berth_env_get(project_id)
berth_env_delete(project_id, key)
berth_env_import(project_id, content)
Security: All environment variable values are treated as secrets. Values 3 or more characters long are replaced with *** in log output (longest values masked first). Variables are stored on the desktop only — they are passed to remote agents at runtime but never persisted on the agent.
Projects can run in two modes:
| Mode | Behavior | Use Case |
|---|---|---|
| Oneshot (default) | Runs once and stops when the process exits | Scripts, data processing, one-time tasks |
| Service | Auto-restarts on crash with exponential backoff (1s → 60s cap). Tracks uptime and restart count. | API servers, bots, workers, long-running services |
In the app, select "Service" from the run mode dropdown before clicking Run. Specify the port your service listens on.
# Via CLI
berth run my-api --mode service --port 8080
When a service crashes, Berth waits before restarting: 1s, 2s, 4s, 8s, 16s, 32s, 60s (cap). The backoff resets after a sustained successful run.
Run projects on a schedule using cron-like expressions. Schedules run on the agent (local or remote), so remote schedules execute even when the desktop app is offline.
| Expression | Description |
|---|---|
@every 5m | Every 5 minutes |
@every 1h | Every hour |
@hourly | At the start of every hour |
@daily | Once a day at midnight |
@weekly | Once a week on Sunday at midnight |
30 9 * * * | Every day at 9:30 AM |
0 */6 * * * | Every 6 hours |
0 9 * * 1-5 | Weekdays at 9 AM |
Standard 5-field cron format: minute hour day-of-month month day-of-week
Open the schedule panel by clicking the Clock icon in the project detail toolbar. Add a schedule with a cron expression.
# Add a schedule
berth schedule add my-project "@hourly"
# List all schedules
berth schedule list
# Remove a schedule
berth schedule remove <schedule-uuid>
berth_schedule_add(project_id, cron)
berth_schedule_list()
berth_schedule_remove(schedule_id)
Agent-side execution: The agent checks for due schedules every 30 seconds. Remote schedules run independently — they fire even when your Mac is off or the app is closed. macOS notifications are sent when scheduled runs complete or fail.
Publish any running project to a public URL via Cloudflare Quick Tunnels. No account required — you get a temporary *.trycloudflare.com URL.
Install cloudflared on the machine where the project runs:
# macOS
brew install cloudflared
# Linux (on the remote agent)
# cloudflared is usually available via package manager or download
# Publish
berth publish my-api --port 8080
# Unpublish
berth unpublish my-api
berth_publish(project_id, port)
berth_unpublish(project_id)
Note: Cloudflare Quick Tunnel URLs are temporary and change each time you publish. For persistent URLs, you'll need a Cloudflare account with named tunnels (not yet supported in Berth).
View and edit your project's entrypoint file directly in the app. The editor appears in the project detail view.
Berth sends macOS native notifications when project runs complete or fail. Notifications work for:
Toggle notifications per-project in the project detail settings. Notifications are enabled by default.
Browse and install pre-built project templates to get started quickly.
| Category | Examples |
|---|---|
| Scrapers | Hacker News scraper, web page monitor |
| API Servers | FastAPI starter, Express.js template |
| Bots | Discord bot, Telegram bot |
| AI/ML | LLM chat, data pipeline |
Click Template Store in the sidebar. Browse by category, search by keyword, and click Install to create a new project from the template.
# List all templates
berth store list
# Filter by category
berth store list --category scrapers
# Search
berth store search "web scraper"
# Install a template
berth store install hn-scraper
Berth includes a 3-way theme selector:
Change the theme in Settings.
Berth lives in your macOS menu bar, showing quick status of running projects. Click the tray icon to see active projects and their status without opening the main window.