Model or dataset
daggerhashimoto/openclaw-nerve avatar
daggerhashimoto/openclaw-nerve

openclaw-nerve installs with a curl pipe and collides on port 3080

Real-time web cockpit for OpenClaw: voice conversations, agent automated kanban board, workspace/file control, sub-agent sessions, inline charts, and usage visibility.

869 stars147 forksTypeScriptMIT

At a glance

What is it?
A web cockpit that puts an OpenClaw gateway in a browser, with voice input, per-agent workspaces, a kanban board and usage meters. The mechanics are where the value is: a bash installer that also serves the next branch, two dev servers that default to the same port, and authentication that only exists once you bind to the network.
Who is it for?
Nerve is a front end for a gateway somebody else runs, and the README is honest about that split, which makes it easy to evaluate. Four things to check.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 124 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The installer is piped to bash, and next still uses master's copy

The whole install is one line:

bash
curl -fsSL https://raw.githubusercontent.com/daggerhashimoto/openclaw-nerve/master/install.sh | bash

The README describes what that script does: it handles dependencies, clone and build, and then usually hands off straight into the setup wizard. Access modes offered by the wizard are localhost, LAN, a Tailscale tailnet IP and Tailscale Serve.

The interesting case is the next branch. A fresh install from next is the same command with an argument:

bash
curl -fsSL https://raw.githubusercontent.com/daggerhashimoto/openclaw-nerve/master/install.sh | bash -s -- --branch next

The URL still points at master. So the branch you test is chosen by the installer, while the installer itself is always master's, and you have no checksum, no version pin and no way to read the script before it runs in both cases.

The two dev servers default to the same port

Development runs a frontend and a backend separately:

bash
npm run dev # frontend — Vite on :3080 by default
PORT=3081 npm run dev:server # backend — explicit split-port dev setup

The README then names the trap directly. `npm run dev:server` uses the normal server `PORT` setting, so without the override the backend also defaults to 3080 and collides with Vite. The server port is the same `PORT` variable the deployment uses, which is why the example sets it inline for one command rather than in a `.env`.

The production path has no such ambiguity, because it builds once and runs a single entry point. `npm run prod` is a build followed by `node server-dist/index.js`, and `npm start` runs that same file without rebuilding. The build itself is three passes: `tsc -b`, then `vite build`, then a server build that compiles two configurations, one into `server-dist` and one into `bin-dist`.

Node.js 22 or later is required, pinned both in `engines` and in a `.nvmrc`.

npm test watches, and the update script lives in build output

Two script definitions are worth knowing before you wire this into anything automated. `test` is `vitest` with no `run`, so it starts in watch mode and stays there; the non-interactive form is `test:coverage`, which is `vitest --coverage`, and neither script as written terminates on its own.

The other is `update`, which runs `node bin-dist/bin/nerve-update.js`. That path is produced by the build, from the second TypeScript configuration compiled by `build:server` into `bin-dist`. On a fresh clone, before a build, the update script does not exist.

What update does once built is described in one line: it fetches the latest release, rebuilds, restarts, verifies health and rolls back automatically on failure. The rollback is the part worth remembering, since it is also listed among the polish items as an updater with rollback.

The postinstall hook is smaller but friendly: if `.env` is missing, it prints a message telling you to run `npm run setup`.

Authentication appears when you bind to the network

The default is local-only. Nerve binds to `127.0.0.1`, and the same value appears in the environment template with the note that `0.0.0.0` is for network or remote access and requires auth.

What auth means is spelled out in the template rather than the README. A password can be required for all API and WebSocket access with `NERVE_AUTH`, the password itself is stored as `NERVE_PASSWORD_HASH`, described as a scrypt hash generated by `npm run setup`, and `NERVE_SESSION_SECRET` is a 32-byte hex value for cookie signing, auto-generated by setup. Sessions last 30 days by default through `NERVE_SESSION_TTL`. The wizard configures these automatically when you choose network access during setup.

One line in the template is unfinished. The security override section says that setting `HOST=0.0.0.0` without auth causes the next thing, and stops there. The README says password authentication protects the UI when bound to the network, but the exact refusal behaviour is only half-written.

Three transports sit between the browser and the gateway

The architecture is one diagram, and it explains where every feature comes from. Nerve listens on 3080 and the OpenClaw gateway on 18789. WebSocket traffic is proxied through to the gateway, server-sent events carry file watchers and real-time sync, and REST handles files, memories, TTS and models.

That split is why the workspace browser feels live: file changes arrive over the event stream rather than by polling. It is also why the gateway's own port is configured in Nerve, through `GATEWAY_URL`, with `GATEWAY_TOKEN` alongside it and an alternative variable name checked as a fallback. The token is injected server-side for trusted connections, local or authenticated, which is what keeps it out of the browser.

