foru17/neko-masterPublic

A modern and elegant dashboard for network traffic visualization and analysis.

AI summary: A real-time network traffic monitoring and auditing tool with multi-gateway support.

Stars
3.2K
+38 today
Forks
205
Watchers
8
Open issues
20
Open PRs
5
Contributors
~3
Commits
175
Branches
3

TypeScriptMITCreated Feb 5, 2026Last push 4d agoLatest release agent-v1.4.5+120 stars this week+120 this month

Star history

since Feb 8, 2026
01K2K3KFeb 2026Apr 2026Jun 2026Aug 2026
3.2K stars as of Aug 7, 2026, tracked back to Feb 8, 2026. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulMonWedFri2025-08-02: 0 commits2025-08-03: 0 commits2025-08-04: 0 commits2025-08-05: 0 commits2025-08-06: 0 commits2025-08-07: 0 commits2025-08-08: 0 commits2025-08-09: 0 commits2025-08-10: 0 commits2025-08-11: 0 commits2025-08-12: 0 commits2025-08-13: 0 commits2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 0 commits2025-08-17: 0 commits2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 0 commits2025-08-21: 0 commits2025-08-22: 0 commits2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 0 commits2025-09-04: 0 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 0 commits2025-09-09: 0 commits2025-09-10: 0 commits2025-09-11: 0 commits2025-09-12: 0 commits2025-09-13: 0 commits2025-09-14: 0 commits2025-09-15: 0 commits2025-09-16: 0 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 0 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 0 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 0 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 0 commits2026-02-06: 12 commits2026-02-07: 7 commits2026-02-08: 9 commits2026-02-09: 7 commits2026-02-10: 8 commits2026-02-11: 3 commits2026-02-12: 4 commits2026-02-13: 9 commits2026-02-14: 6 commits2026-02-15: 2 commits2026-02-16: 7 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 9 commits2026-02-20: 9 commits2026-02-21: 10 commits2026-02-22: 17 commits2026-02-23: 1 commit2026-02-24: 6 commits2026-02-25: 4 commits2026-02-26: 3 commits2026-02-27: 0 commits2026-02-28: 0 commits2026-03-01: 1 commit2026-03-02: 0 commits2026-03-03: 1 commit2026-03-04: 0 commits2026-03-05: 0 commits2026-03-06: 0 commits2026-03-07: 0 commits2026-03-08: 0 commits2026-03-09: 0 commits2026-03-10: 0 commits2026-03-11: 1 commit2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 0 commits2026-03-17: 0 commits2026-03-18: 0 commits2026-03-19: 0 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 0 commits2026-03-24: 0 commits2026-03-25: 0 commits2026-03-26: 1 commit2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 0 commits2026-04-03: 1 commit2026-04-04: 2 commits2026-04-05: 0 commits2026-04-06: 0 commits2026-04-07: 0 commits2026-04-08: 0 commits2026-04-09: 0 commits2026-04-10: 0 commits2026-04-11: 0 commits2026-04-12: 1 commit2026-04-13: 1 commit2026-04-14: 0 commits2026-04-15: 0 commits2026-04-16: 0 commits2026-04-17: 0 commits2026-04-18: 0 commits2026-04-19: 0 commits2026-04-20: 0 commits2026-04-21: 0 commits2026-04-22: 0 commits2026-04-23: 0 commits2026-04-24: 0 commits2026-04-25: 0 commits2026-04-26: 0 commits2026-04-27: 0 commits2026-04-28: 0 commits2026-04-29: 0 commits2026-04-30: 0 commits2026-05-01: 0 commits2026-05-02: 0 commits2026-05-03: 0 commits2026-05-04: 0 commits2026-05-05: 0 commits2026-05-06: 0 commits2026-05-07: 0 commits2026-05-08: 0 commits2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 2 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 0 commits2026-05-28: 0 commits2026-05-29: 0 commits2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 0 commits2026-06-02: 0 commits2026-06-03: 0 commits2026-06-04: 0 commits2026-06-05: 0 commits2026-06-06: 0 commits2026-06-07: 0 commits2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 2 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 1 commit2026-06-19: 0 commits2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 3 commits2026-06-24: 0 commits2026-06-25: 0 commits2026-06-26: 0 commits2026-06-27: 0 commits2026-06-28: 0 commits2026-06-29: 0 commits2026-06-30: 0 commits2026-07-01: 0 commits2026-07-02: 0 commits2026-07-03: 0 commits2026-07-04: 13 commits2026-07-05: 0 commits2026-07-06: 0 commits2026-07-07: 0 commits2026-07-08: 0 commits2026-07-09: 0 commits2026-07-10: 0 commits2026-07-11: 0 commits2026-07-12: 0 commits2026-07-13: 0 commits2026-07-14: 0 commits2026-07-15: 0 commits2026-07-16: 0 commits2026-07-17: 0 commits2026-07-18: 0 commits2026-07-19: 5 commits2026-07-20: 0 commits2026-07-21: 0 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 0 commits2026-07-25: 0 commits2026-07-26: 0 commits2026-07-27: 0 commits2026-07-28: 0 commits2026-07-29: 0 commits2026-07-30: 0 commits2026-07-31: 0 commits2026-08-01: 0 commits
168 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Permissive license

    MIT

  • Continuous integration

    Automated checks passing

What neko-master does

Neko Master is a network diagnostic and monitoring application designed to provide clear visibility into network traffic. It offers real-time monitoring capabilities, allowing users to track and analyze data flowing through their systems. The tool includes features for traffic auditing and supports complex network setups with multi-gateway configurations. It aims to help developers and network administrators understand their network behavior, troubleshoot issues, and ensure proper routing. The project provides a user-friendly interface for complex network data.

Network administrators, developers, and power users who need detailed insights into their system's network activity. Anyone troubleshooting complex routing setups or auditing application traffic.

  • Real-time monitoring: Displays active network connections and traffic flow as it happens.
  • Traffic auditing: Logs and analyzes network data for security or debugging purposes.
  • Multi-gateway support: Handles complex routing scenarios involving multiple network gateways.
  • Visual interface: Provides a clear, graphical representation of network activity.
  • Cross-platform compatibility: Designed to work across different operating systems.

Where teams use it

