Tech Stack
What metrd is built with.
metrd is a monorepo of three deployable pieces plus a shared package, built and released independently.
App
The user-facing web app.
- Next.js 16 (App Router) with React 19
- TypeScript, strict mode
- SignalR (
@microsoft/signalr) for the live connection that drives the display - Generated API client (
packages/api-client), produced by parsing the API's C# controllers and SignalR hubs directly - no separate schema to keep in sync
API
The backend service.
- ASP.NET Core on .NET 10
- Entity Framework Core with Npgsql for PostgreSQL
- Layered as
Service→Business→Data, withClientholding shared request/response contracts andIntegrationholding third-party integration clients, kept dependency-free from the rest of the API - Custom Roslyn analysers (
Metrd.API.Analysers) enforce project-specific conventions at compile time, with code fixes provided where practical - MSTest and Moq for unit tests, plus dedicated convention tests that check structural and naming rules across every project
Site
This documentation and marketing site.
- Next.js 16 with TypeScript
- Docs are plain Markdown files under
Site/docs/, rendered vianext-mdx-remote, with the sidebar generated automatically from the folder structure
Infrastructure
- PostgreSQL 17 as the primary database
- Docker images for the API and App, published to GitHub Container Registry
- GitHub Actions for PR checks, image publishing, and a Docker Compose smoke test on every change to the stack
Performance principles
metrd is built to run on light hardware, not a beefy server, so keeping the API and database frugal is a first-class concern rather than an afterthought:
- Reference data that rarely changes (units, metrics, currencies, display layouts) is served from an in-process hybrid cache rather than re-queried on every request.
- Readings are bucketed for retention (see Readings) so history doesn't grow without bound and older queries scan less data.
- The layered architecture keeps data access confined to repositories, which makes it straightforward to see and control exactly where a database round trip happens.
The guiding rule: every request and every trip to the database counts, so avoid the ones you don't need.
See Coding Standards & Contributing for how these pieces fit together day to day.