# LobeHub: package.json says MIT, GitHub records NOASSERTION

> lobehub/lobehub is a TypeScript monorepo for running AI agents, and reading its configuration files is more informative than reading its README. The license is declared in two places that disagree, the default branch is a canary channel, the security settings file documents one variable backwards, and the container assembles its own runtime by copying individual shared libraries out of a Debian image.

**lobehub/lobehub** — LobeHub acts as a Chief Agent Operator that organizes your AI agents into round-the-clock operations, handling hiring, scheduling, and reporting while you stay in charge.

- Repository: https://github.com/lobehub/lobehub
- Website: https://lobehub.com
- Stars: 82,903 · Forks: 15,943
- Language: TypeScript
- License: not declared
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/lobehub-lobehub

## Two files declare the license and only one of them is read by tooling

The repository record gives the license as NOASSERTION, which is the value a repository gets when automatic detection does not settle on a single license. There is a LICENSE file at the root, a license badge in the README, and package.json carries `"license": "MIT"`. So the file says one thing, the package manifest says another, and the machine-readable repository metadata says neither.

Consequence for the reader: anything that reads the repository API rather than the manifest gets an indeterminate answer. A dependency scanner with a policy of blocking unknown licenses will flag or refuse this package, and a company doing a license audit has to open the file by hand to find out what it is. The MIT string in package.json is what a package manager will show you, so the two tools you would use to check give you two different levels of confidence, and the safest assumption is that the file at the root is the one a lawyer needs to read.

## The default branch is canary, and the version in the tree is not on it

The default branch is canary. The three most recent releases are all canary builds of the same version: v2.2.19-canary.34 published 2026-09-29, v2.2.19-canary.33 published 2026-09-29, and v2.2.19-canary.32 published 2026-09-28. Two of those landed on the same day. package.json, meanwhile, declares version 2.2.17.

The same file also disagrees with the repository about where the project lives. package.json sets homepage to the GitHub repository URL, and the repository record sets the homepage to lobehub.com, so the manifest points a package page back at the source and the source points at the site.

Consequence for the reader: a deployment that follows the default branch is deploying a canary build, which is a reasonable thing to want and a surprising default to inherit. The version string you read from the tree matches none of the tags, so when somebody reports a bug the build they are on cannot be named from what the source says. And a channel publishing several builds a day is not a cadence you can schedule upgrades against, since there is no signal in the tag name that distinguishes a routine rebuild from a risky one.

## One product is four HTML documents and five bundle entry points

The repository root holds index.html, index.auth.html, index.mobile.html and index.workbench.html. The sideEffects field in package.json names seven files: an initialize file, a provider icon module, and five single-page entry points covering auth, desktop, mobile, popup and web. The workspaces list adds apps/desktop/src/main, apps/share, apps/workbench and e2e alongside the package globs.

The build script makes the shape concrete. The main build chains a base single-page build, then auth, then workbench, then share, then a copy step, then the Next.js build. The Docker build chain inserts a mobile step that the main build chain does not have, even though the sideEffects list declares a mobile entry point.

Consequence for the reader: this is a monorepo producing at least four web surfaces plus a desktop main process, and the sideEffects list is the thing that stops a bundler discarding those entry points as unused. Adding a surface means touching three places, the manifest list, the build chain and the HTML documents. The gap between the two build chains is the sharper problem: a mobile entry that the release build does not compile is a surface whose behaviour you cannot confirm from the main build, and the Docker path, which is the path most self-hosters take, is the one that builds it.

## The container copies shared libraries one at a time and bundles proxychains

The Dockerfile starts from node:24-slim, optionally rewrites the Debian package sources to a mirror when a build argument is set, and installs ca-certificates and proxychains-ng. It then creates a distroless directory tree and copies individual files into it: the proxychains library, the legacy dynamic loader and realtime stubs, the proxychains binary and its configuration file, the C and C++ runtime libraries, the node binary, and the certificate bundle. Anything in /tmp and the apt lists is removed afterwards.

Consequence for the reader: this is a distroless image assembled by hand rather than pulled from a distroless base, so the list of shared libraries is a hand-maintained inventory. Add a native dependency and it will not be in the image, and the failure appears when your code calls into it at runtime rather than when the image builds, which is a considerably worse place to find out. Two of the copied files, the legacy loader stub and the realtime stub, exist because the node binary still references them, so the inventory is shaped by one binary's link table. The practical rule is that any native module you add needs its library added here by hand.

## proxychains is in the runtime, which decides how your model calls leave

