{"id":34683928,"url":"https://github.com/pliablepixels/zmng","last_synced_at":"2026-01-17T08:00:26.353Z","repository":{"id":326706045,"uuid":"1105411474","full_name":"pliablepixels/zmNg","owner":"pliablepixels","description":"A complete rewrite of zmNinja","archived":false,"fork":false,"pushed_at":"2026-01-11T22:04:46.000Z","size":66988,"stargazers_count":5,"open_issues_count":1,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T21:15:16.122Z","etag":null,"topics":["agentic-ai","antigravity","cctv","codex","copilot","mobile","nvr","react","tauri","zmninja","zoneminder"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pliablepixels.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-27T15:12:26.000Z","updated_at":"2026-01-12T19:55:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pliablepixels/zmNg","commit_stats":null,"previous_names":["pliablepixels/zmng"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/pliablepixels/zmNg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pliablepixels%2FzmNg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pliablepixels%2FzmNg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pliablepixels%2FzmNg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pliablepixels%2FzmNg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pliablepixels","download_url":"https://codeload.github.com/pliablepixels/zmNg/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pliablepixels%2FzmNg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28504358,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-ai","antigravity","cctv","codex","copilot","mobile","nvr","react","tauri","zmninja","zoneminder"],"created_at":"2025-12-24T21:38:27.348Z","updated_at":"2026-01-17T08:00:26.332Z","avatar_url":"https://github.com/pliablepixels.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zmNg - Modern ZoneMinder Client\n\n[![Build Android](https://github.com/pliablepixels/zmNg/actions/workflows/build-android.yml/badge.svg)](https://github.com/pliablepixels/zmNg/actions/workflows/build-android.yml)\n[![Build macOS](https://github.com/pliablepixels/zmNg/actions/workflows/build-macos.yml/badge.svg)](https://github.com/pliablepixels/zmNg/actions/workflows/build-macos.yml)\n[![Build Windows](https://github.com/pliablepixels/zmNg/actions/workflows/build-windows.yml/badge.svg)](https://github.com/pliablepixels/zmNg/actions/workflows/build-windows.yml)\n[![Build Linux](https://github.com/pliablepixels/zmNg/actions/workflows/build-linux-amd64.yml/badge.svg)](https://github.com/pliablepixels/zmNg/actions/workflows/build-linux-amd64.yml)\n[![Tests](https://github.com/pliablepixels/zmNg/actions/workflows/test.yml/badge.svg)](https://github.com/pliablepixels/zmNg/actions/workflows/test.yml)\n[![GitHub release](https://img.shields.io/github/v/release/pliablepixels/zmNg)](https://github.com/pliablepixels/zmNg/releases)\n[![GitHub downloads](https://img.shields.io/github/downloads/pliablepixels/zmNg/total?cache=none)](https://github.com/pliablepixels/zmNg/releases)\n\n\u003cimg src=\"app/assets/logo.png\" align=\"right\" width=\"120\" /\u003e\n\nA modern web and mobile application for ZoneMinder, providing a clean, intuitive interface for viewing live camera feeds, reviewing events, and managing multiple server profiles. It is a ground-up rewrite of the original [zmNinja](https://zmninja.zoneminder.com/) application, using modern web technologies and a more intuitive user interface. The code was 99% Claude CLI generated when I first started. Since then, I've been using `codex`, `antigravity` and `copilot w/Gemini3` depending on where I have tokens. `claude` is still head and shoulders above the rest, but codex isn't bad. \n\nWatch a video of the demo [HERE](https://youtu.be/ces_2ap-htc)\n\n### Screenshots\n\u003csub\u003e\u003csup\u003eframes courtesy [appleframer](https://appleframer.com/)\u003c/sup\u003e\u003c/sub\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/1.png\" width=\"32%\" /\u003e\n  \u003cimg src=\"images/2.png\" width=\"32%\" /\u003e\n  \u003cimg src=\"images/3.png\" width=\"32%\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/4.png\" width=\"32%\" /\u003e\n  \u003cimg src=\"images/5.png\" width=\"32%\" /\u003e\n  \u003cimg src=\"images/6.png\" width=\"32%\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/7.png\" width=\"32%\" /\u003e\n  \u003cimg src=\"images/8.png\" width=\"32%\" /\u003e\n  \u003cimg src=\"images/9.png\" width=\"32%\" /\u003e\n\u003c/p\u003e\n\n\n### Agentic AI, you and me\n\nAgentic AI and me: I built the very first version of zmNinja over several months and built in more features over multiple years. I built the first version of zmNg over 2.5 days with almost as many features as the last version of zmNinja. My agent of choice was Claude CLI (with Antigraviy and Copilot when tokens expired). Honestly, zmNg is better structured, more modern and easier to support than zmNinja (which uses tons of now deprecated tech and other code issues). I built it to learn how to effectively use agentic coding tools and wow, was I pleasantly surprised. zmNg has better tests, better release workflow (100% automated), easier to read code and better UX as well (imho).\n\nAgentic AI and you: I don't plan to support zmNg at all. Please don't ping me and expect quick answers. \nInstead, treat this as \"personal software\" - i.e. download the code and fix it yourself. If you don't code, or do code, but aren't familiar with the environment of zmNg, I'd encourage you to use an agentic AI tool to help you along the way. Pick one you prefer. Remember, for mobile support, you'll need to generate your own FCM tokens. See mobile guides later for more.\n\n\n#### Pull Requests\n\nI am happy to accept PRs, but I don't want [AI slop](https://en.wikipedia.org/wiki/AI_slop). Funny I am saying this, given this repo is largely AI agent(s) generated. The difference is I understand the code and know how to prompt it with directions that make the tools generate better quality code. Remember these tools are amazing but love to write a lot of code doing custom things when simpler/better means are available. They also make mistakes. So here are the rules:\n\n- If you have not read and understood the code you generated, please don't PR it to my repo. Please continue to extend it yourself\n- See my agent rules for [CLAUDE](CLAUDE.md) here - please make sure to use it in your agent\n- Before you PR, please do a code review\n\n### Limitations \u0026 Notes\n- Self signed/untrusted certificates are not supported. It's not worth the effort to support them. Please use LetsEncrypt or other free certs, or just use http.\n- Push notifications won't work till you build the mobile apps yourself (web notifications, when the app is in foreground will work). See [Android](docs/building/ANDROID.md) and [iOS](docs/building/IOS.md) guides.\n- If you want push notifications, you'll have to use a newer [Event Server](https://github.com/pliablepixels/zm_docker_macos) that has support for direct FCM (yep, you don't need the proxy cloud function anymore)\n\n\n## Quick Start\n\n### Binaries\n- Download binaries from [zmNg Releases](https://github.com/pliablepixels/zmNg/releases)\n- iOS is not uploaded - I don't have a dev account anymore\n- I use Github workflows and runners to automatically build release binaries [here](https://github.com/pliablepixels/zmNg/tree/main/.github/workflows). Binaries are built for specific platforms. If the binary doesn't work for your linux distro, look at those files\n\n## Build from Source\n\n### Prerequisites\n- Node.js ^20.19.0 || \u003e=22.12.0 and npm ([download](https://nodejs.org/en/download))\n- For desktop builds: Rust toolchain (for Tauri builds)\n\n### GitHub Actions Setup (For Automated Releases)\n\nIf you're setting up automated builds via GitHub Actions, you need to enable write permissions:\n\n1. Go to your repository on GitHub\n2. Navigate to **Settings** → **Actions** → **General**\n3. Scroll down to **Workflow permissions**\n4. Select **\"Read and write permissions\"**\n5. Check **\"Allow GitHub Actions to create and approve pull requests\"** (optional)\n6. Click **Save**\n\nThis allows the workflows to create GitHub releases automatically when you push a tag.\n\n### Desktop Development\n\n```bash\ngit clone https://github.com/pliablepixels/zmNg\ncd zmNg/app\nnpm install\n\n# Desktop development (Tauri - native app)\nnpm run tauri:dev\n```\n\n### Desktop Production Builds\n\n#### Desktop production build (Tauri): Recommended\n```bash\nnpm run tauri:build    # Output: src-tauri/target/release/bundle/\n```\n#### Web production build\n```bash\nnpm run build          # Output: dist/\nnpm run preview        # Preview production build\n```\nDeploy web build (`dist/`) to: Netlify, Vercel, GitHub Pages, AWS S3, etc.\n\n### Mobile Builds\n\n- For Android setup and builds, see [ANDROID](docs/building/ANDROID.md)\n- For iOS setup and builds, see [IOS](docs/building/IOS.md)\n\n## Testing\n\nThe project includes unit tests and end-to-end (E2E) tests to ensure code quality and reliability.\n\n### Unit Tests\n\nRun unit tests with Vitest:\n\n```bash\ncd zmNg/app\n\n# Run all unit tests\nnpm run test:unit\n\n# Run tests in watch mode\nnpm run test:unit -- --watch\n\n# Run with coverage report\nnpm run test:coverage\n\n# Run specific test file\nnpm run test:unit -- src/lib/__tests__/url-builder.test.ts\n```\n\nCoverage reports are generated in `coverage/` directory.\n\n### End-to-End Tests\n\nRun E2E tests with Playwright:\n\n```bash\n# Run E2E tests\nnpm run test:e2e\n\n# Run with UI mode (visual debugging)\nnpm run test:e2e:ui\n\n# Run specific test file\nnpm run test:e2e -- tests/monitors.spec.ts\n```\n\n**Note:** E2E tests require a running ZoneMinder server. Configure test credentials in `.env` file (see `.env.example`).\n\n### Run All Tests\n\n```bash\n# Run both unit and E2E tests\nnpm run test:all\n```\n\n### Making releases\n- See `scripts/release.sh` [here](scripts/release.sh). This automatically tags the current state and triggers release builds\n\n### New vs Old\n[View Comparison with zmNinja](notes/COMPARISON.md)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpliablepixels%2Fzmng","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpliablepixels%2Fzmng","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpliablepixels%2Fzmng/lists"}