# Kuma Mieru: a Recharts dashboard for Uptime Kuma status pages

> Kuma Mieru is a third party dashboard that reads an Uptime Kuma public status page and renders it with Recharts, adding latency charts, interactive charts and a dark or light theme on top of the built-in status page. It runs on Next.js 16 with Bun, and it deploys to Vercel with a fork or to Docker with a compose file.

**Alice39s/kuma-mieru** — A 3rd-party Uptime Kuma monitoring dashboard built on Next.js 16, TypeScript and Recharts.

- Repository: https://github.com/Alice39s/kuma-mieru
- Website: https://kuma-mieru.vercel.app/?r=gh
- Stars: 824 · Forks: 350
- Language: TypeScript
- License: MPL-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/alice39s-kuma-mieru

## What Kuma Mieru adds to the built-in status page

Kuma Mieru describes itself as a third party Uptime Kuma monitoring dashboard built on Next.js 16, TypeScript and Recharts. The problem it sets out to solve is stated in the README directly: Uptime Kuma's built-in public status page is not intuitive and has no latency charts.

That is a narrow, well-defined gap. Uptime Kuma is a monitoring tool with a status page feature, and the status page is what you show the public or to your own team. It lists monitors and their current state. What it does not do well is show you a latency graph per monitor, which is the number most people actually want to see, since a monitor that is up but has been slow for an hour is a different problem from one that is down.

Kuma Mieru is a read-only front end for that page. It fetches the status page data, and renders it with Recharts, so the latency and status information is drawn as interactive charts rather than as a list of coloured dots. The README's feature list names real-time monitoring with automatic refresh so the status updates without manual reloading, an interactive chart library so you can hover over latency and status data, multiple themes with dark, light and system options, support for Uptime Kuma's incident announcements and status updates so those are synchronised as well.

The important boundary is that this is a dashboard, not a monitor. It does not check anything and it does not alert. Everything it shows comes from an Uptime Kuma instance you already run.

## The configuration model and its two variable names

The configuration is environment variables, and the most important one is UPTIME_KUMA_URLS. The .env.example gives its format: the full status page URL, with multiple URLs separated by a pipe character.

```bash
UPTIME_KUMA_URLS=https://example.kuma-mieru.invalid/status/default|https://example.kuma-mieru.invalid/status/secondary
```

The example also carries a legacy path, UPTIME_KUMA_BASE_URL plus PAGE_ID, which is used when UPTIME_KUMA_URLS is not set. The README marks the legacy form as still compatible, and the docker-compose file passes both through to the container, with the base URL and page ID described as the fallback.

The presentation settings follow the same pattern. KUMA_MIERU_TITLE, KUMA_MIERU_DESCRIPTION and KUMA_MIERU_ICON set what the page says about itself, and KUMA_MIERU_EDIT_THIS_PAGE and KUMA_MIERU_SHOW_STAR_BUTTON toggle the edit link and the star button. Each of those has a FEATURE_ prefixed equivalent that is used as a fallback, and the compose file shows the same double fallback expressed as nested variable defaults.

Two more settings are worth understanding. ALLOW_INSECURE_TLS skips certificate validation for upstream requests to Uptime Kuma, and the .env.example is explicit that the default is false and it should only be enabled for trusted self-signed environments. ALLOW_EMBEDDING controls whether the page may be embedded in a frame.

The request policy is configurable too, with REQUEST_TIMEOUT_MS, REQUEST_RETRY_MAX and REQUEST_RETRY_DELAY_MS, and a separate SSR_STRICT_MODE switch that makes the root layout throw and render a global error page when every page fails in multi-page mode rather than degrading quietly.

## The timezone requirement that catches everyone

There is a warning box near the top of the README, and it is the single most useful thing to know before deploying this.

From version 1.1.4 onwards the project refactored its time handling logic, and as a consequence the Display Timezone setting in the Uptime Kuma backend has to be changed to UTC+0. The README's own FAQ asks why the times in Kuma Mieru differ from the times in Uptime Kuma, and the answer is that this configuration has to be aligned.

This is the kind of constraint that is easy to mistake for a bug. A dashboard that is offset from the source by a fixed number of hours does not look like a timezone preference, it looks like the chart is wrong. The fix is on the Uptime Kuma side, not in this project, and it is invisible unless you know to look.

The reason the project requires it is structural rather than arbitrary. Kuma Mieru fetches the status page data and does its own time arithmetic to build the latency history, and that arithmetic assumes a single reference timezone. Letting the upstream apply its own offset on top would double-count it.

So before pointing Kuma Mieru at anything, set Display Timezone to UTC+0 in Uptime Kuma, and treat a visible offset as a symptom of that step having been missed.

## Running it locally with Bun

The local path is short, and Bun is the package manager.

```bash
git clone https://github.com/Alice39s/kuma-mieru.git
cd kuma-mieru
```

The README shows how to install Bun itself for both platforms.

```bash
# Linux/macOS
curl -fsSL https://bun.sh/install | bash
# Windows
powershell -c "irm bun.sh/install.ps1 | iex"
```

