Skip to content

Every company has the same dirty secret: critical business processes run on spreadsheets, Slack messages, and manual copy-paste between systems. The admin dashboard that would take two months to build properly never gets built. The webhook processor that should exist gets replaced by someone checking email. The report that should be automated is generated by hand every Friday.

These tools do not get built because the overhead of building them is absurd. Spin up a server. Configure a database. Set up authentication. Write a deployment pipeline. Manage SSL certificates. All for an internal tool that three people use.

On Hoody, an internal tool is a file. You write a function, it becomes an HTTP endpoint. You query the database through HTTP. You share the URL with your team. Done. No infrastructure. No deployment. No maintenance. The file IS the tool.


Traditional Internal ToolHoody Internal Tool
Provision a serverAlready have one
Install a web frameworkWrite a function in a file
Set up a databasehoody-sqlite is already running
Configure authenticationProxy permissions
Write deployment scriptsFiles are live instantly
Manage SSL certificatesHandled by the proxy
Monitor uptimehoody-daemon auto-restarts
Schedule taskshoody-cron is already running

The distance between “I need this tool” and “this tool exists” collapses from weeks to minutes.


An admin dashboard that reads user data from SQLite and returns JSON. The frontend can be any HTML page, a React app, or even a curl command.

Terminal window
# Create the users table with sample data (--db is required; --create-db-if-missing creates app.db on first use)
hoody db exec-transaction --db /hoody/databases/app.db --create-db-if-missing \
--transaction '[{"statement": "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL, name TEXT NOT NULL, role TEXT DEFAULT '\''user'\'', status TEXT DEFAULT '\''active'\'', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, last_login DATETIME)"}]'
# Insert sample data
hoody db exec-transaction --db /hoody/databases/app.db \
--transaction '[{"statement": "INSERT INTO users (email, name, role, status, last_login) VALUES (\"alice@company.com\", \"Alice Chen\", \"admin\", \"active\", \"2026-03-03\"), (\"bob@company.com\", \"Bob Martinez\", \"user\", \"active\", \"2026-03-04\"), (\"carol@company.com\", \"Carol Kim\", \"user\", \"suspended\", \"2026-02-15\")"}]'

Create a hoody-exec script that serves as the dashboard backend:

Terminal window
hoody exec scripts write \
--path "admin/dashboard.ts" \
--content "// @mode serverless\n// @cors reflective\n// @timeout 5000\n\nconst SQLITE = \"https://PROJECT-CONTAINER-sqlite-1.SERVER.containers.hoody.icu\";\n\nconst stats = await fetch(SQLITE + \"/api/v1/sqlite/db?db=/hoody/databases/app.db\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ transaction: [{ query: \"SELECT COUNT(*) as total_users FROM users\" }] })\n}).then(r => r.json());\n\nreturn { statistics: stats, generated_at: new Date().toISOString() };" \
--create-dirs

Your dashboard API is now live:

Terminal window
curl "https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.icu/admin/dashboard"

Response:

{
"statistics": {
"total_users": 3,
"active_users": 2,
"suspended_users": 1,
"admin_count": 1,
"active_this_week": 2
},
"recent_logins": [
{ "name": "Bob Martinez", "email": "bob@company.com", "role": "user", "status": "active", "last_login": "2026-03-04" },
{ "name": "Alice Chen", "email": "alice@company.com", "role": "admin", "status": "active", "last_login": "2026-03-03" }
],
"generated_at": "2026-03-04T12:00:00.000Z"
}

From nothing to a working admin dashboard API: one file, one URL, zero infrastructure.


Receive webhooks from external services, store them in SQLite, and send notifications.

Terminal window
hoody exec scripts write \
--path "webhooks/stripe.ts" \
--content "// @mode serverless\n// @cors *\n// @timeout 10000\n// @concurrent false\n\nconst SQLITE = \"https://PROJECT-CONTAINER-sqlite-1.SERVER.containers.hoody.icu\";\nconst NOTIFY = \"https://PROJECT-CONTAINER-n-1.SERVER.containers.hoody.icu\";\n\nawait fetch(SQLITE + \"/api/v1/sqlite/db?db=/hoody/databases/app.db\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n transaction: [{\n query: \"INSERT INTO webhook_events (source, event_type, payload, received_at) VALUES (?, ?, ?, ?)\",\n values: [\"stripe\", req.body.type, JSON.stringify(req.body), new Date().toISOString()]\n }]\n })\n});\n\nreturn { received: true, event: req.body.type };" \
--create-dirs

