Skip to content

Getting Started

We’ll cover getting Daemun up and running on your local machine for development, as well as some guidelines for developing new features and widgets.

First, clone the Daemun repository.

For installing NPM packages, this project uses pnpm (and so should you!):

Terminal window
pnpm install

Start the development server:

Terminal window
pnpm dev

Open http://localhost:3000 to start.

This is a Hono application with Vite-built React client assets.

Once dependencies have been installed you can lint your code with

Terminal window
pnpm lint

Daemun uses Vitest for unit and component tests.

Run the test suite:

Terminal window
pnpm test

Run the test suite with coverage:

Terminal window
pnpm test:coverage
  • New or updated widgets should generally include a component test near the widget component (for example src/widgets/<widget>/component.test.tsx) that covers realistic behavior: loading/placeholder state, error state, and a representative “happy path” render.
  • If you add or change a widget definition file (src/widgets/<widget>/widget.ts), add/update its corresponding unit test (src/widgets/<widget>/widget.test.ts) to cover the config/mapping behavior.
  • If your widget requires a custom proxy (src/widgets/<widget>/proxy.ts), add a proxy unit test (src/widgets/<widget>/proxy.test.ts) that validates:
    • request construction (URL, query params, headers/auth)
    • response mapping (what the widget consumes)
    • error pathways (upstream error, unexpected payloads)
  • Avoid placing test files under src/pages/** to keep route handlers and page tests clearly separated. Page tests should live under test/pages/**.

To ensure a consistent style and formatting across the project source, run the JavaScript toolchain checks before committing.

Terminal window
pnpm lint
pnpm test

Preferring self-hosted open-source software

Section titled “Preferring self-hosted open-source software”

In general, Daemun is meant to be a dashboard for ‘self-hosted’ services and we believe it is a small way we can help showcase this kind of software. While exceptions are made, mostly when there is no viable self-hosted / open-source alternative, we ask that any widgets, etc. are developed primarily for a self-hosted tool.

  • New features or enhancements, no matter how small, must be linked to an existing feature request with some comments or ‘up-votes’ that demonstrate community interest. The purpose of this requirement is to avoid the addition (and maintenance) of features that might only benefit a small number of users.
  • If you have ideas for a larger feature you may want to open a discussion first.

To ensure cohesiveness of various widgets, the following should be used as a guide for developing new widgets:

  • Please only submit widgets that target a feature request discussion with at least 20 ‘up-votes’. The purpose of this requirement is to avoid the addition (and maintenance) of service widgets that might only benefit a small number of users.
  • Note that we reserve the right to decline widgets for projects that are very young (eg < ~1y) or those with a small reach (eg low GitHub stars). Again, this is in an effort to keep overall widget maintenance under control.
  • Widgets should be only one row of blocks
  • Widgets should be no more than 4 blocks wide and generally conform to the styling / design choices of other widgets
  • Use withWidgetFields(service, defaultFields) from utils/widget-fields to apply default fields and cap configured fields without mutating the service. The helper limits widgets to 4 fields.
  • Minimize the number of API calls
  • Avoid the use of custom proxy unless absolutely necessary
  • Widgets should be ‘read-only’, as in they should not make write changes using the relevant tool’s API. Daemun widgets are designed to surface information, not to be a (usually worse) replacement for the tool itself.
  • Widgets should not allow manually overriding the “refresh interval” setting, as misconfigured refresh intervals can easily lead to performance issues for users.