RhineLabUI: a Three.js rebuild of the Rhine Lab terminal from Arknights
Rhine Lab archive interface built with TypeScript and Three.js
At a glance
- What is it?
- RhineLabUI is an unofficial browser reconstruction of the Rhine Lab archive terminal, built with TypeScript, Three.js and Vite. It is a visual and interaction project first, an application second, and the README is candid about which parts are still rough.
- Who is it for?
- Adopt RhineLabUI if you want a studied reference for Three.js scene timelines, glass material transitions and DOM-driven opening sequences, or if you want a Rhine Lab archive interface you can run locally. Do not adopt it as a general-purpose archive or document platform: the content is a fixed set of 40 entries in content/archives.json, and the README does not document a path for replacing that data with your own.
- 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 3 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 16, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What RhineLabUI actually is, and who it is for
RhineLabUI is described in its README as an unofficial recreation of the terminal interface from the Arknights special video "Rhine Lab: Access". The opening sequence, the five-column archive array, the extraction animation and the document decryption are all modelled on that footage. The README states the project uses the original video's 5 to 40 second range as its main visual and motion reference, with the actual opening starting from a white frame at 6.76 seconds, and it cites roughly 41 seconds and 46 to 51 seconds for the internal structure shots.
That framing matters when you decide whether to care. This is not a library and it is not an archive product with a pluggable backend. It is a single-page application whose subject is a fictional corporate terminal, and the interesting engineering is in how the scene, the DOM overlay and the animation timeline are kept in step. If you are building a Three.js interface that has to transition between a 2D opening and a live 3D scene without a visible seam, the source layout is worth reading. If you need to store and search your own documents, this is the wrong starting point.
The intended audience is narrow and the README does not pretend otherwise. Layout is calibrated to 1920 x 1080 and scales proportionally, and the text says the interface is aimed mainly at desktop and landscape screens. Touch and portrait are supported, but the baseline is a wide window.
How the scene, the timeline and the DOM stay in sync
The repository splits responsibilities by file rather than by feature. src/main.ts holds page state, archive reading, search, favourites and keyboard shortcuts. src/boot.ts and src/boot-motion.ts own the opening interface and its frame-by-frame timeline. src/scene.ts and src/archive-loop.ts own the Three.js scene, the looping array, and the extract-and-return motion. src/model-viewer.ts is the standalone 360 degree viewer with its disassembly animation, and src/decryption.ts plus src/document-decryption.ts drive the model decryption path and the synchronised reveal of the document text.
The README describes the opening as driven by DOM and SVG together with a scene timeline, while the 3D models are rendered live at runtime. That split explains why the boot sequence can do per-character typing, a circling ring and continuous logo strokes without those elements living in the WebGL context. The handoff is the hard part: the array has to be laid out against the real camera and screen bounds, and the README notes the array is arranged and cropped to the actual viewport so that wide screens do not expose the end of the row.
Content is data, not markup. content/archives.json holds the 40 entries across five categories with eight each, and src/data.ts defines the archive types. A predev and prebuild step runs scripts/export-records.mjs, which the README describes as producing data shared between the page and the download. The loop itself wraps in both directions: left and right change category, up and down page through a category, and returning to a column restores the previous selection.
Installing RhineLabUI and running the archive interface locally
The README requires Node.js 22.12 or newer and says Node.js 24 is acceptable, plus a modern desktop browser with WebGL 2. No API key is needed and there is no backend service to start. Clone the repository and move into it:
git clone https://github.com/LBEILC/RhineLabUI.git
cd RhineLabUIInstall dependencies with npm ci and start the development server. The first install needs network access because fonts and models are fetched at that point, and the postinstall script patches a rolling-number dependency before anything else runs.
npm ci
npm run devOpen the address the terminal prints, which the README gives as usually http://127.0.0.1:5173/. If that port is taken, trust the actual output rather than the documented default. On Windows the repository also ships 启动终端.cmd, which installs dependencies on first run, starts the local service and opens the browser.
For a production build, the README gives two commands. The build output lands in dist/ and the README states it must be served over a static HTTP server, not opened by double-clicking dist/index.html.
npm run build
npm run previewThe first load pulls fonts and GLB models. The README notes that four official MiSans WOFF2 files are kept in the project, about 19.7 MB in total, and are loaded according to actual use. Quality presets are performance, original, high and extreme, with original as the default, and a separate super performance mode reduces 3D rendering cost while keeping the animations.
The 40-entry content model is the real ceiling
The most concrete limitation is not graphical. The README states there are five categories with eight archives each, 40 in total, and that content/archives.json is the shared source for both the page and the download. Nothing in the README describes an import path, a schema migration or a way to point the interface at another dataset. If you want this terminal to display your own records, you are editing JSON by hand and re-running the export script, and the README does not document rollback if a change breaks the layout.
There is a content check in package.json, check:content, which runs scripts/check-content.mjs under Node's experimental type stripping. That suggests the project validates its own data shape, but the README does not state what the validator enforces, so treat it as a signal that the format is constrained rather than as documentation of the constraints.
Search is also bounded by the same data. The README lists searchable fields as number, title, English name, department, related personnel and category, which means free-text search over document bodies is not described. Favourites and preferences are stored in the current browser, so they do not follow a user across machines, and clearing site data removes them.
Performance is a genuine constraint on weaker hardware. The README offers a performance preset and a super performance mode precisely because the default original preset is not guaranteed to be smooth, and a reduced-motion setting exists for simplifying camera, text and reveal animations.
Where RhineLabUI stops and RhineLabWallpaper begins
The repository's own history is the clearest alternative to consider, and it is not a competitor in the usual sense. The README states the Wallpaper Engine version was split into a separate public repository, RhineLabWallpaper, and that future wallpaper features are developed on that repository's main branch. The original wallpaper branch, codex/wallpaper-engine, is kept in RhineLabUI as a migration record. If your goal is a live desktop background rather than a browser page, the difference in approach is concrete: the wallpaper build uses a different Vite mode and output directory, and the README states the wallpaper build does not enable PWA.
git clone https://github.com/LBEILC/RhineLabWallpaper.git
cd RhineLabWallpaper
npm ci
npm run build:wallpaperThe output goes to release/wallpaper, and the README says you open the index.html inside it from the Wallpaper Engine editor. The wallpaper variant adds a desktop workbench mode with clock, agenda, countdown, system media information and a focus timer, plus music reactivity and a ripple mini-game, none of which are described as part of the web version. The two share the archive and 3D foundation but diverge on host integration.
For a browser-hosted 3D archive that is not tied to Wallpaper Engine, the web repository remains the maintained one. The README does not name any other project as a comparable alternative, and this article has no basis to claim one.
Licence, maintenance and what an upgrade costs you
RhineLabUI is MIT licensed, and package.json marks the package as private with version 1.0.0. The repository is not archived and the last push was on 2026-09-15, two days before this article's reference point, so the web version is being worked on now. There are no retrieved releases, which means there is no tagged version to pin against; you track main.
That has a practical consequence. Because the project has no release cadence, an upgrade means pulling main and re-reading the integration notes. The README points to verification/WEB-INTEGRATION.md for the scope and validation of the main-branch integration, and that file is the closest thing to a changelog the README offers. Dependencies are thin: three at ^0.183.0 and @kitlangton/rolling-number pinned at 0.4.1, with TypeScript, Vite and Prettier as dev dependencies. The pinned rolling-number package is patched by scripts/patch-rolling-number.mjs on both postinstall and prebuild, so a dependency bump there is not a drop-in change.
MIT terms let you reuse and modify the code, but the licence covers the source, not the underlying property. The README calls the project an unofficial recreation of an Arknights special video, and the archive content, names and visual identity come from that source. Whether you can ship a derivative publicly is a question for your own legal review, not something this article can settle.
Upgrade cost is dominated by the asset pipeline rather than the JavaScript. Fonts, GLB models and a build-time PWA step all run during build, and the README notes the wallpaper build deliberately skips PWA, so the two build paths are not interchangeable.
Editorial conclusion
Adopt RhineLabUI if you want a studied reference for Three.js scene timelines, glass material transitions and DOM-driven opening sequences, or if you want a Rhine Lab archive interface you can run locally. Do not adopt it as a general-purpose archive or document platform: the content is a fixed set of 40 entries in content/archives.json, and the README does not document a path for replacing that data with your own. Before you build on it, confirm the Node.js 22.12 floor on your machine, run npm run check:content against content/archives.json to see what the content validator actually enforces, and open a build with npm run preview rather than double-clicking dist/index.html, because the README states the built output must be served over HTTP.
Frequently asked questions
What is RhineLabUI?
It is an unofficial recreation of the Rhine Lab archive terminal from the Arknights special video "Rhine Lab: Access", built with TypeScript, Three.js and Vite. The README describes it as an interactive three-dimensional interface with search, favourites, document reading, model disassembly and sound settings layered on top of the recreated opening and archive array.
How do I install and run RhineLabUI locally?
You need Node.js 22.12 or newer and a browser with WebGL 2. Clone the repository, run npm ci, then npm run dev, and open the address the terminal prints, which the README gives as usually http://127.0.0.1:5173/. No API key or backend service is required.
Is Rhine Lab evil in Arknights?
The repository does not discuss the Rhine Lab storyline, so this article cannot answer it. RhineLabUI only reproduces the terminal interface and a set of 40 archive entries defined in content/archives.json.
Community notes