Holm v0.114.2 cartridge online
Holm · self-hostable app & agent platform

Sovereign compute in one binary and one database.

A self-hostable app and agent platform you can move by copying one file. Apps, storage, auth, realtime, AI, and agents — without a service zoo. The binary is replaceable. The database is the instance.

binary
~14 MB
runtime
Pure Go · no CGO
platforms
Linux · Darwin
state
one SQLite file
01The problem

One product, spread thin across a service zoo.

Modern app development often splits one product across many rented surfaces — hosting, auth, database, object store, realtime, queue, serverless, email, AI, dashboards. The cost is not just bills. State and authority drift apart. Agents become a privileged integration mess.

×hosting ×auth ×postgres ×s3 ×queue ×realtime ×functions ×email ×analytics ×secrets ×ai gateway ×cron ×vector db ×oauth ×logs ×dashboard
Holm
$ ls ~/.config/holm/
data.db
holm
#  one binary + one database = a complete node
State and authority stay together.
02The atlas

The whole platform, in twelve nodes.

Holm compresses a service zoo into one runtime. Pick a scenario, hover a node, or click in to read what it does, the binding you'd reach for, and where it sits in the system. Every node lives in the same SQLite file.

core surface capability
The binary is replaceable.
The database is the instance. — knowledge-base / philosophy / core.md
03Build apps

An app is a directory.

Drop a folder, run one command. Static, BFBB, or Vite — the same source can run raw, or compile through a bundler. ESM in api/main.js. Relative imports inside api/. Top-level await. Bindings injected at runtime.

A

The shape

A Holm app is just files. No scaffolding. No framework lock.
my-app/
├── manifest.json          # name, title, visibility
├── index.html             # web surface
├── api/
│   └── main.js            # ESM handler for /api/*
└── private/
    ├── secrets.json       # auth-gated
    └── agents/
        └── parvathy/
            ├── agent.json
            └── AGENTS.md
B

The deploy

Same command, any peer. Local or production. Custom host or platform alias.
# local node
holm @local app deploy ./my-app

# named remote peer
holm @prod app deploy ./my-app

# own a hostname end-to-end
holm app deploy ./my-app \
  --host app.example.com
C

The handler

ESM, native dispatch. JS decides; Go performs the heavy work.
// api/main.js
export default async function handler(req) {
  if (req.path === '/api/notes') {
    const notes = await holm.app.member.ds
      .find('notes', { limit: 50 })
    return json(notes)
  }
  return json({ ok: true })
}
D

BFBB — build-free, but buildable

The same source runs without Node or npm. Add Vite for HMR and TypeScript when you want it. Tooling is enhancement, not dependency.
# no build step
holm app deploy ./blog

# or, with Vite
cd ./blog && pnpm build && \
holm app deploy ./blog/dist
04Agents

Agents are members.

Not bots bolted onto a PaaS. A native agent uses the same identity model, the same storage, the same auth, the same approvals as a human. It lives inside the app's trust boundary — explicit tools, durable memory, server-authoritative writes.

private/agents/parvathy/

agent.json

Identity, instructions, triggers, tools. Deployed brain is immutable until redeploy.
{
  "name":    "Parvathy Menon",
  "role":    "app_admin",
  "triggers": ["message", "webhook", "event"],
  "tools": [
    "holm.ai.chat",
    "holm.app.member.ds",
    "holm.app.kv",
    "holm.email.send",
    "holm.approvals.request"
  ]
}
  • message
    someone DM'd the agent on a channel
  • heartbeat
    a recurring schedule fired
  • webhook
    an external service called in
  • event
    an in-app event was emitted
brain overlays ai.chat app.ds app.kv app.s3 members.lookup secrets net.fetch approvals delegation pipes threads events templates connectors
05Capacity

What one node can carry.

Benchmarked on a $6 VPS — not a marketing rig. Holm uses SQLite's single-writer shape intentionally; writes serialize through a queue. Predictable ceilings beat fake infinite cloud fabric. When one node isn't enough, add another and route by app.

Concurrent users
2,000+
sustained
Read throughput
20k
requests / s
Write throughput
800+
writes / s
Mixed workload, 30% writes
2,300+
ops / s
WebSocket connections
5-10k
safe → tuned
RAM under load
~60
MB

Holm is not for huge multi-region workloads today. It is more than enough for many personal, internal-tool, small-SaaS, community, and agent-backed apps — on hardware that costs less than a coffee subscription.

06Operations

Boring is a feature.

Four commands you run for years. Install. Deploy. Backup. Upgrade. That's the operational surface. The database is one file. The binary is one file. Restore is a file copy.

01 · install

One binary

# Linux VPS, systemd $ curl -fsSL holmhq.com/install.sh | sh $ holm service install
02 · deploy

One directory

# local or remote peer $ holm @prod app deploy ./blog \ --host blog.example.com
03 · backup

One file copy

$ holm stop --force $ cp ~/.config/holm/data.db \ /backups/holm.db $ holm start
04 · upgrade

One swap

# resolves holmhq/releases $ holm upgrade $ holm @prod upgrade
07Status

Pre-1.0, fast-moving, and honest about it.

Holm is source-available today. Free for all except entities above $1M annual revenue. Each release moves to fully open source (MIT) after the deferred window. Releases ship from holmhq/releases; issues live at holmhq/issues.

Latest release checking…
v0.114.2
peer health reporting fix · this week
linux-amd64.tar.gz — —
linux-arm64.tar.gz — —
darwin-amd64.tar.gz — —
darwin-arm64.tar.gz — —

License posture

free Use Holm at no cost if your entity is at or below $1M annual revenue.
commercial Entities above $1M annual revenue need a commercial license.
hosted Selling Holm-as-a-service requires a commercial license, any size.
deferred oss Each release becomes MIT four years after publication.
Hosting is renting.
Holm is owning.
$ curl -fsSL holmhq.com/install.sh | sh click to copy