A premium Node.js application for aggregating and visualizing install, active device, and uninstall metrics across the Google Play Store and Apple App Store.
Includes a web-based dashboard, a CLI for programmatic access, and a mock-data demo mode for local evaluation.
Explore the Dashboard Demo
(Note: The demo is locked in Simulated Mode with rich sample data)
Pull the latest image directly from the GitHub Container Registry.
-
Pull the image:
docker pull ghcr.io/zmsp/appstore-analytics:sha-65d8ec55f30974f879afd526106cdf21aea8a15b
-
Prepare configuration: Create a
configdirectory in your host path. Place yourconfig.jsonand any required.jsonor.p8API keys inside it. -
Run the container:
docker run -d \ -p 3000:3000 \ -v $(pwd)/config:/config \ -v $(pwd)/data:/app/downloaded_stats \ -e CONFIG_PATH=/config/config.json \ --name appstore-analytics \ ghcr.io/zmsp/appstore-analytics:sha-65d8ec55f30974f879afd526106cdf21aea8a15b
-
Clone the repository:
git clone https://github.com/your-username/store_stat_viewer.git cd store_stat_viewer -
Run via Docker Compose:
docker-compose up -d
-
Access the Web UI: Navigate to
http://localhost:3000.- Initial Setup: You will be prompted to configure an admin password on the first run.
- Demo Mode: Toggle the switch in the sidebar to bypass authentication and preview the UI with simulated data.
- Web Dashboard: Glassmorphic dark-themed UI with Chart.js visualizations for daily event trends, segmentable by country, OS version, app version, and device type.
- Multi-Platform Aggregation: Unified data layer fetching from Google Play Console (via GCS exports) and Apple App Store Connect.
- Headless CLI: Terminal utility for scripting, cron jobs, or rapid querying without the web interface.
- Self-Hosted & Secure: Local data persistence and JWT-based authentication for the web interface. Service account keys remain on your host.
The backend is an Express-based Node.js server that handles API communication with Google Cloud Storage and App Store Connect, serving data to a single-page frontend.
graph TD
subgraph Frontend
WebUI[Web Dashboard]
StaticConfig[static_config.json]
end
subgraph Backend
Server[Express Server]
CLI[CLI Utility]
end
subgraph Core Libraries
GCSLib[Google Play Lib]
AppleLib[App Store Lib]
end
subgraph External Data Sources
GCS[(Google Cloud Storage)]
AppStoreAPI[(App Store Connect API)]
end
User([User / Browser]) <--> WebUI
WebUI <--> Server
WebUI -- Read if Static --> StaticConfig
Server --> GCSLib
Server --> AppleLib
CLI --> GCSLib
GCSLib <--> GCS
AppleLib <--> AppStoreAPI
Server <--> LocalCache[(Local Cache)]
Pushes to the main branch trigger a GitHub Actions workflow that builds a new production Docker image (GHCR) and updates the static demo deployed to GitHub Pages.
graph LR
Push[git push main] --> GHA[GitHub Actions]
subgraph GitHub Actions
BuildDemo[Build Demo]
BuildDocker[Build Docker]
end
BuildDemo --> GHPages[GitHub Pages]
BuildDocker --> GHCR[GitHub Container Registry]
GHPages --> DemoUser([Public User])
GHCR --> SelfHost([Self-Hosted Docker])
Google Play exports bulk reports directly into a Google Cloud Storage (GCS) bucket.
- Go to the Google Cloud IAM Service Accounts Console.
- Create a service account (e.g.
playstore-stats-reader). - In the Keys tab, click Add Key -> Create New Key (JSON).
- Save the file to
config/keys/google_key.json.
- Go to the Google Play Console -> Users and Permissions.
- Invite the service account email.
- Grant "View app information and download bulk reports (read-only)" permission.
- Note: It can take up to 24 hours for bucket permissions to synchronize.
- In Play Console, go to Download reports -> Statistics.
- Click Copy Cloud Storage URI (e.g.
gs://pubsite_prod_12345678/stats/installs/). - The bucket name is the part between
gs://and the first slash:pubsite_prod_12345678.
- Go to App Store Connect -> Users and Access -> Keys.
- Generate an API Key with Sales and Reports access.
- Download the
.p8file and save it toconfig/keys/apple_key.p8. - Note your Issuer ID and Key ID.
The dashboard and CLI look for a config/config.json file. Use the following template as a guide.
[
{
"name": "Production Account",
"projectID": "your-gcp-project-id",
"bucketName": "pubsite_prod_12345678",
"keyFilePath": "keys/google_key.json",
"appleIssuerId": "xxxx-xxxx-xxxx",
"appleKeyId": "XXXXXXXXXX",
"keyFilePath_apple": "keys/apple_key.p8",
"ignoredPackages": ["com.example.testapp"]
}
]| Field | Platform | Description |
|---|---|---|
name |
Both | Display name for this configuration set. |
projectID |
Your Google Cloud Project ID. | |
bucketName |
The GCS bucket name where Play Console exports reports. | |
keyFilePath |
Path to the service account JSON key (relative to config.json). |
|
appleIssuerId |
Apple | Issuer ID from App Store Connect API. |
appleKeyId |
Apple | Key ID from App Store Connect API. |
keyFilePath_apple |
Apple | Path to the .p8 private key (relative to config.json). |
ignoredPackages |
Optional array of package names to hide from the dashboard. |
You can query your stats directly in the command line.
Option A: Using a Saved Project (Recommended)
# Query the first project in config (index 0)
node app/cli.js -s 0
# Query by project name
node app/cli.js -s "Production Account"Option B: Manual Parameters
node app/cli.js \
--key="config/keys/google_key.json" \
--projectID="your-id" \
--bucketName="your-bucket" \
--packageName="com.example.app"| Argument | Alias | Description |
|---|---|---|
--key |
-k |
Path to the service account JSON key file |
--project |
-s |
Name or index of the saved project from config |
--config |
-c |
Path to config.json (defaults to ../config/config.json) |
--projectID |
-g |
Google Cloud Project ID |
--bucketName |
-b |
Google Play Console GCS Bucket name |
--packageName |
-p |
App package identifier (e.g. com.example.app) |
.
├── app/
│ ├── lib/ # Core logic for GCS and App Store integration
│ ├── public/ # Dashboard frontend (HTML/JS/CSS)
│ ├── server.js # Express API backend server
│ └── cli.js # Command-line utility
├── config/ # User configuration and keys (GIT IGNORED)
├── Dockerfile # Multi-stage production Docker image
└── docker-compose.yml # Docker orchestration
This project is licensed under the MIT License - see the LICENSE file for details.
