Open-source project
dd-center/vtbs.moe avatar
dd-center/vtbs.moe

vtbs.moe and the Bilibili virtual YouTuber status page built on one repository

Virtual YouTubers in bilibili

642 stars36 forksVueMIT

At a glance

What is it?
vtbs.moe records the live status of Bilibili virtual streamers, and its repository is unusual because the front end, the back end and the database all live in the same tree, with a Level database, a Koa JSON API and socket.io pushing updates. It fits a developer who wants to read how a live status board is put together, and it is a data source built on someone else's platform, not a platform of its own.
Who is it for?
vtbs.moe fits a developer who wants to see how a live status board for a third party platform is built, who is comfortable with Vue 2 and Koa, and who wants to run the whole thing from one checkout. It is the wrong tool for building your own streaming status page, because the data source is specifically Bilibili and the collection depends on a third party API project.
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 11 days ago.
What is it written in?
Mainly Vue, according to GitHub's language statistics.

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

Editorial analysis

One repository holds the front end, the back end and the database

The project is a statistics site for Bilibili virtual streamers, and the readme makes the unusual structural decision explicit: the front end, the back end and the database are all in this repository.

That is the first thing to understand about it. Most sites of this shape split into a front end repository, an API service and a data pipeline, because they are deployed separately and owned by different people. Here the top level listing shows `src/` for the Vue application, `api/` for the back end, `db/` for the data layer, `public/`, `script/`, plus `cdn.ts`, `index.cjs`, `index.html`, `hawk.cjs`, `state-center` and `BiliChat` directories, and an `ecosystem.config.yml` for process management.

The author's framing of the project is personal rather than institutional. It is described as a Bilibili virtual streamer status recording page made for his own amusement, and the readme opens with a greeting and closes with a note that you can open an issue to chat.

The live site is at vtbs.moe, and the readme embeds status badges pointing at endpoints on `api.vtbs.moe` for the overall VTuber count, the live count, a guard number and an online sum, wired to the site's home, live and macro pages. Those badges are a small piece of evidence about the architecture, because they are reading the same public JSON API that other projects consume, and the readme confirms that vtbs.moe does provide some public APIs, with the API documentation in `api.md`, and a request not to abuse them.

So the repository is both the site and its data source. That is what makes it readable as a reference implementation.

The stack is Vue 2, Koa, socket.io and a Level database

The dependency list in the package manifest is the clearest statement of the design, and the readme names the same components in prose.

On the front end, the framework is Vue.js with Vite and Vuex, the component library is Element, and the charts are ECharts with v-charts. The package manifest pins Vue at 2.7.16 and Vuex at 3.1.2, with vue-router at 3.1.3, and the manifest also carries vue-socket.io, vue-gtag for analytics, vue-json-tree-view, vue-virtual-scroll-list and bulma. The presence of a virtual scroll list and a JSON tree view alongside the charts suggests the interface is built for large lists of streamers, which is what a catalogue of thousands of channels needs.

On the back end, the database is Level, with levelup, subleveldown and encoding-down in the dependency list, plus lru-cache and rave-level for caching. Data collection uses Bili-api, listed as `bili-api` at `^1.10.1` and linked in the readme to the simon300000 project. Front end and back end communicate over socket.io, with socket.io and socket.io-client both present and a custom `@socket.io/sticky` package pulled from the dd-center organisation, plus `state-center` as a local file dependency.

The open API is Koa, with koa and @koa/router, and the request layer uses ky.

Two things stand out as deliberate choices rather than defaults. First, the socket.io sticky package is a fork maintained by the same organisation, which suggests they needed sticky sessions across clustered workers and did not want to carry a patch upstream. Second, the database is not a SQL server but Level, a key value store that keeps everything on the filesystem, which is why `db/` is a directory in the tree and why the whole thing can be cloned and run as one unit.

The build is Vite on port 8080, and the test script is the build

The npm scripts in the manifest are the whole developer workflow, and one of them is unusual.

json
    "serve": "vite --port 8080",
    "build": "npm run tsc && npm run build:vue",
    "tsc": "npx tsc -b",
    "dev": "npx tsc -b -w",

