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.
Development
Section titled “Development”First, clone the Daemun repository.
For installing NPM packages, this project uses pnpm (and so should you!):
pnpm installStart the development server:
pnpm devOpen http://localhost:3000 to start.
This is a Hono application with Vite-built React client assets.
Code Linting
Section titled “Code Linting”Once dependencies have been installed you can lint your code with
pnpm lintTesting
Section titled “Testing”Daemun uses Vitest for unit and component tests.
Run the test suite:
pnpm testRun the test suite with coverage:
pnpm test:coverageWhat tests to include
Section titled “What tests to include”- 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 undertest/pages/**.
Code Formatting
Section titled “Code Formatting”To ensure a consistent style and formatting across the project source, run the JavaScript toolchain checks before committing.
pnpm lintpnpm testPreferring 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 Feature or Enhancement Guidelines
Section titled “New Feature or Enhancement Guidelines”- 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.
Service Widget Guidelines
Section titled “Service Widget Guidelines”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)fromutils/widget-fieldsto 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.