Then the dependencies and the environment file.

```bash
bun install
cp .env.example .env
```

And the development server.

```bash
bun run dev
```

The README says to open http://localhost:3883 in the browser to see the dashboard. The package.json tells a slightly different story, since the dev script runs next dev with the turbopack flag and an explicit port of 3881, while the Docker compose file maps the container's 3000 to 3883 on the host. The port numbers in the scripts and in the documentation do not line up, so the port you see in the browser depends on how you started it, and it is worth checking the console output rather than trusting the documentation number.

For a production build locally, the same README gives the two commands.

```bash
bun run build
bun run start
```

The start script is not simply next start, it runs a generate step and an init script before launching the standalone server, so the build has a preparation stage that has to succeed before the app runs.

## The generate step and the scripts behind the build

The package.json is where the real shape of this project shows, and the first thing to notice is that nearly every command begins with the same prefix.

```bash
"generate": "bun scripts/generate-config.ts && bun scripts/generate-image-domains.ts && bun scripts/banner.ts"
```

Three scripts, and they run before the dev server, before the build, before the start and before the Docker image. The first produces a config file, the second produces a list of image domains, and the third produces a banner. The build, build:analyze, build:cloudflare, dev and start scripts all chain into it.

That ordering has a practical consequence. A deployment that runs next build without running the generate step first will not match a local run, because the generated artefacts are missing. It is also why the Dockerfile copies the scripts and utils directories before installing dependencies, so that the generate step can run against a cached dependency layer.

The linting setup is worth a mention too, because it is not the common one. Instead of ESLint with a config file, the project uses oxlint for linting and oxfmt for formatting, with oxlintrc.json and oxfmtrc.json at the root, and the scripts are lint, lint:fix and format. The tests are run with bun test.

There are also three Cloudflare-specific commands, build:cloudflare and deploy:cloudflare, which set CF_DEPLOYMENT and go through opennextjs-cloudflare. The README, however, marks the Cloudflare Workers route as not currently supported and recommends Vercel or Netlify instead, with a link to an issue discussion.

## Deploying to Vercel and running the container

The recommended deployment is Vercel, and the steps are a fork, an import, an environment variable and a deploy.

The README asks that the forked repository be public, because otherwise the automatic sync of upstream updates does not work, and it makes the point that all configuration lives in environment variables, so the fork does not leak your configuration.

The Vercel side is: import the fork from the Vercel new project page, add the UPTIME_KUMA_URLS variable, and deploy. Updating later is a Sync fork followed by Update branch in the GitHub fork, which is the standard fork workflow and the reason the README asks for a public fork.

The Docker route is marked as beta. The compose file builds from the published image.

```bash
docker compose up -d
```

The service then runs on port 3883 on the host, mapped to 3000 in the container, and the logs are followed with.

```bash
docker compose logs -f
```

For a plain docker run, the image comes from GHCR.

```bash
docker pull ghcr.io/alice39s/kuma-mieru:1
```

The compose file's healthcheck is worth reading because it tells you what the project considers alive.

```yaml
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/health']
      interval: 30s
      timeout: 3s
      retries: 3
```

A health endpoint under /api that the container probes every thirty seconds with three retries is a sensible design for something you will run unattended. The compose file also mounts a tmpfs at /tmp and sets a restart policy of unless-stopped, and the Dockerfile is a two-stage build on node:26-alpine that installs Bun globally in the builder stage and runs bun install with the frozen lockfile before the Next.js build.

## Where Kuma Mieru is the wrong tool

The first limitation is that it is a second system to run. Uptime Kuma does the monitoring, and Kuma Mieru does the presentation, and they are separate deployments with separate configuration, separate upgrade cycles and separate failure modes. A team that wanted one status page and now has two containers to patch has taken on more than they signed up for. The Docker route is still labelled beta, which is a fair signal of where that sits.

The second is that it only reads the public status page. That means it inherits whatever the status page exposes, and it means the monitor set and the incident data are Uptime Kuma's to configure. Anyone hoping for a monitoring or alerting improvement here will not find one, and the README's own comparison is with the built-in status page, not with the monitor.

The third is the UTC+0 requirement, which is not optional and which changes a setting in the upstream system. That is an invasive requirement for a secondary component to impose, and a team with several Uptime Kuma instances configured for local display will have to change them.

The fourth is the Cloudflare Workers gap. The build commands for it exist in package.json, but the README states the deployment route is not supported and points to an issue. The Vercel route is the supported one, which means a team standardised on Cloudflare has to bring its own adapter or use Netlify.

The fifth is that the Recharts dependency brings the bundle weight of a charting library to a page whose data set is small, and the latency charts are the only thing here that the built-in status page does not already attempt. For a page with a handful of monitors, the extra machinery buys less than it does for a deployment with hundreds.

## Kuma Mieru compared with the built-in status page and with Better Stack

The comparison with the built-in Uptime Kuma status page is the closest one, and the difference in approach is that the built-in page is a list while this is a chart. The built-in page tells you which monitors are up right now, which is exactly what a status page for a public audience needs and what Uptime Kuma's own interface already does well for internal use. Kuma Mieru adds the dimension the built-in page lacks, which is how a monitor behaved over time, and it does so by fetching the same status page data and rendering it differently.

