Hyperopen
Open-source Hyperliquid trading client with portfolio analytics and vault analytics
Install / Use
npx skills add thegeronimo/hyperopenInstalls into whichever agent you are using.
README
Table of Contents
- Quick Start
- Why Hyperopen
- Current Focus
- Project Status
- Architecture Overview
- Validation
- Contributing
- License
Quick Start
Prerequisites
Install and run
npm ci && clojure -P
npm run dev
Open http://localhost:8080 in your browser.
<details> <summary>More dev commands</summary># Main app plus UI workbench
npm run dev:portfolio
# Same-origin HyperUnit proxy for funding flows
npm run dev:proxy # opens at http://localhost:8081
Production build:
npm run build
The release-ready static artifact is generated at out/release-public. Smoke-test locally with:
npm run test:playwright:seo
This command builds out/release-public, serves it through the repo's Pages-style static server, and runs the release-only SEO smoke suite. That keeps /robots.txt, /sitemap.xml, route directories like /trade, and the generated Cloudflare Pages _headers policy on the same path the release artifact is meant to use.
For the bridge-based interactive browser smoke suite, use:
npm run test:playwright:smoke
npm run build now also writes out/release-public/_headers with the repo-owned security and cache policy for the static deployment. Before launch, verify the deployed environment still serves that contract:
HYPEROPEN_VERIFY_ORIGIN="https://staging.hyperopen.example" npm run verify:deployment-headers
This command fails closed if the deployed origin is missing the expected CSP, anti-framing, or cache headers. If Hyperopen later adopts Pages Functions or an advanced-mode _worker.js, keep the same contract but move the header attachment into that Worker response path because Cloudflare does not apply _headers to Pages Function responses.
Why Hyperopen
Hyperopen is a community-driven trading interface built around a simple idea: traders should have control over the software they trade through.
| | | |---|---| | Inspectable and forkable | Open-source frontend meant to be studied, modified, and improved by the community | | Deterministic by default | Websocket flows, state transitions, and trading-critical logic live in testable code paths | | Explicit execution | Signing, funding, and order flows are treated as safety-critical surfaces | | Practical workflows | Trade, portfolio, funding, vault, and realtime market views in one codebase | | Developed in the open | Architecture, reliability rules, and product intent are documented in the repository |
Current Focus
- Trade surfaces with charting, order entry, and orderbook workflows
- Portfolio and account views
- Funding and wallet-related flows
- Websocket/runtime reliability and parity testing
- Open architecture with contributor-facing documentation
Project Status
Hyperopen is under active development. APIs, UX details, and internal boundaries are still evolving, but the project already enforces strict validation gates for reliability and signing-sensitive changes.
Start here to understand the project:
| Document | What it covers | |---|---| | Architecture Map | Layering, boundaries, and governance | | Security and Signing Safety | Crypto signing rules and credential handling | | Reliability Invariants | Runtime guarantees and validation gates | | Product Specs | Roadmap and feature specifications |
Architecture Overview
Hyperopen is built with ClojureScript, Replicant (data-driven rendering), and Nexus (action/effect dispatch). The core design principle: most product logic works on plain maps, vectors, and keywords, then hands off side effects to named boundary namespaces.
Key architectural choices:
- Data-oriented state — Actions return effect descriptors instead of mutating UI objects directly
- Explicit state flow — Reducers own transitions, effect interpreters own I/O, tests drive each separately
- Boundaries at the edge — Browser APIs, sockets, timers, and storage are pushed to dedicated infrastructure namespaces
- Projections and view models — UI consumes derived data, not raw exchange payloads
- WebSocket runtime — Realtime handling is a structured runtime with explicit stages, not a single
onmessagecallback
ClojureScript reinforces the architectural habits this codebase depends on. Product logic is written as functions over plain values — when a function takes a state map, it returns a new value or a vector of effects. Mutation points (swap!, browser APIs, sockets) are explicit and confined to boundary namespaces.
This matters for both humans and LLM-assisted development: reasoning stays local, it's easy to tell whether a function transforms data or performs I/O, and targeted edits are safer because mutation points are named and limited. The language also offers long-term stability — most product logic lives in reducers and projections rather than framework-heavy object lifecycles.
</details> <details> <summary>Detailed architecture and code walkthrough</summary>The wiring is visible in:
src/hyperopen/app/bootstrap.cljs— connects Replicant rendering to Nexus dispatchsrc/hyperopen/runtime/wiring.cljs— registers actions, effects, and runtime watchers- Feature namespaces like
src/hyperopen/chart/actions.cljs— domain-specific action handlers
Data-oriented actions return effect descriptors:
(defn select-chart-type
[state chart-type]
[(chart-dropdown-projection-effect nil [[[:chart-options :selected-chart-type] chart-type]])
[:effects/local-storage-set "chart-type" (name chart-type)]])
The WebSocket runtime treats realtime handling as a structured system:
websocket/client.cljs— assembles transport, scheduler, clock, router, and configwebsocket/application/runtime.cljs—core.asyncchannels and topic routingwebsocket/application/runtime_reducer.cljs— state transitions and emitted effectswebsocket/infrastructure/runtime_effects.cljs— transport, timer, and projection side effects
Market topics get sliding buffers while lossless topics (orders, fills) get regular buffers — high-frequency market traffic is smoothed without dropping account data.
Boundaries are pushed to the edge: raw provider payloads are normalized once in websocket/acl/hyperliquid.cljs, and mutable browser objects stay out of core reducer state.
For the full architecture, see ARCHITECTURE.md.
</details>Validation
| Command | What it does |
|---|---|
| npm run check | Lint and compile gates for app, worker, docs, and test builds |
| npm test | Compile and run the main Node test suite |
| npm run test:websocket | Websocket-focused test suite |
| npm run test:ci | Full local CI gate (check + test) |
| npm run test:watch | Watch mode for iterating on tests |
| npm run lint:delimiters -- --changed | Fast reader-level syntax preflight on changed files |
Contributing
Contributions are welcome. Start with:
- Architecture Map — understand the layering and boundaries
- Frontend Policy — conventions and code style
- Quality Scorecard — what "good" looks like here
- Planning and Execution — how work is planned
- Work Tracking — contributor workflow with
bd(beads)
The repository uses beads (bd) for local issue
Related Skills
codebase-memory-mcp
38.1kHigh-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.
codebase-memory-mcp
38.1kHigh-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.
codebase-memory-mcp
38.1kHigh-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.
tabularis
4.0kOpen-source desktop SQL workspace for PostgreSQL, MySQL/MariaDB, SQLite and 15+ more databases like DuckDB, ClickHouse, Redis and Firestore. Built-in MCP server for Claude, Cursor and Devin, SQL notebooks and visual EXPLAIN.