The same base stage installs proxychains-ng and copies the proxychains binary to /distroless/bin/proxychains together with /etc/proxychains4.conf. The builder stage then sets a database driver, a database URL pointing at a local Postgres with a literal password, and an application URL, as build-time defaults.

Consequence for the reader: outbound traffic from the container, including calls to model providers, can be routed through a proxy chain, and the configuration that governs it is the distribution's own proxychains4.conf rather than something this project defines. That is a deliberate capability for networks where a direct route does not exist, and it is also an egress decision you inherit before you configure anything, so it belongs in your review rather than in a later hardening pass. The build-time database default is worth knowing too, because a value baked into a stage is a value that reaches logs and image layers even when the runtime configuration overrides it.

## The security comment for the content security policy contradicts the variable

The example environment file has a security section with two settings. The first is documented in three lines that do not agree with each other: set the variable to 1 to enable the frame options and content security policy headers, and the default is 0, which the same comment then describes as enabled. The second setting is documented consistently. Setting it to 1 allows connections to private IP addresses and disables server-side request forgery protection, the default of 0 keeps that protection on, and there is a warning to enable it only in trusted environments.

Consequence for the reader: the two settings are documented in opposite styles, and the first one is the one to slow down on. Read literally, the comment says the headers are on by default while the instruction says setting the variable turns them on, and those cannot both be true. An operator who trusts the default line leaves the state they did not choose, and an operator who sets 1 to be certain has taken the opposite action to the one they intended if the comment's second half is the accurate one. Nothing else in the file repeats the pattern, which makes this one line an outlier rather than a house style.

## The private address list only applies while protection is switched on

The third security setting is a whitelist of allowed private addresses, given as a comma-separated list, with an example of two bare addresses. The comment states that it takes effect only when the protection-disabling variable is 0.

Consequence for the reader: the two settings cannot be combined to express the thing most people want, which is to allow one internal host and keep blocking the rest. Turning protection off also switches off the list, so the only configuration that honours your two addresses is the one that leaves the blanket block in place. An operator who genuinely needs private networking therefore has to accept that their list is now ignored, and an operator who wants a single exception has to keep the protection on and enumerate every host the application is allowed to reach, including any that are added later. The example values are bare addresses with no scheme and no port, so the format is left to you to infer from the surrounding code.

## Conclusion

Read this repository's configuration rather than its front page if you are evaluating it, because the two disagree in ways that matter to an operator. Do not deploy from the default branch expecting a stable build, since that branch is canary and the version in package.json is not the version on the canary channel, so pin a tag. Before you self-host, check three things: the license, which you will have to read from the LICENSE file because the repository record reports it as indeterminate; the content security policy setting, whose comment in the example environment file contradicts the variable it documents; and the Redis key prefix, which defaults to the project's former name, so a shared Redis instance will collide with anything else using that namespace. And if you add a native dependency, expect to add its shared library to the Dockerfile by hand, because the runtime image is assembled file by file.

## FAQ

### What is LobeHub?

It is a TypeScript monorepo that the README describes as a chief agent operator, organizing agents into continuous operation by hiring, scheduling and reporting on them. The package manifest describes it more narrowly as an open-source AI agent framework supporting speech synthesis, multimodal work and an extensible function-call plugin system, with one-click deployment of a private chat application.

### is lobehub open source

Yes, and the record is inconsistent about it. There is a LICENSE file at the root of the repository, a license badge in the README, and package.json declares MIT. The repository's own license metadata reads NOASSERTION, which is what an undetermined license looks like to a tool, so check the file rather than the badge or the manifest.

### how to use lobehub

The README's table of contents lays out two self-hosting routes: one deploying to Vercel, Zeabur, Sealos or Alibaba Cloud, and one deploying with Docker, followed by a section on environment variables and a step for obtaining an OpenAI API key. The example environment file is where the settings live, including the OpenAI key, Redis connection details and the security switches.

### is lobehub safe

The example environment file ships server-side request forgery protection on by default, with a private address list that applies only while that protection stays on, and a separate switch for content security policy and frame options headers whose comment contradicts itself. The container image also bundles proxychains, so outbound calls can be routed through a proxy chain using the distribution's own configuration file.

### lobehub vs open webui

The README makes no comparison with Open WebUI or with any other project, and names no alternative. Its ecosystem and plugins sections point at directories of extensions rather than at comparable tools, so any comparison has to be assembled from outside this repository.

## Sources

- [Official documentation](https://lobehub.com)
- [Official README](https://github.com/lobehub/lobehub#readme)
- [Project repository](https://github.com/lobehub/lobehub)
- [Release notes](https://github.com/lobehub/lobehub/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lobehub-lobehub