Network troubleshooting

Diagnosing connectivity issues or identifying misconfigured routing rules.

Traffic analysis

Understanding which applications are consuming bandwidth and where data is being sent.

Security auditing

Monitoring outbound connections to detect unauthorized or suspicious network activity.

Proxy and VPN configuration

Verifying that traffic is correctly routed through specific gateways or tunnels.

Getting started: Download the appropriate release for your platform and follow the setup instructions in the README.

README

main branch

Neko Master Logo
Neko Master

See your network traffic clearly.
Real-time monitoring · Traffic auditing · Multi-gateway support

English | 中文

Stars Docker Pulls Docker Version Image Size License Docker CI Architecture Docs

Important

Disclaimer

This project is a traffic analysis and visualization tool for local gateway environments.

It does not provide any network access service, proxy subscription, or cross-network connectivity. All data is collected from the user's own network environment.

This project is open-sourced under the MIT License. We assume no responsibility for any consequences resulting from the use of this software. Please use it in compliance with applicable laws and regulations.

Neko Master Preview (Light 1) Neko Master Preview (Light 2)
Neko Master Preview (Dark 1) Neko Master Preview (Dark 2)

About the Name

Neko (ねこ) means cat in Japanese. Pronounced /ˈneɪkoʊ/ (NEH-ko).

Like a cat, Neko Master observes network traffic quietly and precisely. It is a lightweight analytics dashboard designed for modern gateway environments.

📋 Table of Contents

✨ Features

Feature Description
📊 Real-time Monitoring WebSocket real-time collection with millisecond latency
📈 Trend Analysis Multi-dimensional traffic trends: 30min / 1h / 24h
🌐 Domain Analysis View traffic, associated IPs, and connection count per domain
🗺️ IP Analysis ASN, geo-location, and associated domain display
🚀 Proxy Statistics Traffic distribution and connection count per proxy node
📱 PWA Support Install as desktop app for native experience
🌙 Dark Mode Light / Dark / System theme support
🌍 i18n Support English / Chinese seamless switching
🔄 Multi-Backend Monitor multiple OpenClash backend instances simultaneously

🚀 Quick Start

Option 1: Docker Compose (Recommended)

The repository's built-in docker-compose.yml maps 3000/3001/3002 by default. Scenarios A/B below are minimal templates for common deployments.

Scenario A: Minimal deployment (only expose 3000)

services:
  neko-master:
    image: foru17/neko-master:latest
    container_name: neko-master
    restart: unless-stopped
    ports:
      - "3000:3000" # Web UI
    volumes:
      - ./data:/app/data
      # Local MMDB (optional, files should be downloaded into ./geoip)
      - ./geoip:/app/data/geoip:ro
    environment:
      - NODE_ENV=production
      - DB_PATH=/app/data/stats.db
      - COOKIE_SECRET=${COOKIE_SECRET}

Recommended in .env (same directory as docker-compose.yml): COOKIE_SECRET=<at least 32-byte random string> (generate with openssl rand -hex 32)

This mode is fully upgrade-compatible and works out of the box. If WS is not routed, the app falls back to HTTP polling automatically.

Scenario B: Real-time WebSocket (recommended with reverse proxy)

services:
  neko-master:
    image: foru17/neko-master:latest
    container_name: neko-master
    restart: unless-stopped
    ports:
      - "3000:3000" # Web UI
      - "3002:3002" # WebSocket (for Nginx / Tunnel forwarding)
    volumes:
      - ./data:/app/data
      # Local MMDB (optional, files should be downloaded into ./geoip)
      - ./geoip:/app/data/geoip:ro
    environment:
      - NODE_ENV=production
      - DB_PATH=/app/data/stats.db
      - COOKIE_SECRET=${COOKIE_SECRET}

Then run:

docker compose up -d

Open http://localhost:3000 to get started.

If you use the repository's built-in Compose file (default 3000/3001/3002), run the same command.

Option 2: Docker Run

# Generate a fixed cookie secret first (for session persistence)
export COOKIE_SECRET="$(openssl rand -hex 32)"
# Minimal (only 3000)
docker run -d \
  --name neko-master \
  -p 3000:3000 \
  -v $(pwd)/data:/app/data \
  -e COOKIE_SECRET="$COOKIE_SECRET" \
  --restart unless-stopped \
  foru17/neko-master:latest

# Real-time WS (with reverse proxy)
docker run -d \
  --name neko-master \
  -p 3000:3000 \
  -p 3002:3002 \
  -v $(pwd)/data:/app/data \
  -e COOKIE_SECRET="$COOKIE_SECRET" \
  --restart unless-stopped \
  foru17/neko-master:latest

Open http://localhost:3000 to get started.

The frontend uses same-origin /api by default, so port 3001 is usually not required externally. For real-time WS, your reverse proxy/tunnel must be able to reach port 3002. If not, the app falls back to ~5s HTTP polling.

For docker run, change external ports using -p mappings directly. Only if you use direct WS access (no reverse proxy) and external WS port is not 3002, also pass -e WS_EXTERNAL_PORT=<external-ws-port>.

Local MMDB lookup mode (optional): mount -v $(pwd)/geoip:/app/data/geoip:ro, then switch source to Local in Settings -> Preferences -> IP Lookup Source.

Option 3: One-Click Script

Automatically detects port conflicts and configures everything:

# Using curl
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash

# Or using wget
wget -qO- https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash

The script will automatically:

  • ✅ Download docker-compose.yml
  • ✅ Check if default ports (3000/3001/3002) are in use
  • ✅ Suggest available alternative ports
  • ✅ Create configuration file and start the service

Option 4: Source Code

# 1. Clone the repository
git clone https://github.com/foru17/neko-master.git
cd neko-master

# 2. Install dependencies
pnpm install

# 3. Prepare collector env (source mode reads apps/collector/.env)
cp apps/collector/.env.example apps/collector/.env

# 4. Start development services
pnpm dev

Open http://localhost:3000 to configure.

