confish
Live demo

The missing UI for the things you run.

Typed config your code fetches on demand, one-off commands it picks up on the next poll, and live feeds of whatever you push. Settings, buttons, and readouts for your scripts - no frontend to build, no open ports, no restarts.

dashboard
you, in a browser

Config

maintenance_mode
max_retries
5
log_level
alert_threshold
80

Dispatch action

queued on the env. your app picks it up on its next poll.

Logs from your app

received · 2
1minfo · queue drained
24stick · processed 4 items
worker.py· pid 4271
your app
bootworker.py · pid 4271
bootconnected to confish · env=production
bootconfig loaded · max_retries=5 · log_level=info · threshold=80
00:00starting work loop…
$
try:

The problem

Your scripts have a UI. It's SSH.

Changing a value means an .env edit and a restart. Checking last night's run means tailing logs over SSH. Kicking off a job means opening a terminal. The real fix is a little admin panel - one per project, plus auth, plus hosting. We've all started that repo.

Before
constants.ts
-export const MAX_RETRIES = 3;
-export const DEBUG = false;
-export const THRESHOLD = 80;
// edit. commit. push. wait. restart.
After
config.ts
+const config = await client.fetch();
+config.max_retries // 5
+config.debug // true
// change in dashboard. done.
  • typed schema - never ship "true" as a string
  • per-environment - staging, prod, per-client
  • webhooks - pushed to your endpoint when config changes
  • push logs back - see what your script's doing

How it works

Three steps from signup to a real UI.

  1. Step 01

    Register an app

    Create an application, grab a pair of API credentials. Each app is its own isolated thing - its own schema, its own environments.

  2. Step 02

    Define your schema

    Typed fields: strings, numbers, booleans, dates, arrays. Config and feeds are both schema-backed, enforced on every write - no more "true" shipped as a string.

  3. Step 03

    Add environments

    Staging, prod, per-client, per-script - spin up as many as you want. Same schema, different values, separate keys. Point your code at one and go.

Where it pays off

Four things you stop building.

01Tweak it while it runs

Flip a flag, not a deploy.

Your scraper's being weird. You want to bump a retry count, or kill a feature, or quiet the logs. Change the value in the dashboard - your script reads the new one on its next poll. No SSH, no restart, no "just one more deploy."

typed · per-env · zero deploys
scraper.enabledboolean
14:02:17dashboard → false
14:02:24scraper.py polled · picked up change
14:02:24paused gracefully · 14ms
- or -webhook → POST your-app/cfg
paused. zero restarts. zero deploys.
02Per-environment

Same schema, different worlds.

Spin up as many environments as you want - staging, prod, per-client, per-script. Define the fields once. Each env keeps its own values.

typed · per-env · zero deploys
staging-eu
max_retries
5
log_level
debug
region
eu-w1
prod-us
max_retries
3
log_level
warn
region
us-e1
one schema · multiple envs
03Remote actions

Restart a worker without opening a port.

Queue an action on the environment. Your app polls, picks it up, executes it, reports back. No inbound port, no admin UI to build, no extra service to deploy - just your script and the dashboard.

typed · per-env · zero deploys
dashboard · youenv://production
action: flush_cache
payload: { "scope": "all" }
✓ queued · awaiting next poll
worker.py · 24s later
12:01:42 poll → action pending
12:01:42 action received · flush_cache
12:01:42 executing…
12:01:42 ✓ done · reported back · 84ms
04Live feeds

Your output, without the frontend.

You already produce the data - scrape results, job runs, incidents, sensor readings. Define a typed feed, push items by ID, and confish renders them as live cards, a table, or a compact list. Items update in place and clean themselves up on a TTL. Share any feed at a public link - or compose feeds from all your apps into one public board. That dashboard you were going to build this weekend? Already built.

typed · per-env · zero deploys
PUT /feeds/jobs/items/sitemap-crawl200 · updated in place
sitemap-crawlerdone

nightly full crawl

pages

12,480

2m ago
image-pipelinerunning

thumbnails + alt text

queue

314

26s ago
pushed from your code · finished runs expire on a ttl

SDKs

Five languages, one mental model.

Typed config, actions, logs, and feeds - hand-written for each language.

npm
$npm install @confish/sdk
example.ts
import { Confish } from '@confish/sdk';
const client = new Confish({ envId, apiKey });
const config = await client.fetch();
Read the docsMIT License

Pricing

Start free. Upgrade when it earns its keep.

No credit card required. Switch to Pro when you outgrow the free tier.

Free

Perfect for side projects and trying things out.

£0forever
  • Applications- 3
  • Environments per app- 3
  • Action dispatches per month- 50
  • API requests per minute (per app)- 60
  • Log entries per environment- 500
  • Log retention- 14 days
  • Config history per environment- 10 changes
  • Feeds per application- 1
  • Items per feed- 50
  • Webhooks (HMAC-signed)
Most popular

Pro

For when the basics aren't enough.

£9.99/month

Early adopter pricing

  • Applications- Unlimited
  • Environments per app- Unlimited
  • Action dispatches per month- Unlimited
  • API requests per minute (per app)- 600
  • Log entries per environment- 5,000
  • Log retention- 30 days
  • Config history per environment- 100 changes
  • Feeds per application- 10
  • Items per feed- 500
  • Public share links
  • Webhooks (HMAC-signed)

ready when you are

Give the things you run a UI.

Free forever, no credit card. Pick a language, paste a few lines, and you'll be reading your first value in minutes - actions, logs, and feeds right behind it.

  • no credit card
  • free tier forever
  • 5-minute integration