Helixent: a ReAct agent loop and coding CLI built on Bun
Helixent is a small library for building ReAct-style AI agent loops based on the Bun stack.
At a glance
- What is it?
- Helixent packages a three-layer TypeScript agent stack (foundation, agent loop, coding agent) with a Bun CLI, YAML model config, and the agentskills.io skill format. The interesting part is the middleware seam; the limiting part is that the licence is not stated in the material.
- Who is it for?
- Helixent is worth a look if you want a ReAct loop you can extend through middleware rather than fork, and you are already on Bun. Skip it if you need a stated licence before you ship, or if your runtime is Node and you cannot add Bun.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 118 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 September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap Helixent fills between a raw model call and a finished coding agent
Most teams writing an agent end up with the same three pieces: a wrapper around a provider API, a loop that alternates between reasoning and tool calls, and a pile of file and shell tools. Helixent ships those as separate layers instead of one blob. The README describes three: foundation, agent loop, and coding agent, with a fourth directory, src/community/, for third-party integrations such as OpenAI. The target reader is a TypeScript developer who wants the loop but not the whole opinionated product. If you only need to call a model and parse a response, this is more machinery than the job requires. If you have written the think, act, observe cycle by hand twice, the middle layer is the part you are actually buying.
Foundation, loop, coding agent: what each layer owns
The foundation layer holds three primitives. Model is described as a unified abstraction over LLM providers, so agent code is written against Model rather than a vendor SDK. Message is a single transcript type that the README calls the single source of truth for the conversation. Tool covers tool definitions and the execution plumbing. The agent layer above it maintains state over that transcript and orchestrates think, act, observe steps in a loop. Tool calls are invoked in parallel and the observations are fed back into the next reasoning step. The README states that this layer depends only on foundation and stays generic, which is the claim that matters most: it means you can use the loop without the coding tools. The coding layer sits on top with read_file, write_file, str_replace, list_files, glob_search, grep_search, apply_patch, file_info, mkdir, move_path and bash, plus a plan mode driven by a todo list. That separation is the design decision worth judging. A generic loop with a domain layer bolted on is easier to reason about than a coding agent with the loop buried inside it, and it is the reason the middleware story below is even possible.
Middleware is the extension point, and the hook list is what to inspect first
The README advertises first-class middleware support for extending behaviour, naming state, tool orchestration and skills as examples, and lists Available Hooks as a subsection. The hook names themselves are not in the material supplied here, so treat the hook list in the repository as the first thing to read before committing. What the structure implies is that you extend the loop by registering middleware rather than editing it, which matters for upgrade cost: if your customisation lives in middleware, a change to the loop internals is less likely to break you than a patch against loop source. Human-in-the-loop approval of tool calls is listed as a feature of the same layer, which suggests approval is expressed as one of these extensions rather than as a separate mode. That is a reasonable arrangement, but it also means the approval path is only as good as the middleware contract, and the contract is not visible in the README text provided.
Skills, AGENTS.md, and where the agent reads project context from
Helixent implements the standard agent skill format from agentskills.io. Skills are discovered in four locations: ~/.agents/skills, ~/.helixent/skills, and the equivalents under the current project at .agents/skills and .helixent/skills. The README notes that duplicate skill names in different folders are allowed, which is a deliberate choice with a consequence: resolution order becomes something you have to reason about, and the material does not state which path wins. Project guidance is handled separately through AGENTS.md at the repository root, picked up automatically when present. Together these two mechanisms are how a project tells the agent what it is. The split is sensible (skills for reusable capability, AGENTS.md for this repository's conventions), but if you maintain shared skills across several projects, confirm the precedence rule yourself rather than assuming the user-level directory overrides the project one.
Installing and running it: the commands in the README
Two paths are given. To install globally: npm install -g helixent@latest, then cd into your project and run helixent, with helixent --help for usage. To skip the install: cd into the project and run npx helixent@latest, or npx helixent --help. Configuration lives in ~/.helixent/config.yaml. Model management is a small subcommand tree: helixent config model list, helixent config model add, helixent config model remove <model_name> (or the same command with no argument to pick from a list), and helixent config model set-default <model_name> (again, no argument gives a selection prompt). Note the mismatch worth knowing about: the CLI is distributed through npm, but the project is a Bun project. Building from source uses bun install, bun run dev for development mode, and bun run build:bin, which the README says produces dist/bin/helixent. A pre-commit hook runs bun run check, and the same check runs in GitHub Actions on every push and pull request. The README is candid that this slows commits down and argues the trade is worth it. For a solo contributor that hook is a friction point; for a team it is the thing that keeps the main branch green.
Where Helixent is the wrong choice
The licence is not stated in the material supplied. That is not a small omission. If you are evaluating this for anything you intend to redistribute, or for a company with a dependency review step, you cannot complete that review from the README alone, and you should not assume a permissive default. Check the repository for a licence file before anything else. The second constraint is the runtime. The project is built on Bun and the badges name Bun, TypeScript, Ink and React, with the CLI using Ink for its terminal UI. The README includes a Why Bun? section, which tells you the choice was deliberate rather than incidental. If your deployment target is Node, adopting Helixent means either adding Bun to your environment or treating the loop as a reference implementation to port. Third, this is a young project with no releases retrieved in the material, so there is no version history to read for stability signals. Fourth, the coding agent's toolset is broad (patch application, glob and grep search, shell execution) and the README does not describe a sandbox or permission model beyond human-in-the-loop approval. If you run it against a repository you care about, the approval mechanism is the only guardrail described, and you should confirm how it behaves before pointing it at anything with write access.
How it compares to assembling the loop yourself or using a hosted agent
The realistic alternative is not another library, it is writing the loop. A ReAct loop over a provider SDK is a few hundred lines: hold a message array, call the model, dispatch tool calls, append observations, repeat. What you get from Helixent in exchange for the dependency is the Model abstraction so provider swaps do not touch agent code, parallel tool invocation, the middleware seam, and a coding layer already wired to file and shell tools. The difference in approach is where customisation lives. If you write your own loop, you own everything and every provider change is your problem. If you adopt Helixent, you accept its Message type as the transcript format and its middleware contract as the extension surface, and in return the coding tools and the CLI exist already. A hosted coding agent takes a third position: you get a finished product and no loop to extend at all. Helixent sits between those, and the middleware hook list is the thing that decides whether the middle position is actually useful to you or just a thinner version of writing it yourself.
Maintenance cost and the licence question
Upgrade cost here is mostly about the middleware contract and the config file. The loop is extended through hooks, so as long as the hook signatures hold, your customisations survive internal changes to the loop. The config at ~/.helixent/config.yaml is user-level, which means model setup does not travel with the repository; a new machine needs helixent config model add run again, and there is no project-level config path mentioned in the material. The pre-commit hook that runs bun run check is a per-clone setup step, so onboarding a contributor means getting Bun installed and the hook active, not just npm install. On licensing, the material gives no licence identifier, so any statement about redistribution, modification or commercial use would be a guess. Read the repository's licence file, and if there is none, ask the maintainer directly before you depend on it. That is a question with a factual answer, and it is cheaper to ask now than to unwind a dependency later.
Editorial conclusion
Helixent is worth a look if you want a ReAct loop you can extend through middleware rather than fork, and you are already on Bun. Skip it if you need a stated licence before you ship, or if your runtime is Node and you cannot add Bun. Before adopting, run helixent config model list to confirm your provider is representable in ~/.helixent/config.yaml, check the middleware hook list against the behaviour you need to intercept, and read the repository for a licence file, since none is given here.
Community notes