Documentation A ZoneMinder client for web, desktop, iOS, and Android.
$ npx -y skills add ZoneMinder/zmNinjaNg --agent claude-code
A ZoneMinder client for web, desktop, iOS, and Android. It shows live camera feeds, a montage of many cameras at once, and events on a timeline, and has an AI chat agent you can ask about your cameras. It is a rewrite of the original zmNinja, built on React, TypeScript, Capacitor, and Electron.
qwen3:8b on your Ollama server, or Qwen3 4B on device. The models built into phones (Apple Intelligence, Gemini Nano) scored lower in our evals.I (Pliablepixels) don't plan to support zmNinjaNg with any urgency. Please don't ping me and expect quick answers. ZoneMinder however does plan to offer limited support, just like it did with zmNinja.
Claude Code agents write most of the code in zmNinjaNg, zmesNg, and pyzmNg. That is how I was able to rewrite zmNinja, and I don't plan to change it, because I wouldn't have time to keep extending the app otherwise. I read and review the design as changes land, and I've spent a lot of time with Claude writing the rules the agents follow.
I'm happy to accept PRs, including ones written by agents, as long as they aren't AI slop. Coding agents often write custom code where the codebase already has a helper, and they make mistakes, so every PR has to follow these rules:
npm run gates from app/ and make sure it passes before you open a PR. Chapter 14 explains how agents work in this repo.If you're setting up automated builds via GitHub Actions, you need to enable write permissions:
This allows the workflows to create GitHub releases automatically when you push a tag.
git clone https://github.com/ZoneMinder/zmNinjaNg
cd zmNinjaNg/app
npm install
# Desktop development
npm run electron:dev # Electron shell (Chromium)
Desktop builds use Electron (bundles its own Chromium).
npm run electron:build # -> desktop_release_builds/electron/
On macOS, the build signs with the Developer ID and notarizes when APPLE_ID, APPLE_PASSWORD, and APPLE_TEAM_ID are set in the environment. Append :nosign for an unsigned build:
npm run electron:build:nosign
The target folder is wiped at the start of each build.
npm run build # Output: app/dist/
npm run preview # Preview the production build
Deploy the web build (app/dist/) to Netlify, Vercel, GitHub Pages, AWS S3, etc.
The project has unit tests and end-to-end (E2E) tests for web and devices. All testing commands run from app/.
npm run test:unit # Run all unit tests
npm run test:unit -- --watch # Watch mode
npm run test:coverage # With coverage report
Uses Playwright with Gherkin .feature files against a real ZoneMinder server. Configure credentials in app/.env.
npm run test:e2e # All web E2E tests
npm run test:e2e -- tests/features/dashboard.feature # Single feature
npm run test:e2e -- --headed # See the browser
npm run test:all # Unit + web E2E
Tests run on the Android emulator and iOS simulators (phone + tablet). Each platform uses shell scripts that handle building, booting, and running tests.
bash scripts/test-android.sh # Android emulator (Playwright via CDP)
bash scripts/test-ios.sh phone # iPhone simulator (WebDriverIO + Appium)
bash scripts/test-ios.sh tablet # iPad simulator (WebDriverIO + Appium)
bash scripts/test-all-platforms.sh # All platforms sequentially
Device tests require one-time setup (Xcode, Android Studio, Appium, etc.). Run npm run test:platform:setup to verify your machine is ready. See app/tests/README.md for setup instructions and docs/developer-guide/06-testing-strategy.rst for the full testing guide.
pip install -r docs/requirements.txt sphinx-autobuild && cd docs && make clean && make html && sphinx-autobuild . _build/html
scripts/make_release.sh. It tags the current state and triggers release buildsmake_release.sh offers to publish to the App Store and Google Play in one prompt. Both land as drafts, so nothing reaches users until you release them in the respective console. scripts/upload-ios.sh and scripts/upload-android.sh also run on their own to publish a release tagged earlier. Setup is in the iOS and Android build guidesapp/package.json is the source of truth for the version numbernpm run notice <version> to draft a short in-app "what's new" notice from the closed issues since the last release (Claude writes it, you approve it). It only writes docs/notices.json for you to test; nothing is committed. To discard a test draft, run git checkout -- docs/notices.json. On minor/major releases make_release.sh offers to generate one for you. Details in the release notices guide.zmninjang is a Claude Code plugin with 3 hand-picked skills, indexed on Flowy in the Mobile category. Install it with the command on its page. It includes add-language, fable-review, mine-history. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it