# PageSpy Web wires seven SDK badges to three repositories and one backend binary

> The remote debugging platform documents two deployment paths and three deployment badges, ships a Dockerfile that compiles the Go backend but never the vite client, and marks its own frontend package private so the npm install you are told to run belongs to the API instead.

**HuolalaTech/page-spy-web** — A remote debugging platform you'll definitely find useful. Lightweight, cross-platform, out-of-box debugging tool

- Repository: https://github.com/HuolalaTech/page-spy-web
- Website: https://www.pagespy.org
- Stars: 5,633 · Forks: 355
- Language: TypeScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/huolalatech-page-spy-web

## postinstall runs a shell script the README never explains

The first thing to notice in the script table is that the package is marked private, so nothing here can be published to npm under this name, and the second is that installing it still executes a shell script. The postinstall hook runs a file from the scripts directory with bash, and no section of the README says what it copies or why. Two more shell scripts guard the release flow rather than the install: preversion checks the branch and postversion checks the release, which means the guard runs only when the version command is used, not when a tag is pushed from somewhere else. A committed .env file and a .npmrc sit at the root next to .gitignore, and the values inside them are not described anywhere in the documentation. For a repository whose purpose is capturing other people's application data, that install-time script is the first file worth reading.

## The release badge reads package.json from a branch named release

The badge that reports the current release does not read a tag. Its image path asks for the package.json of this repository on a branch called release, and its link opens that same file on that branch, while the repository's default branch is main. The value in package.json reads 2.4.10, and the three releases listed for the project are v2.4.10, v2.4.9 and v2.4.8, so the two agree today. The cadence does not: all three are patch numbers, two of them three days apart, and no minor or major tag appears among them. The link definition at the top of the file also points its repository shorthand at a different name, the same .git URL ending in page-spy rather than page-spy-web, which is where the build status and coverage badges are wired.

## Build, coverage and API badges are wired to other repositories

Of the nine version badges under the title, three point away from this project. The build status and the coverage percentage both resolve to the sibling repository named page-spy on its main branch, so the coverage figure shown to a visitor describes that repository's test runs and not this one's. Two more belong to the backend: the API version badge reads tags from page-spy-api, and the Go version badge reads the go.mod of page-spy-api on its master branch, which is a different default branch name from the main branch used here. A sixth badge, the weekly download counter, is wired to the npm package of the API rather than to anything in this tree. That leaves the browser, WeChat, Alipay, UniApp and Taro badges as the only ones describing the SDKs this repository's own upgrade command touches.

## The Harmony SDK sits outside the scope the upgrade command covers

The script that keeps SDK versions in step runs a yarn upgrade with a pattern covering one scope only, the huolala-tech scope. Five of the six SDK badges point at packages in that scope, but the Harmony badge does not: its version image asks for a package under the shorter huolala scope, and its link goes to an OpenHarmony package detail page rather than to npm. So the one command meant to keep every SDK current cannot see the Harmony one, and that package's version has to be tracked by hand. The same package is the only one whose version image is served from a third-party mirror domain rather than from the usual badge service, which means a reader has to trust that mirror to learn the current release.

## Three deploy badges, two deployment sections, one port

The badge row offers three ways to install, and the body of the file gives two. The Node and Docker badges have a section each; the Baota badge has none, and its link goes to a documentation page on the project's site. The two documented paths converge on the same port. The Node route adds the backend package globally, with yarn or npm, then asks you to run the page-spy-api command in a terminal and open localhost on port 6752. The Docker route publishes that same port from a container image and mounts two host directories, one for logs and one for data.

```bash
yarn global add @huolala-tech/page-spy-api@latest

# if you use npm

npm install -g @huolala-tech/page-spy-api@latest
```

```bash
docker run -d --restart=always -v ./log:/app/log -v ./data:/app/data -p 6752:6752 --name="pageSpy" ghcr.io/huolalatech/page-spy-web:latest
```

The repository's own development script starts the server by invoking that same binary, so the local frontend workflow depends on the global install above having been done first.

## The Dockerfile compiles the Go backend and never touches the client

The image built for the repository named page-spy-web compiles Go. A first stage on golang:1.23 copies backend/go.mod and go.sum, downloads modules, copies the backend directory and builds one static binary with cgo disabled, and a second stage on alpine copies that binary and runs it as the container command.