The `serve` script runs `vite --port 8080`, so the front end dev server is on 8080 rather than the Vite default. The `build` script runs `npm run tsc && npm run build:vue`, so a production build type checks first and then runs `vite build`. The `dev` script is `npx tsc -b -w`, which is the TypeScript project build in watch mode, and `tsc` is `npx tsc -b`.

The odd one is `test`. It is defined as `npm run build`, so the test command simply rebuilds the application. There is no test framework in the dependency list, no jest, no vitest, no playwright, and no test script of its own.

That is worth flagging plainly, because it is the kind of thing a reader will assume is an oversight. It is more likely a deliberate choice for a project where the build is the real check: a Vue and TypeScript codebase that compiles cleanly under `tsc -b` with strict settings will catch a large class of mistakes, and the site is a read only presentation layer over a data pipeline that runs elsewhere. The repository does contain a `tests/` directory, but the manifest gives it no test command.

The lint setup is a separate concern and is properly configured. The `lint` script runs eslint over `src` with the extensions `.js` and `.vue`, and it excludes a vendored directory with `--ignore-pattern src/assets/biliob-frontend/**`, which tells you the project carries a copy of another front end under `src/assets/`.

The remaining scripts are `preview` for `vite preview` and `build:vue` for `vite build`.

The public API and the contribution rules tell you what the project expects

The project publishes APIs, and the way it asks people to use them is a good indicator of its posture.

The readme says vtbs.moe does provide some public APIs, and asks please do not abuse. The API documentation is in `api.md` at the root, and the badge URLs point at endpoints such as `https://api.vtbs.moe/endpoint/vtbs`, `https://api.vtbs.moe/endpoint/live`, `https://api.vtbs.moe/endpoint/guardNum` and `https://api.vtbs.moe/endpoint/onlineSum`, which is a small public data surface for a hobby project with no stated service level.

The contribution guidance follows the same pattern. The readme says that if you want to add a large feature you can open an issue to discuss it first, while things like completing the VTuber list or fixing bugs can go straight to a pull request, and that questions can be opened as issues too.

That is a reasonable division, and it mirrors how the project is scoped in general. This is a personal project with a stated audience of one at the start, a live status board rather than a platform, and a maintainer who has kept the repository going without treating it as a product.

There is also an organisational dimension. The readme points to a DD Center organisation page with a dependency diagram, describing it as the DD Center org with some internal relationship, and the package manifest pulls one dependency directly from that organisation as a git reference rather than from a registry. So the project sits inside a small group of related repositories, and the dependency diagram on the organisation page is the place to see the wider shape.

The development documentation is in `development.md` at the root, and the repository also carries a `CLAUDE.md`, an `AGENTS.md` and a `.gitmodules` file, which indicates that some of the sibling directories are submodules rather than plain directories.

What the dependency on a third party API means for a data project

The single most important structural fact about this project is that it does not have its own source of truth. The data comes from Bilibili, and the collection is done through a separate open source library, Bili-api, credited in the readme as the data collection component and pinned in the manifest at `^1.10.1`.

That has consequences for anyone planning to depend on this service or to run it. The site is a projection of a platform it does not control. When Bilibili changes its API, or when the upstream library stops tracking those changes, the data stops updating, and nothing in this repository can prevent that. A status board that silently shows stale data is worse than one that shows nothing, which makes the freshness of the collection the thing to watch.

The Level database helps in one specific way. Because the data is a key value store on the filesystem rather than a hosted service, a run of the collector leaves a snapshot behind, so the history is inspectable and recoverable rather than being locked in a proprietary database. The `db/` directory in the tree is that store.

The caching dependencies deserve a mention for the same reason. `lru-cache` and `rave-level` are both present, which means the service caches aggressively in front of the upstream API, and that caching is what keeps the read rate against Bilibili down. It also means the numbers on the site can lag the live platform, which is a legitimate design choice for a status board and a meaningful difference from a real time feed.