A third variable, `NERVE_PUBLIC_ORIGIN`, is for the remote-workspace gateway RPC fallback, where the browser's origin has to be named explicitly. Nerve is described as sitting in front of the gateway and giving it a cockpit, with OpenClaw remaining the engine, so every capability beyond the three transports belongs to the gateway.

The two next-branch blocks are identical

The next-branch section has two command blocks that read the same. The first is titled switching an existing install to next, the second keeping next updated, and both contain the same sequence:

bash
cd ~/nerve # installer default; manual clone: cd openclaw-nerve
git fetch origin
git switch next || git switch -c next --track origin/next
git pull --ff-only
npm install
npm run build
npm run prod

So the switch operation doubles as the update operation, which is convenient and means the second block documents nothing new. Two details in it are worth keeping. `git switch next || git switch -c next --track origin/next` is a fallback that creates a local tracking branch when the remote one does not exist locally yet, and `git pull --ff-only` refuses to merge, so an install that has diverged stops rather than producing a merge commit in place.

The comment on the first line records the installer's default directory as `~/nerve`, with `openclaw-nerve` as the name a manual clone gets.

Per-agent identity, soul and skills are editable from the UI

The capability table is where the scope is. Each agent in the fleet has its own workspace, subagents, memory, identity, soul and skills, and Nerve lets you inspect and edit that context live rather than guessing what an agent knows. The workspace side is a per-agent file browser, a tabbed editor, memory editing, config editing and a skills browser. Operations add a session tree, cron scheduling, a kanban task board, a review flow, a proposal inbox and model overrides.

Observability is a token usage view, cost tracking, a context meter, agent logs and event logs, which is the practical answer to running long jobs. Cron runs show up as their own sessions rather than as automation you cannot see. Charts are a first-class output rather than a code block.

Voice is treated as a feature rather than an extra: push to talk, wake word flows, explicit language selection, local Whisper transcription, multilingual stop and cancel phrases, and multiple TTS providers. The stack underneath is React 19, Tailwind CSS 4, shadcn/ui and Vite 7 on the front, Hono 4 on Node.js behind, with a large CodeMirror stack for the editor.

Editorial conclusion

Nerve is a front end for a gateway somebody else runs, and the README is honest about that split, which makes it easy to evaluate. Four things to check. Install path: the whole setup is a remote script piped into bash, and even the next-branch install fetches that installer from master, so you are trusting one script before you choose a branch. Network exposure: the default bind is 127.0.0.1, and password authentication, a scrypt password hash and a cookie-signing secret only come into play when you bind to `0.0.0.0`, with sessions defaulting to 30 days. Ports: the backend and the Vite dev server both default to 3080, which the README warns about only in the development section. And version discipline: package.json reads 1.5.3, the newest tag is v1.5.3 from 2026-04-22, and the branch was pushed on 2026-06-03, so the last two months of work are on master without a tag. There is a stable branch and a `next` branch, and the README does not say which one a bug fix lands in first.

Frequently asked questions

How do I install openclaw-nerve?

Run `curl -fsSL https://raw.githubusercontent.com/daggerhashimoto/openclaw-nerve/master/install.sh | bash`. The installer handles dependencies, clone and build, then hands off to the setup wizard. A manual path is `git clone`, `npm install`, `npm run setup` and `npm run prod`. Node.js 22 or later and an OpenClaw gateway are required.

What port does Nerve listen on and how do I reach it remotely?

Port 3080 by default, bound to 127.0.0.1. The setup wizard offers localhost, LAN, a Tailscale tailnet IP and Tailscale Serve as guided access modes, and binding to the network uses HOST=0.0.0.0 with password authentication switched on.

How do I run the Nerve development servers?

`npm run dev` starts Vite on port 3080, and `PORT=3081 npm run dev:server` starts the backend on a different port. Without that override the backend also defaults to 3080 and collides with the frontend, which the README calls out explicitly.

How does openclaw-nerve update itself?

`npm run update -- --yes` fetches the latest release, rebuilds, restarts, verifies health and rolls back automatically on failure. The script it runs is `bin-dist/bin/nerve-update.js`, which exists only after a build has produced the bin output.

Does openclaw-nerve require a password by default?

No. NERVE_AUTH is commented out in the environment template and false by default, which matches the 127.0.0.1 bind. When you do enable it, the password is kept as a scrypt hash in NERVE_PASSWORD_HASH and the cookie signing secret is a 32-byte hex value, both generated by `npm run setup`, with sessions defaulting to 30 days.

Official sources

  1. daggerhashimoto/openclaw-nerve on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/daggerhashimoto-openclaw-nerve.svg)](https://hysenlabs.com/projects/daggerhashimoto-openclaw-nerve)