```
FROM golang:1.23 AS backend
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
FROM alpine:latest
CMD ["/app/main"]
```

No line in the file invokes the vite builds that produce the browser client, and nothing states where those assets come from, so the client half of the debugging interface is missing from the image definition. Two further details are worth noting on their own: the final base is the moving tag alpine:latest rather than a pinned release, and the file declares no user, so the process runs as root inside the container.

## Lint stops at ./src and no script type checks the tree

The lint command takes four extensions and one directory, ending at ./src, so files under backend/, scripts/ and the configuration at the root are outside its reach, which is consistent with a Go backend and a shell-heavy scripts folder but leaves those scripts unchecked. There is a tsconfig.json at the root and no script that runs the TypeScript compiler, so nothing in the table verifies types; the closest thing is the eslint pass with the TypeScript parser. The build side is split into two vite modes instead, one for the documentation site and one for the client, and both builds run a record generation step first, so the documentation and the debugging client are produced from one tree by two different entries. The dependency list explains why: markdown and mdx tooling, plus rrweb type definitions, sit in devDependencies for that documentation build.

## The Why section holds one proverb, and the Intro names a platform with no SDK

The section headed Why PageSpy contains a single quoted line about pictures and words, and nothing else. The reasoning that does exist is in the Intro, which explains the mechanism: the tool wraps native APIs, filters and transforms the arguments when those methods run, serializes them in a standard format and sends them to a client that renders them in an interface resembling a local devtools console. The Intro also names React Native among the supported platforms, while the badge row above it lists SDKs for browsers, WeChat, Alipay, UniApp, Taro and Harmony, with no React Native package among them. The remaining documentation, including the deployment guides the badges link to and the FAQ, lives on the project's own site rather than in this repository.

## Conclusion

Read this repository as the client half of a two-part system: the thing you can install from npm is the Go backend, and the TypeScript tree here is what a vite build turns into the browser client. That split explains the private package flag, the missing client build in the Dockerfile, and the three deploy badges pointing at documentation you have to fetch elsewhere. Before you run either documented command, decide whether port 6752 should be reachable from outside your machine, since the published form of that mapping binds every interface. And check the SDK you actually need against the scope the upgrade command covers, because the Harmony package sits outside it.

## FAQ

### How do I start the PageSpy server on my own machine?

Install the backend globally with yarn global add @huolala-tech/page-spy-api@latest or npm install -g @huolala-tech/page-spy-api@latest, then run page-spy-api in the terminal and open http://localhost:6752. The repository's start:server script does the same by invoking that binary, so the frontend development flow assumes the global install already happened.

### Does the documented Docker command for PageSpy expose port 6752 to the network?

The command publishes the port with the mapping -p 6752:6752, and Docker binds that to every interface unless you name an address, so the debugging interface is reachable from outside the machine as written. It also sets --restart=always and mounts ./log and ./data from the host, and the container image is ghcr.io/huolalatech/page-spy-web:latest.

### Which platforms does PageSpy actually ship an SDK for?

The Intro names Web, React Native, Mini Programs and HarmonyOS apps. The badge row shows packages for browser, WeChat, Alipay, UniApp, Taro and Harmony, and the visible list has no React Native package among them, so the Intro and the badges do not line up.

### Can I install page-spy-web from npm myself?

Not as this package. package.json sets private to true, which blocks publishing it. What the instructions add to your machine is the backend, @huolala-tech/page-spy-api, and the Harmony SDK is published under a different scope entirely, @huolala/page-spy-harmony.

### Where does the browser client inside the PageSpy Docker image come from?

The Dockerfile does not say and does not build it. It compiles the Go backend from backend/ into a single binary, copies that into alpine and runs it as the container command, and never invokes the vite builds that produce the client.

## Sources

- [HuolalaTech/page-spy-web on GitHub](https://github.com/HuolalaTech/page-spy-web)
- [License: MIT](https://github.com/HuolalaTech/page-spy-web/blob/main/LICENSE)
- [Project website](https://www.pagespy.org)
- [README](https://github.com/HuolalaTech/page-spy-web/blob/main/README.md)
- [Releases](https://github.com/HuolalaTech/page-spy-web/releases)

---

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