The `state-center` local dependency and the socket.io layer are the mechanism by which the front end receives updates rather than polling. The state centre holds shared state between the collector and the API, the sticky socket.io package keeps sessions working when more than one worker is running, and the front end subscribes with `vue-socket.io`. For a live dashboard, that is a sensible architecture, and it is also the part that would need the most work to scale beyond a single machine.

Where vtbs.moe is the wrong tool to copy

There are three situations where this repository is the wrong reference, and the first is about what the data is.

The first is a team building a status or analytics product for its own users. The collection here is specific to Bilibili virtual streamers, and the schema follows that domain. Reading the code teaches you how this project does its job, not how to do yours.

The second is a service that has to be reliable. The readme describes the project as something the author made for his own amusement, there is no stated availability or support commitment, the public API asks not to be abused rather than publishing limits, and the test command is the build. If your product depends on this data, you are depending on an upstream API and a hobby project at the same time, and both can change under you.

The third is a modern front end stack. Vue is pinned at 2.7.16 and Vuex at 3.1.2, with vue-router at 3.1.3, and Element UI rather than Element Plus. The Vite build tooling and the TypeScript 4.9 setup are current enough, but the framework generation is the previous one, and anyone reading this for Vue patterns will pick up approaches that the current documentation no longer recommends.

There is also a simpler alternative worth naming for a comparable need, and the difference is in the data source rather than the code. If you want a live status board for your own services, a push model where each service reports its own health to a collector, and a dashboard that renders whatever it receives, avoids the scraping problem entirely. The same front end, the same socket.io layer and the same Level store would work, with the fragile part replaced by an endpoint the services control.

What vtbs.moe is genuinely good for is reading, and the repository is honest about being small. A Vue 2 and Koa application where the collector, the state centre, the socket layer and the database are all visible in one tree, and where the whole thing runs with a dev server on port 8080, is a good thing to read if you are building something similar.

Editorial conclusion

vtbs.moe fits a developer who wants to see how a live status board for a third party platform is built, who is comfortable with Vue 2 and Koa, and who wants to run the whole thing from one checkout. It is the wrong tool for building your own streaming status page, because the data source is specifically Bilibili and the collection depends on a third party API project. Before running it, verify three things: that the upstream Bilibili API library it depends on still works against the current site, since the whole service sits on top of it, that you can run the Node backend and the Vite dev server together, and whether the public API endpoints are appropriate for your use, because the readme asks plainly that they not be abused. The code is MIT licensed, the last push was on 2026-10-12, and the repository publishes no releases.

Frequently asked questions

What is vtbs.moe and what does it track?

It is a statistics and status recording site for Bilibili virtual streamers, live at vtbs.moe. The repository contains the front end, the back end and the database together, and it publishes public JSON API endpoints for the VTuber count, the live count, a guard number and an online sum.

What is the tech stack of vtbs.moe?

The front end is Vue.js with Vite and Vuex, Element as the component library, and ECharts with v-charts for charts. The back end is Koa with a Level database, socket.io for front end and back end communication, Bili-api for data collection, and Node.js underneath.

How do I run vtbs.moe locally?

The package scripts are `npm run serve` for the Vite dev server on port 8080, `npm run dev` for the TypeScript project build in watch mode, and `npm run build` for a production build that type checks first and then runs `vite build`. There is no separate test framework configured, since the `test` script runs the build.

Can I use the vtbs.moe public API?

The readme says vtbs.moe does provide some public APIs, with the documentation in `api.md`, and asks that they not be abused. The embedded status badges point at endpoints such as `https://api.vtbs.moe/endpoint/vtbs` and `https://api.vtbs.moe/endpoint/live` on the site.

How does vtbs.moe collect the Bilibili data?

Collection is delegated to the third party Bili-api library, listed as a dependency at `^1.10.1` and credited in the readme as the data collection component. Because the site depends on a platform and library it does not control, the freshness of the data depends on those staying compatible.

Official sources

  1. dd-center/vtbs.moe on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
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/dd-center-vtbs-moe.svg)](https://hysenlabs.com/projects/dd-center-vtbs-moe)

Was this useful?