In source mode: collector listens on 3001/3002, web listens on 3000 by default. If you changed API_PORT (not 3001), set API_URL accordingly (for example API_URL=http://localhost:4001) so web /api rewrite targets the correct API. apps/collector/.env.local takes precedence over apps/collector/.env.

🤖 Agent Deployment

Use Agent mode when you want one centralized Neko Master service and multiple remote devices (OpenWrt, Linux, macOS) collecting local gateway data. The agent runs near the gateway, pulls data, and reports to the panel — the panel never connects to the gateway directly.

Supported gateway types: Clash / Mihomo (WebSocket real-time) and Surge v5+ (HTTP polling).

Quick Install (UI-generated command)

  1. In the dashboard, go to Settings → Backends, add an Agent backend, select gateway type
  2. Click "View Agent Script" and copy the one-line install command, then run it on the target host:
# Clash / Mihomo gateway example
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/apps/agent/install.sh \
  | env NEKO_SERVER='http://your-panel:3000' \
        NEKO_BACKEND_ID='1' \
        NEKO_BACKEND_TOKEN='ag_xxx' \
        NEKO_GATEWAY_TYPE='clash' \
        NEKO_GATEWAY_URL='http://127.0.0.1:9090' \
        sh

# Surge gateway example
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/apps/agent/install.sh \
  | env NEKO_SERVER='http://your-panel:3000' \
        NEKO_BACKEND_ID='2' \
        NEKO_BACKEND_TOKEN='ag_yyy' \
        NEKO_GATEWAY_TYPE='surge' \
        NEKO_GATEWAY_URL='http://127.0.0.1:9091' \
        sh

After install, manage instances with nekoagent:

nekoagent list               # list all instances
nekoagent status <instance>  # check running state
nekoagent logs <instance>    # tail live logs
nekoagent restart <instance> # restart
nekoagent upgrade            # global upgrade (CLI + binary)

The script auto-detects an existing installation — if neko-agent is already present, it only adds the new instance without re-downloading. Multiple instances can run on the same host (different NEKO_INSTANCE_NAME), each pointing to a different gateway.

Agent Documentation

📖 First Use

First Use

Connect Clash / Mihomo

  1. Open http://localhost:3000
  2. The Gateway Configuration dialog will appear on first visit
  3. Fill in your network gateway (e.g., OpenClash) connection info:
    • Name: Custom name (e.g., "Home Gateway")
    • Type: Select Clash / Mihomo
    • Host: Gateway backend address (e.g., 192.168.101.1)
    • Port: Gateway backend port (e.g., 9090)
    • Token: Fill if Secret is configured, otherwise leave empty
  4. Click "Add Backend" to save
  5. The system will automatically start collecting and analyzing traffic data

💡 Get Gateway Address: Go to your gateway control panel (e.g., OpenClash) → Enable "External Control" → Copy API address

Connect Surge

Surge HTTP API Configuration

Neko Master supports connecting to Surge gateways for complete rule chain visualization and traffic analysis.

1. Enable Surge HTTP API

Enable HTTP remote API in your Surge configuration:

[General]
http-api = 127.0.0.1:9091
http-api-tls = false
http-api-web-dashboard = true

Or configure via Surge's graphical interface:

  • HTTP Remote API: SettingsGeneralHTTP Remote API
  • Port: Default 9091
  • Authentication: Recommended to set a password for enhanced security

2. Add Surge Backend in Neko Master

  1. Open Neko Master settings dialog
  2. Click "Add Backend"
  3. Fill in the connection info:
    • Name: Custom name (e.g., "Surge Home")
    • Type: Select Surge
    • Host: IP address where Surge is running (e.g., 192.168.1.1 or 127.0.0.1)
    • Port: HTTP API port (default 9091)
    • Token: HTTP API password (if configured)
  4. Click "Test Connection" to verify the configuration
  5. Save the configuration

💡 Note: Surge uses HTTP polling to fetch data (compared to Clash's WebSocket real-time stream), with a data refresh delay of approximately 2 seconds.

🔧 Port Conflict Resolution

If you see "port already in use" error, here are the solutions:

Solution 1: Use .env File

Create a .env file in the same directory as docker-compose.yml:

WEB_EXTERNAL_PORT=8080    # Change Web UI port
API_EXTERNAL_PORT=8081    # Change API port
WS_EXTERNAL_PORT=8082     # Change WebSocket external port (only for direct access)
COOKIE_SECRET=your-long-random-secret   # Strongly recommended to keep fixed

Then restart:

docker compose down
docker compose up -d

Now access http://localhost:8080

Solution 2: Directly Modify docker-compose.yml

ports:
  - "8080:3000" # External 8080 → Internal 3000
  - "8082:3002" # External 8082 → Internal 3002 (for proxy/tunnel WS forwarding)

Note: if you use direct WS access (no reverse proxy) and external WS port is not 3002, set WS_EXTERNAL_PORT=<external-ws-port>.

Solution 3: Use One-Click Script

curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash

The script will automatically detect and suggest available ports.

🐳 Docker Configuration

Ports

Port Purpose External Required Description
3000 Web UI Frontend entry point
3001 API Optional Frontend uses same-origin /api by default; usually no public exposure needed (default Compose maps it)
3002 WebSocket Optional Real-time push endpoint; recommended for reverse proxy/tunnel forwarding only (default Compose maps it)

Environment Variables (Deployment)

Variable Default Purpose When to set
WEB_PORT 3000 Web listen port (inside container) Usually unchanged
API_PORT 3001 API listen port (inside container) Usually unchanged
COLLECTOR_WS_PORT 3002 WS listen port (inside container) Usually unchanged
DB_PATH /app/data/stats.db SQLite data path Custom data path
WEB_EXTERNAL_PORT 3000 External web port mapping in docker-compose.yml External web port changed
API_EXTERNAL_PORT 3001 External API port mapping in docker-compose.yml Direct external API access needed
WS_EXTERNAL_PORT 3002 External WS port mapping in docker-compose.yml; also used for direct WS port inference Direct WS access without proxy and external WS port changed
NEXT_PUBLIC_API_URL empty Override frontend API base URL (e.g. https://api.example.com) API is not same-origin /api
NEXT_PUBLIC_WS_URL empty Override frontend WS URL (absolute URL or /custom_ws) Custom WS path/domain
NEXT_PUBLIC_WS_PORT 3002 WS direct-connection fallback port (build-time only — setting this at Docker runtime has no effect; use WS_EXTERNAL_PORT instead) Only for custom source builds
API_URL http://localhost:3001 Next.js /api rewrite target (mainly source/custom builds) API listen address changed
COOKIE_SECRET auto-generated Cookie signing secret; if not fixed, sessions can be invalidated after restart when data dir is not persisted Strongly recommended in production
GEOIP_LOOKUP_PROVIDER online IP geolocation source (online / local) Default to local MMDB lookup
GEOIP_ONLINE_API_URL https://api.ipinfo.es/ipinfo Online IP geolocation API endpoint (must be compatible with ipinfo.my response schema) Set only when you deploy a compatible endpoint
FORCE_ACCESS_CONTROL_OFF false Force disable access control (emergency recovery) Temporary use only when token is lost
SHOWCASE_SITE_MODE false Read-only showcase mode (blocks sensitive write operations) Public demo sites only

Advanced Tuning Variables (Optional)

Variable Default Description
FLUSH_INTERVAL_MS 30000 Buffer flush interval for collector writes
FLUSH_MAX_BUFFER_SIZE 5000 Max buffer entries before early flush
REALTIME_MAX_MINUTES 180 Realtime in-memory window size (minutes)
REALTIME_RANGE_END_TOLERANCE_MS 120000 End-time tolerance for range queries
SURGE_POLICY_SYNC_INTERVAL_MS 600000 Surge policy sync interval
DB_RANGE_QUERY_CACHE_TTL_MS 8000 Range-query cache TTL
DB_HISTORICAL_QUERY_CACHE_TTL_MS 300000 Historical-query cache TTL
DB_RANGE_QUERY_CACHE_MAX_ENTRIES 1024 Max range-query cache entries
DB_RANGE_QUERY_CACHE_DISABLED empty Set 1 to disable range-query cache
DEBUG_SURGE false Enable Surge collector debug logs (true)

API / WS Resolution Priority

  1. API client base: runtime-config.API_URLNEXT_PUBLIC_API_URL → same-origin /api
  2. /api server-side rewrite target: API_URL (default http://localhost:3001, applied in Next.js rewrites)
  3. WS URL: runtime-config.WS_URLNEXT_PUBLIC_WS_URL → auto candidates (when runtime-config.WS_PORT is set, direct port is preferred; otherwise /_cm_ws is tried first)
  4. WS port: runtime-config.WS_PORT (from WS_EXTERNAL_PORT) → NEXT_PUBLIC_WS_PORT3002
  5. In normal deployments, NEXT_PUBLIC_WS_URL is usually unnecessary unless you use a custom WS path/domain

Production Environment Baseline (Recommended)

NODE_ENV=production
DB_PATH=/app/data/stats.db
COOKIE_SECRET=<at least 32-byte random string>
# Optional: default to local MMDB lookup
# GEOIP_LOOKUP_PROVIDER=local
# Keep false in normal operation
# FORCE_ACCESS_CONTROL_OFF=false

Use openssl rand -hex 32 to generate COOKIE_SECRET.

Additional recommendations:

  1. Mount persistent storage (for example ./data:/app/data) to avoid data and secret loss.
  2. If using direct WS access and external WS port is not 3002, set WS_EXTERNAL_PORT accordingly.
  3. If API port/address changes in source deployment, update API_URL as well.
  4. For local MMDB lookup, mount ./geoip:/app/data/geoip:ro and switch source in Settings -> Preferences -> IP Lookup Source.
  5. MMDB files are large and are not bundled in the image. Download and place them in ./geoip with fixed names: GeoLite2-City.mmdb, GeoLite2-ASN.mmdb (required), and GeoLite2-Country.mmdb (optional). Recommended source: https://github.com/P3TERX/GeoLite.mmdb.

Advanced Agent details (install, config, release, compatibility) are maintained under docs/agent/*.

🗄️ ClickHouse (Optional)

SQLite is Neko Master's default storage engine and works well for most users. Consider enabling ClickHouse if you need:

  • Very large datasets (hundreds of thousands of domain/IP entries)
  • Fast aggregation queries over long time ranges (≥ 7 days)
  • Separation of historical stats from configuration/metadata storage

ClickHouse is entirely optional. SQLite remains as the configuration and metadata store regardless of whether ClickHouse is enabled.

Architecture Overview

When ClickHouse is enabled, the system enters dual-write mode:

BatchBuffer.flush()
    │
    ├──→ SQLite (config / metadata, always written)
    └──→ ClickHouse (stats traffic data, dual-write)
           └── Buffer tables → SummingMergeTree async merge

Read source is controlled by STATS_QUERY_SOURCE (default: sqlite).

Enabling ClickHouse (Docker)

Step 1: Start the ClickHouse container

The repository's built-in docker-compose.yml already includes a ClickHouse service, gated by profiles: [clickhouse] so it does not start by default. From the repository root, run:

docker compose --profile clickhouse up -d

ClickHouse data is persisted to ./data/clickhouse, separate from the main app data directory.

If you use a custom docker-compose.yml (such as Scenario A/B above), add the ClickHouse service block manually:

services:
  neko-master:
    # ... your existing config ...
    environment:
      # append to existing environment section:
      - CH_ENABLED=${CH_ENABLED:-0}
      - CH_HOST=${CH_HOST:-clickhouse}
      - CH_PORT=${CH_PORT:-8123}
      - CH_DATABASE=${CH_DATABASE:-neko_master}
      - CH_USER=${CH_USER:-neko}
      - CH_PASSWORD=${CH_PASSWORD:-neko_master}
      - CH_WRITE_ENABLED=${CH_WRITE_ENABLED:-0}
      - STATS_QUERY_SOURCE=${STATS_QUERY_SOURCE:-sqlite}
    networks:
      - neko-master-network

  clickhouse:
    image: clickhouse/clickhouse-server:24.8
    container_name: neko-master-clickhouse
    restart: unless-stopped
    profiles: ["clickhouse"]
    ports:
      - "${CH_EXTERNAL_HTTP_PORT:-8123}:8123"
      - "${CH_EXTERNAL_NATIVE_PORT:-9000}:9000"
    volumes:
      - ./data/clickhouse:/var/lib/clickhouse
    environment:
      - CLICKHOUSE_DB=${CH_DATABASE:-neko_master}
      - CLICKHOUSE_USER=${CH_USER:-neko}
      - CLICKHOUSE_PASSWORD=${CH_PASSWORD:-neko_master}
      - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1
    networks:
      - neko-master-network
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8123/ping || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

networks:
  neko-master-network:
    driver: bridge

Step 2: Configure environment variables

Add to your .env (same directory as docker-compose.yml):

# Enable ClickHouse connection
CH_ENABLED=1

# Enable dual-write
CH_WRITE_ENABLED=1

# Read source: sqlite (default) / auto (smart routing) / clickhouse (force)
STATS_QUERY_SOURCE=auto

# ClickHouse connection (defaults match docker-compose.yml, no change needed)
CH_HOST=clickhouse
CH_PORT=8123
CH_DATABASE=neko_master
CH_USER=neko
CH_PASSWORD=neko_master

Restart:

docker compose --profile clickhouse up -d

ClickHouse Environment Variables

Variable Default Description
CH_ENABLED 0 Enable ClickHouse connection (1 to enable)
CH_WRITE_ENABLED 0 Enable dual-write (requires CH_ENABLED=1)
CH_ONLY_MODE 0 When CH is healthy, skip SQLite stats writes (CH-only mode)
CH_HOST clickhouse ClickHouse host address
CH_PORT 8123 ClickHouse HTTP port
CH_DATABASE neko_master Database name
CH_USER neko Username
CH_PASSWORD neko_master Password
CH_SECURE 0 Use HTTPS connection
CH_REQUIRED 0 Refuse to start if CH is unavailable
CH_AUTO_CREATE_TABLES 1 Auto-create tables on first start
CH_WRITE_MAX_PENDING_BATCHES 200 Max pending write batches
CH_UNHEALTHY_THRESHOLD 5 Consecutive failures before marking unhealthy (auto-fallback to SQLite)
STATS_QUERY_SOURCE sqlite Read source: sqlite / auto / clickhouse
CH_COMPARE_ENABLED 0 Enable SQLite ↔ ClickHouse consistency check
CH_EXTERNAL_HTTP_PORT 8123 ClickHouse HTTP external port (Compose mapping)
CH_EXTERNAL_NATIVE_PORT 9000 ClickHouse Native external port (Compose mapping)

Health & Fallback: After CH_UNHEALTHY_THRESHOLD consecutive write failures, the system automatically marks ClickHouse as unhealthy and resumes SQLite writes—even when CH_ONLY_MODE=1. Once ClickHouse recovers, it is re-marked healthy and logged.

Migration Guide for Existing Users

Upgrading from a SQLite-only version? Your data is safe. The SQLite file (./data/stats.db) is fully preserved. Here is the recommended gradual migration path:

Phase 1: Dual-write (observation period, recommended starting point)

CH_ENABLED=1
CH_WRITE_ENABLED=1
STATS_QUERY_SOURCE=sqlite   # Keep reading from SQLite while CH accumulates data

Start and watch [ClickHouse Writer] logs to confirm successful writes.

Phase 2: Switch read source

STATS_QUERY_SOURCE=auto        # Smart routing: recent data from CH, historical from SQLite
# or
STATS_QUERY_SOURCE=clickhouse  # Force all reads to ClickHouse

Phase 3 (optional): Migrate historical data

To move historical SQLite stats into ClickHouse:

# Standard migration (truncate CH then re-import, with consistency check)
./scripts/ch-migrate-docker.sh

# Append mode (keep existing CH data, incremental import)
./scripts/ch-migrate-docker.sh --append

# Specific time window
./scripts/ch-migrate-docker.sh --from 2026-02-01T00:00:00Z --to 2026-02-20T00:00:00Z

Phase 4 (optional): CH-only mode

Once ClickHouse is running stably, stop SQLite stats writes:

CH_ONLY_MODE=1

Even with CH_ONLY_MODE=1, if ClickHouse becomes unhealthy the system automatically falls back to SQLite writes—no data loss.

Reverting to SQLite-only

You can always roll back completely:

CH_ENABLED=0
CH_WRITE_ENABLED=0
CH_ONLY_MODE=0
STATS_QUERY_SOURCE=sqlite

Restart and everything returns to pure SQLite mode. Historical data remains intact.


🌐 Reverse Proxy & Tunnel

Recommended approach: keep Web and WS under the same domain, with path routing: /3000, /_cm_ws3002.

Nginx Standard Example

server {
  listen 443 ssl http2;
  server_name neko.example.com;

  location / {
    proxy_pass http://<neko-master-host>:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

  location ^~ /_cm_ws {
    proxy_pass http://<neko-master-host>:3002;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 86400;
    proxy_send_timeout 86400;
    proxy_buffering off;
  }
}

Optional env override:

# Not required by default (already /_cm_ws)
# NEXT_PUBLIC_WS_URL=/custom_ws

Cloudflare Tunnel Standard Example

~/.cloudflared/config.yml:

tunnel: <your-tunnel-name-or-id>
credentials-file: /path/to/<credentials>.json

ingress:
  - hostname: neko.example.com
    path: /_cm_ws*
    service: http://localhost:3002
  - hostname: neko.example.com
    path: /*
    service: http://localhost:3000
  - service: http_status:404

Run:

cloudflared tunnel --config ~/.cloudflared/config.yml run <your-tunnel-name-or-id>

For Zero Trust dashboard-managed routes (token mode), configure the same two routes and keep /_cm_ws* above /*.

Key Notes

  1. Do not use ws (without leading slash) as WS path; it can overmatch and cause /_next/static/...426 Upgrade Required
  2. WS route must be above catch-all /*
  3. NEXT_PUBLIC_WS_URL is optional by default; if customized, restart frontend/container after changes
  4. Mapping only 3000 still works, but falls back to HTTP polling (~5s), with less real-time responsiveness
  5. beacon.min.js failures (Cloudflare analytics script) are typically unrelated to app API/WS data flow
  6. No extra /api reverse-proxy rule is required in most setups; frontend uses same-origin /api and app handles internal forwarding to 3001

Note: /_next/static/... 426 Upgrade Required is common in misconfigured reverse proxy / tunnel setups; it is uncommon in direct local access without a proxy.

Multi-Architecture Support

Docker images support both linux/amd64 and linux/arm64.

Data Persistence

Data is stored in /app/data inside the container. Mount it to host to prevent data loss:

volumes:
  - ./data:/app/data

Update to Latest

# Pull the latest image and restart
docker compose pull
docker compose up -d

🔐 Authentication & Security

Neko Master supports access authentication to protect dashboard data.

Production Security Baseline

  1. Set a fixed COOKIE_SECRET (otherwise sessions may be invalidated after restart).
  2. Do not keep FORCE_ACCESS_CONTROL_OFF=true enabled in normal operation.
  3. Use SHOWCASE_SITE_MODE=true only for public demo environments (write operations are restricted).

Example:

COOKIE_SECRET=<at least 32-byte random string>
# FORCE_ACCESS_CONTROL_OFF=false
# SHOWCASE_SITE_MODE=false

Enable / Disable Authentication

  1. Open dashboard and click "Settings" in the lower-left sidebar.
  2. Go to the "Security" tab.
  3. Enable/disable access control and set your token.

Forgot Token (Emergency Reset)

If you forgot the token, temporarily set FORCE_ACCESS_CONTROL_OFF=true to enter emergency mode.

Docker Compose

  1. Add to docker-compose.yml:

    environment:
      - FORCE_ACCESS_CONTROL_OFF=true
  2. Restart:

    docker compose up -d
  3. Open dashboard and reset token in "Settings -> Security".

  4. Remove this env var immediately after reset, then restart again.

Docker CLI

  1. Stop and remove container:

    docker stop neko-master
    docker rm neko-master
  2. Re-run with emergency flag:

    docker run -d \
      --name neko-master \
      -p 3000:3000 \
      -v $(pwd)/data:/app/data \
      -e FORCE_ACCESS_CONTROL_OFF=true \
      foru17/neko-master:latest
  3. Reset token, then remove this flag and restart normally.

❓ FAQ

Q: Can I run normally with only 3000:3000 exposed?

A: Yes. Core features still work. If WS is not routed, the app automatically falls back to HTTP polling. For full realtime experience, route /_cm_ws to 3002.

Q: Port conflict or inaccessible after port changes?

A: Create/update .env (same directory as docker-compose.yml):

WEB_EXTERNAL_PORT=8080
API_EXTERNAL_PORT=8081
WS_EXTERNAL_PORT=8082

Then restart:

docker compose down
docker compose up -d

Q: Why does login/session disappear after restart?

A: Usually because COOKIE_SECRET is not fixed or data directory is not persisted.

  1. Set a fixed COOKIE_SECRET
  2. Mount ./data:/app/data

Q: Which files are required for local MMDB lookup?

A: Create ./geoip in your project directory (same level as docker-compose.yml is recommended), then place:

  1. GeoLite2-City.mmdb (required)
  2. GeoLite2-ASN.mmdb (required)
  3. GeoLite2-Country.mmdb (optional)

Recommended source: https://github.com/P3TERX/GeoLite.mmdb. Inside the container, the fixed lookup path is /app/data/geoip, so keep: ./geoip:/app/data/geoip:ro. To update later, just replace files in host ./geoip.

Q: Failed to connect OpenClash / gateway?

A: Check:

  1. External control is enabled on gateway side
  2. Host/port is correct
  3. Token/Secret is correct (if configured)
  4. Container network can reach gateway

Q: How to backup and restore data?

A: Backup first:

cp -r ./data ./data-backup-$(date +%Y%m%d)

Restore:

docker compose down
cp -r ./data-backup-YYYYMMDD/. ./data/
docker compose up -d

🏗️ Architecture Guide

If you want to quickly understand the system design depth, read in this order:

  1. System Architecture Diagram: end-to-end layering and module responsibilities → docs/architecture.en.md
  2. Data Flow: Clash / Surge collection pipelines and aggregation
  3. Data Model & Storage: SQLite schema, ClickHouse Buffer tables, retention policy
  4. Realtime Channel Design: RealtimeStore merge strategy and WS push
  5. ClickHouse Module: dual-write architecture, health fallback, read routing

Full documentation index: docs/README.md

This documentation covers the core design of collection, aggregation, caching, realtime push, and multi-backend management.

🤝 Feedback & Issues

This project uses GitHub Issue Templates (Bug / Feature / Support).

Please include at least:

  1. Deployment method (Compose / Docker Run / Source)
  2. Version info (image tag or commit)
  3. Key env vars (masked, e.g. COOKIE_SECRET=***)
  4. Reproduction steps and expected vs actual behavior
  5. Key logs (docker logs, browser console, network errors)

📁 Project Structure

neko-master/
├── docker-compose.yml      # Docker Compose config
├── Dockerfile              # Docker image build
├── setup.sh                # One-click setup script
├── docker-start.sh         # Docker container startup script
├── start.sh                # Source code dev startup script
├── docs/                   # Documentation (see docs/README.md)
│   ├── README.md           # Documentation index (English default)
│   ├── README.zh.md        # Documentation index (Chinese)
│   ├── README.en.md        # Documentation index (English mirror)
│   ├── architecture.md     # System architecture (Chinese)
│   ├── architecture.en.md  # System architecture (English)
│   ├── release-checklist.md
│   ├── agent/              # Agent docs (bilingual)
│   │   ├── overview.md / overview.en.md
│   │   ├── quick-start.md / quick-start.en.md
│   │   ├── install.md / install.en.md
│   │   ├── config.md / config.en.md
│   │   ├── release.md / release.en.md
│   │   └── troubleshooting.md / troubleshooting.en.md
│   ├── research/           # Research reports
│   └── dev/                # Internal development docs
├── assets/                 # Screenshots and icons
├── apps/
│   ├── collector/          # Data collection service (Node.js + WebSocket)
│   ├── agent/              # Agent daemon (Go)
│   └── web/                # Next.js frontend app
└── packages/
    └── shared/             # Shared types and utilities

🛠️ Tech Stack

🤝 Contributing

Contributions are welcome!

Before opening a PR, read CONTRIBUTING.md (workflow, checks, i18n/dark-mode requirements).

Developing with an AI coding tool? (Claude Code, Copilot, Cursor, Codex, ...) Point it at AGENTS.md — conventions, key contracts, and the project map — plus the task-specific workflow guides in .claude/skills/. Claude Code picks both up automatically.

📄 License

MIT © foru17


⭐ Star History

Star History Chart


Made with ❤️ by @foru17
If this project helps you, please consider giving it a ⭐

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

18 total
  1. v1.4.0v1.4.0Jul 19, 2026

    第二次深度评审修复迭代(每条发现均经证伪核验)。 ## 修复 - **Agent 安装/升级 404**:不再用会命中主应用 release 的 `releases/latest`,改为解析最新 `agent-v*` tag。 - **Agent CH_ONLY 静默丢数据**:ClickHouse 写失败时补齐 SQLite 兜底回写(流量+国家维度)。 - **Agent realtime store 无界增长**:agent 路径补上 `pruneIfNeeded`,防止 CH 持续故障时 OOM。 - **统计错误态缺失**:collector 请求失败时不再谎报"暂无数据",改为显示错误提示。 ## 安全 - **CORS 默认拒绝跨源**(未设 `CORS_ORIGIN` 时)。⚠️ **升级提示**:仪表盘与 collector 不同源的部署需显式设置 `CORS_ORIGIN`(同源/默认 Docker 部署不受影响)。 - **`GET /api/backends` 不再返回明文 token**。 完整变更见 CHANGELOG.md / CHANGELOG.en.md。

  2. agent-v1.4.5agent-v1.4.5Jul 19, 2026137 downloads

    **Full Changelog**: https://github.com/foru17/neko-master/compare/v1.3.10...agent-v1.4.5

  3. v1.3.10v1.3.10Jul 4, 2026

    This release comes from a project-wide deep review (architecture / database / performance / frontend / UX) and fixes the high-risk findings. Full report: `docs/dev/deep-review-2026-07.md`. ## Fixed - **RuleSet/IPCIDR nodes in the chain-flow entry column (v1.3.9 regression)** — mihomo traffic keys on the top-level policy group again; a one-time startup migration remaps and merges the polluted rows written since v1.3.9 - **30-day ranges effectively contained only 7 days of dimension data** — hourly dim tables now follow the hourly retention window instead of the minute-level cutoff - **Silent missing data when ClickHouse writes are on but reads stay on SQLite** — write reduction now requires reads to prefer ClickHouse, with a startup warning for the misconfiguration - **CSV association columns dropped values on substring collisions** (`a.com` vs `aa.com`) — delimiter-aware dedup everywhere - **Batch writes double-counted on retry** — the flush is now one atomic transaction - **Cross-backend data bleed while switching backends** — WS pushes carry `backendId`; the client drops mismatched in-flight pushes - **Error surfaces** — route/global error boundaries; chain-flow failures show a

  4. A stability-focused release driven by a performance/reliability code review, plus two community contributor PRs. ## 🐛 Fixes - **Silent persistence data loss when ClickHouse degrades** — when ClickHouse was healthy the SQLite write was skipped, but the in-memory batch was cleared before the async ClickHouse write was confirmed, so a failed write (queue full / partial-table / timeout) lost the data. The collector now writes the batch to SQLite as a durable fallback on ClickHouse failure; a full queue counts toward "unhealthy"; and health resets only after a complete detail+agg batch so a persistently-failing table can't mask the outage. - **Agent under-counted traffic on counter resets** — the Go agent dropped traffic to zero when a flow counter went backwards (gateway restart / id reuse); it now counts the current value as new traffic, matching the direct collector. - **Deleting a backend left orphaned data** — `PRAGMA foreign_keys` is OFF so the declared `ON DELETE CASCADE` never fired; `deleteBackend` now explicitly removes all associated data. - **#65 — Collector didn't recover after a backend password change** — the socket is now torn down synchronously before flushing, so it

  5. agent-v1.4.4agent-v1.4.4Jun 23, 2026117 downloads

    **Full Changelog**: https://github.com/foru17/neko-master/compare/agent-v1.4.3...agent-v1.4.4

Commits per week

last 52 weeks
460Week of 2025-08-02: 0 commitsWeek of 2025-08-09: 0 commitsWeek of 2025-08-16: 0 commitsWeek of 2025-08-23: 0 commitsWeek of 2025-08-30: 0 commitsWeek of 2025-09-06: 0 commitsWeek of 2025-09-13: 0 commitsWeek of 2025-09-20: 0 commitsWeek of 2025-09-27: 0 commitsWeek of 2025-10-04: 0 commitsWeek of 2025-10-11: 0 commitsWeek of 2025-10-18: 0 commitsWeek of 2025-10-25: 0 commitsWeek of 2025-11-01: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 0 commitsWeek of 2025-11-23: 0 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 0 commitsWeek of 2025-12-14: 0 commitsWeek of 2025-12-21: 0 commitsWeek of 2025-12-28: 0 commitsWeek of 2026-01-04: 0 commitsWeek of 2026-01-11: 0 commitsWeek of 2026-01-18: 0 commitsWeek of 2026-01-25: 0 commitsWeek of 2026-02-01: 19 commitsWeek of 2026-02-08: 46 commitsWeek of 2026-02-15: 37 commitsWeek of 2026-02-22: 31 commitsWeek of 2026-03-01: 2 commitsWeek of 2026-03-08: 1 commitsWeek of 2026-03-15: 0 commitsWeek of 2026-03-22: 1 commitsWeek of 2026-03-29: 3 commitsWeek of 2026-04-05: 0 commitsWeek of 2026-04-12: 2 commitsWeek of 2026-04-19: 0 commitsWeek of 2026-04-26: 0 commitsWeek of 2026-05-03: 0 commitsWeek of 2026-05-10: 0 commitsWeek of 2026-05-17: 2 commitsWeek of 2026-05-24: 0 commitsWeek of 2026-05-31: 0 commitsWeek of 2026-06-07: 2 commitsWeek of 2026-06-14: 1 commitsWeek of 2026-06-21: 3 commitsWeek of 2026-06-28: 13 commitsWeek of 2026-07-05: 0 commitsWeek of 2026-07-12: 0 commitsWeek of 2026-07-19: 5 commitsWeek of 2026-07-26: 0 commitsAug 2, 2025Jul 26, 2026
168 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 3 commitsSun 1:00 — 6 commitsSun 2:00 — 0 commitsSun 3:00 — 0 commitsSun 4:00 — 0 commitsSun 5:00 — 0 commitsSun 6:00 — 0 commitsSun 7:00 — 0 commitsSun 8:00 — 1 commitsSun 9:00 — 1 commitsSun 10:00 — 7 commitsSun 11:00 — 0 commitsSun 12:00 — 0 commitsSun 13:00 — 1 commitsSun 14:00 — 3 commitsSun 15:00 — 3 commitsSun 16:00 — 1 commitsSun 17:00 — 0 commitsSun 18:00 — 0 commitsSun 19:00 — 0 commitsSun 20:00 — 1 commitsSun 21:00 — 1 commitsSun 22:00 — 1 commitsSun 23:00 — 6 commitsMon 0:00 — 2 commitsMon 1:00 — 1 commitsMon 2:00 — 0 commitsMon 3:00 — 0 commitsMon 4:00 — 2 commitsMon 5:00 — 0 commitsMon 6:00 — 0 commitsMon 7:00 — 0 commitsMon 8:00 — 0 commitsMon 9:00 — 0 commitsMon 10:00 — 0 commitsMon 11:00 — 3 commitsMon 12:00 — 0 commitsMon 13:00 — 3 commitsMon 14:00 — 1 commitsMon 15:00 — 0 commitsMon 16:00 — 1 commitsMon 17:00 — 1 commitsMon 18:00 — 0 commitsMon 19:00 — 0 commitsMon 20:00 — 0 commitsMon 21:00 — 1 commitsMon 22:00 — 1 commitsMon 23:00 — 0 commitsTue 0:00 — 0 commitsTue 1:00 — 0 commitsTue 2:00 — 0 commitsTue 3:00 — 0 commitsTue 4:00 — 0 commitsTue 5:00 — 0 commitsTue 6:00 — 0 commitsTue 7:00 — 0 commitsTue 8:00 — 1 commitsTue 9:00 — 3 commitsTue 10:00 — 1 commitsTue 11:00 — 0 commitsTue 12:00 — 0 commitsTue 13:00 — 1 commitsTue 14:00 — 3 commitsTue 15:00 — 0 commitsTue 16:00 — 1 commitsTue 17:00 — 0 commitsTue 18:00 — 0 commitsTue 19:00 — 1 commitsTue 20:00 — 3 commitsTue 21:00 — 4 commitsTue 22:00 — 0 commitsTue 23:00 — 0 commitsWed 0:00 — 0 commitsWed 1:00 — 0 commitsWed 2:00 — 0 commitsWed 3:00 — 0 commitsWed 4:00 — 0 commitsWed 5:00 — 0 commitsWed 6:00 — 0 commitsWed 7:00 — 0 commitsWed 8:00 — 0 commitsWed 9:00 — 0 commitsWed 10:00 — 1 commitsWed 11:00 — 0 commitsWed 12:00 — 2 commitsWed 13:00 — 1 commitsWed 14:00 — 1 commitsWed 15:00 — 0 commitsWed 16:00 — 1 commitsWed 17:00 — 0 commitsWed 18:00 — 1 commitsWed 19:00 — 0 commitsWed 20:00 — 1 commitsWed 21:00 — 1 commitsWed 22:00 — 1 commitsWed 23:00 — 0 commitsThu 0:00 — 2 commitsThu 1:00 — 0 commitsThu 2:00 — 0 commitsThu 3:00 — 1 commitsThu 4:00 — 0 commitsThu 5:00 — 0 commitsThu 6:00 — 0 commitsThu 7:00 — 0 commitsThu 8:00 — 0 commitsThu 9:00 — 1 commitsThu 10:00 — 1 commitsThu 11:00 — 0 commitsThu 12:00 — 2 commitsThu 13:00 — 0 commitsThu 14:00 — 0 commitsThu 15:00 — 1 commitsThu 16:00 — 0 commitsThu 17:00 — 1 commitsThu 18:00 — 1 commitsThu 19:00 — 1 commitsThu 20:00 — 4 commitsThu 21:00 — 1 commitsThu 22:00 — 1 commitsThu 23:00 — 1 commitsFri 0:00 — 1 commitsFri 1:00 — 4 commitsFri 2:00 — 0 commitsFri 3:00 — 1 commitsFri 4:00 — 3 commitsFri 5:00 — 0 commitsFri 6:00 — 0 commitsFri 7:00 — 0 commitsFri 8:00 — 0 commitsFri 9:00 — 0 commitsFri 10:00 — 0 commitsFri 11:00 — 2 commitsFri 12:00 — 4 commitsFri 13:00 — 2 commitsFri 14:00 — 2 commitsFri 15:00 — 1 commitsFri 16:00 — 2 commitsFri 17:00 — 2 commitsFri 18:00 — 2 commitsFri 19:00 — 1 commitsFri 20:00 — 1 commitsFri 21:00 — 1 commitsFri 22:00 — 1 commitsFri 23:00 — 1 commitsSat 0:00 — 1 commitsSat 1:00 — 1 commitsSat 2:00 — 1 commitsSat 3:00 — 0 commitsSat 4:00 — 0 commitsSat 5:00 — 0 commitsSat 6:00 — 0 commitsSat 7:00 — 0 commitsSat 8:00 — 0 commitsSat 9:00 — 0 commitsSat 10:00 — 2 commitsSat 11:00 — 2 commitsSat 12:00 — 4 commitsSat 13:00 — 1 commitsSat 14:00 — 10 commitsSat 15:00 — 4 commitsSat 16:00 — 3 commitsSat 17:00 — 2 commitsSat 18:00 — 2 commitsSat 19:00 — 1 commitsSat 20:00 — 3 commitsSat 21:00 — 1 commitsSat 22:00 — 1 commitsSat 23:00 — 1 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.

Who is committing

last 52 weeks
Maintainer commits173 (99%)
Community commits2 (1%)

175 commits in total over the last year.

  • freeCodeCamp/freeCodeCamp

    freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.

    453.6K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    385.5K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • openclaw/openclaw

    Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

    384.4K stars · TypeScript

  • anomalyco/opencode

    The open source coding agent.

    194.7K stars · TypeScript