That also means it is a replacement for the presentation layer only. If your need is a prettier public page, the built-in page is the baseline and this is the upgrade. If your need is a better internal monitoring experience, this is the wrong project, because the built-in Uptime Kuma interface is where that work goes.

The second comparison is with a hosted status page service such as Better Stack or Uptime Robot, and the README has a FAQ entry on exactly this. The difference in approach is that a hosted status page is a product you configure through a web interface and pay for, while Kuma Mieru is software you host and point at a status page you already run. The hosted option gives you a maintained public status page without a second deployment, and Kuma Mieru gives you charts and theming without a vendor.

The third comparison is with building the dashboard yourself, which for a team with frontend capability is a real option. The chart of latency over time is not hard, and the fetching of status page data is a single request. What is not trivial is the timezone handling, the incident and announcement synchronisation, the theming and the responsive layout, and those are the parts this project already contains.

## Licence, maintenance and what to verify after deploying

The licence field on the repository records MPL-2.0, and the package.json agrees. The file-level copyleft is the right fit for a web application that people self-host and may want to modify, since a change to a covered file has to be published, while the deployment as a whole does not.

The project is not archived and the last push was on 2026-10-15, so it is actively worked on. The release history shows a steady patch cadence, with v1.7.4 from 2026-06-27, v1.7.3 from 2026-05-25 and v1.7.2 from 2026-05-23. The repository also carries a SECURITY.md, a CODE_OF_CONDUCT.md and a CONTRIBUTING.md.

Five things to check after you have it running.

Whether the times line up with the Uptime Kuma backend, which is the UTC+0 setting and the most likely first complaint. Whether the monitors you expect are present, since the data comes from the status page and a monitor missing from the status page is missing here. Whether the auto-refresh is actually refreshing, since the README makes the real-time behaviour a headline feature. Whether ALLOW_INSECURE_TLS is left at its default, since enabling it is only appropriate for a trusted self-signed environment. And whether ALLOW_EMBEDDING is what you want, since it controls whether the page can be framed by another site.

One deployment note worth carrying over from the fork instructions: the configuration lives in environment variables, so a fork does not carry your settings with it, but a public fork does publish whatever you commit, so keep configuration out of committed files.

## Conclusion

Kuma Mieru suits someone who already runs Uptime Kuma and wants a public status page that shows latency history and looks presentable, and who is willing to host a second component alongside the monitor. It is the wrong tool if you want alerting or uptime checks, since the project only reads the status page, and the wrong choice if you need it to work without setting the Uptime Kuma display timezone to UTC+0. Before deploying, point UPTIME_KUMA_URLS at your status page URL, and note that the version from 1.1.4 onwards refactored the time handling, so a page that shows a wrong offset is a configuration problem rather than a bug in the chart.

## FAQ

### What does Kuma Mieru do for Uptime Kuma?

It is a third party dashboard that reads an Uptime Kuma public status page and renders it with Recharts, adding latency charts, interactive charts, dark, light and system themes, and synchronisation of incident announcements and status updates. It does not monitor anything or send alerts.

### Which environment variable does Kuma Mieru need to show monitoring data?

UPTIME_KUMA_URLS, set to the full status page URL, with several URLs separated by a pipe character. The older UPTIME_KUMA_BASE_URL and PAGE_ID pair is still supported and is used when UPTIME_KUMA_URLS is not set.

### Why do the times in Kuma Mieru differ from the times in Uptime Kuma?

From version 1.1.4 onwards the project refactored its time handling, so the Display Timezone setting in the Uptime Kuma backend has to be changed to UTC+0. With that aligned, the times match.

### How do I run Kuma Mieru locally?

Clone the repository, install Bun, then run bun install, copy .env.example to .env, fill in the environment variables and run bun run dev. The README points at http://localhost:3883, while the dev script in package.json starts Next.js on port 3881, so check the console output for the port actually in use.

### How do I deploy Kuma Mieru to Vercel?

Fork the repository as a public repository, import the fork into Vercel, add the UPTIME_KUMA_URLS environment variable and deploy. Later updates come from a Sync fork and an Update branch in GitHub, and the README notes that all configuration is in environment variables so the fork does not leak your settings.

### Can I run Kuma Mieru with Docker?

Yes, and the Docker route is marked as beta. The compose file runs the image ghcr.io/alice39s/kuma-mieru:1 on port 3883 with a healthcheck against /api/health, and docker compose up -d starts it.

## Sources

- [Alice39s/kuma-mieru on GitHub](https://github.com/Alice39s/kuma-mieru)
- [License: MPL-2.0](https://github.com/Alice39s/kuma-mieru/blob/main/LICENSE)
- [Project website](https://kuma-mieru.vercel.app/?r=gh)
- [README](https://github.com/Alice39s/kuma-mieru/blob/main/README.md)
- [Releases](https://github.com/Alice39s/kuma-mieru/releases)

---

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