Point Stripe’s webhook URL at:

https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.icu/webhooks/stripe

Every webhook is stored in SQLite. Payment successes and failures trigger push notifications to your phone. The @concurrent false magic comment ensures webhooks are processed one at a time — no race conditions, no duplicate processing.


Generate CSV reports from database queries and serve them via hoody-files.

Terminal window
SQLITE="https://$PROJECT_ID-$CONTAINER_ID-sqlite-1.$SERVER.containers.hoody.icu"
FILES="https://$PROJECT_ID-$CONTAINER_ID-files-1.$SERVER.containers.hoody.icu"
hoody exec scripts write \
--path "reports/weekly-users.ts" \
--content "// @mode serverless\n// @cors reflective\n// @timeout 30000\n\nconst SQLITE = \"$SQLITE\";\nconst FILES = \"$FILES\";\n\nconst result = await fetch(SQLITE + \"/api/v1/sqlite/db?db=/hoody/databases/app.db\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ transaction: [{ query: \"SELECT name, email, role, status FROM users\" }] })\n}).then(r => r.json());\n\nconst rows = result.data || result;\nconst csv = \"Name,Email,Role,Status\\n\" + rows.map(r => [r.name, r.email, r.role, r.status].join(\",\")).join(\"\\n\");\n\nres.setHeader(\"Content-Type\", \"text/csv\");\nreturn csv;" \
--create-dirs

Hit the URL and download the report:

Terminal window
curl -o report.csv "https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.icu/reports/weekly-users"

The report is also saved to the filesystem via hoody-files, creating an archive of historical reports.

Run the report automatically every Friday:

Terminal window
hoody cron entries create root \
--schedule "0 9 * * 5" \
--command "curl -s https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.icu/reports/weekly-users > /dev/null" \
--comment "Weekly user report generation"

Every Friday at 9 AM, the report generates and saves to the filesystem. No crontab editing. No server maintenance. An HTTP call configured the schedule.


Internal tools should not be public. Lock them down:

Terminal window
# Password protect the container
# Writes are optimistic-concurrency guarded: pass the current file_version via --if-match
hoody containers proxy permissions replace -c $CONTAINER_ID \
--project $PROJECT_ID \
--if-match "$(hoody containers proxy permissions get --container $CONTAINER_ID --field file_version)" \
--groups '{"team": {"type": "password", "password": "internal-tools-2026"}}' \
--permissions '{}'
# Or restrict to office IP
hoody containers proxy permissions replace -c $CONTAINER_ID \
--project $PROJECT_ID \
--if-match "$(hoody containers proxy permissions get --container $CONTAINER_ID --field file_version)" \
--groups '{"office": {"type": "ip", "range": "203.0.113.0/24"}}' \
--permissions '{}'

Now all services — exec endpoints, SQLite UI, terminal access — require the password. One setting protects everything.


Share the URL. That is the entire distribution process.

Admin Dashboard: https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.icu/admin/dashboard
Webhook Processor: https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.icu/webhooks/stripe
Weekly Report: https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.icu/reports/weekly-users
SQLite Web UI: https://PROJECT-CONTAINER-sqlite-1.SERVER.containers.hoody.icu
File Browser: https://PROJECT-CONTAINER-files-1.SERVER.containers.hoody.icu

Or create clean aliases:

admin.hoody.icu/admin/dashboard
hoody proxy create --container-id $CONTAINER_ID --program exec --index 1 --alias "admin"

Your team opens the URL. The tool is there. No deployment, no installation, no training on how to access it. If they can open a browser, they can use the tool.


Every internal tool on Hoody follows the same pattern:

  1. Write a hoody-exec script — The logic lives in a file that becomes a URL
  2. Use hoody-sqlite for data — Queries and storage through HTTP
  3. Use hoody-notifications for alerts — Push notifications when events occur
  4. Use hoody-files for output — Reports, exports, archives
  5. Use hoody-cron for scheduling — Automated execution on a schedule
  6. Use proxy permissions for access — Password or IP restriction
  7. Share the URL — Distribution complete

No servers to manage. No frameworks to learn. No deployment pipelines to configure. No SSL certificates to renew. No Docker images to build. No Kubernetes manifests to write.

Just functions that become URLs, talking to databases that are URLs, saving files that are URLs, on a schedule that is configured via URL.