Frontend Development 15 min read

Technical Architecture and Engineering Practices of Bilibili's PC Client

Bilibili’s newly rebuilt PC client, launched in May 2022, uses Electron with a Node.js/NestJS main process and a Vue 3/Vite renderer, incorporates custom UI libraries, employs fast hidden‑window startup, energy‑saving tray mode, secure encrypted packaging and incremental updates, and delivers a dual‑window playback experience that has attracted over three million daily active users, representing about 40 % of installations.

Bilibili Tech
Bilibili Tech
Bilibili Tech
Technical Architecture and Engineering Practices of Bilibili's PC Client

Bilibili, known as a learning platform, has launched a dedicated PC client to leverage desktop advantages such as shortcut access, independent windows, and unique interactions. The client was redeveloped in late 2021 to replace an outdated UWP version.

Technology Selection

After evaluating various cross‑platform solutions, the team chose the Electron framework based on a Web technology stack for its balance of development efficiency, cross‑platform support, and maturity.

Electron combines Chromium and Node.js, exposing system APIs (dialogs, tray, menus, clipboard, etc.) to JavaScript, enabling rapid desktop application development.

Process Architecture

The application is divided into a Main Process (Node.js) and a Renderer Process (Web). The Main Process handles native APIs, logging, storage, download, reporting, and updates, while the Renderer Process implements UI and business logic.

For maintainability and extensibility, the Main Process is built with Node.js + NestJS + esbuild, and the Renderer Process uses the same stack as the web front‑end: Vue 3 + Vite + TypeScript.

Custom Tool Libraries

The project incorporates internally developed libraries such as vivid‑ui (Vue components), @bilibili/b‑utils (utility functions), and @bilibili/b‑style (style utilities) to maximize code reuse and reduce development cost.

Overall Architecture

The Renderer Process renders business pages, while the Main Process provides services like local logging, storage, and download SDKs. Communication between the two is abstracted via a unified JSB interface injected through the preload script.

To improve startup performance, the client creates a hidden main window with a lightweight splash page, shows it after rendering, then loads the full main page. A hidden playback window is prepared in advance, enabling fast video playback on demand. Windows are hidden rather than destroyed on close to allow rapid re‑opening.

Energy‑Saving Mode

If the app remains hidden in the system tray for a configurable period, it enters an energy‑saving mode that terminates rendering processes to free resources. Re‑opening the app follows the same fast window creation flow.

Engineering Build

Both processes are written in TypeScript, with a shared common layer for types and constants. The project structure is:

bilibili-electron
├── app/                # Build output
├── build/              # Build resources
├── dist/               # Installer packages
├── scripts/
│   └── build.main.ts   # Main‑process build config
├── src/
│   ├── common/         # Shared types
│   ├── main/           # Main‑process code
│   └── render/          # Renderer‑process code
├── electron-builder.config.js   # Installer configuration
├── vite.config.ts              # Renderer build config
└── package.json

The release package is built via yarn build:prod . To protect the binary, the team applies a combination of code obfuscation, AES‑256 symmetric encryption, bytecode handling, WASM decryption, and hash verification.

During startup, the appropriate bytecode entry is selected based on OS and architecture, decrypted, executed, and its hash is validated before the app proceeds.

Packaging uses electron‑builder . macOS installers are generated directly, while Windows uses a custom NSIS + Qt one‑click installer.

Initially, updates required full package downloads. Since version 1.9.x, incremental updates replace only the app.asar bundle, reducing download size and improving user experience.

Playback Experience

The client adopts a dual‑window model (main window + playback window) similar to other video platforms. It uses the web‑based Nano player, offering advanced features such as danmaku, playback settings, and hotkeys. Compared to the web page, the PC client shows better first‑frame latency and lower stutter, though error rates are slightly higher due to additional edge cases.

Features like “small window” mode allow the playback window to stay on top, resize without black bars, and support picture‑in‑picture‑like interactions.

Quality Assurance

Each release undergoes a strict testing pipeline: integration testing four days before launch, full‑package regression two days prior, and automated testing via the Magic Mirror platform. A custom CLI tool streamlines Fawkes build configuration, channel selection, signing, and deployment, reducing human error.

Release and Metrics

The PC client launched on May 10 2022 across Bilibili’s web homepage, download center, Microsoft Store, Lenovo Store, Huawei AppGallery, and Tencent Guard. Since launch, daily active users have grown to over 3 million, with the client accounting for ~40 % of total installations and a steady increase in channel‑specific installs.

TypeScriptarchitectureelectronsoftware engineeringNode.jsVue.jsPC client
Bilibili Tech
Written by

Bilibili Tech

Provides introductions and tutorials on Bilibili-related technologies.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.