-
Notifications
You must be signed in to change notification settings - Fork 13
Development
How to set up Ultra Card locally, run the dev workflow, and contribute changes.
TL;DR: clone,
npm install,npm run watch:ha. See below for full workflow.
- Node.js ≥ 20 (20 LTS recommended)
- npm (bundled with Node)
- A working Home Assistant instance for testing
- (macOS) the HA config volume mounted at
/Volumes/config, orHA_DEPLOY_PATHset to your HAwww/community/Ultra-Cardfolder
git clone https://github.com/WJDDesigns/Ultra-Card.git
cd Ultra-Card
npm installThe fastest loop:
npm run watch:haWhat this does on every save:
- Webpack rebuilds the bundle (~8–10s).
- Built file auto-deploys to your HA
www/community/Ultra-Card/. - Console prints
✓ Auto-deployed to HA. -
Refresh your HA browser (
F5/Cmd+Shift+R) to see changes — no HA restart needed.
If your HA volume isn't at /Volumes/config, set the path explicitly:
HA_DEPLOY_PATH=/path/to/ha/config/www/community/Ultra-Card npm run watch:haHA aggressively caches frontend resources. Open DevTools, Network → Disable cache, and keep DevTools open while developing. Or do a hard refresh (Cmd+Shift+R / Ctrl+Shift+F5).
| Script | What |
|---|---|
npm run watch:ha |
Recommended. Watch mode + auto-deploy to HA. |
npm run dev:ha |
Alias for watch:ha. |
npm run watch |
Watch mode (auto-deploys when HA path is found). |
npm run dev |
Standalone dev server with hot reload (localhost:8080). |
npm run build |
Production build (dist/). |
npm run build:deploy |
Build + run deploy.js. |
npm run build:release |
Run the release script (creates a tagged release). |
npm run build:prerelease |
Same but as a prerelease. |
npm run typecheck |
tsc --noEmit. |
npm run lint / lint:fix
|
ESLint. |
npm run test / test:run / test:coverage
|
Vitest. |
npm run validate:translations |
Sanity-check translation JSON files. |
npm run translations:stats |
Coverage report per language. |
npm run sync:panel |
Copy built sidebar panel into the integration repo. |
npm run release:check |
Run before any release — typecheck + lint + tests + translations + prebuild + production build. Same pipeline as CI. |
src/
├── cards/ Top-level <ultra-card> Lit element
├── modules/ Module implementations + registry + manifest
├── editor/ Visual editor + selector tabs
├── tabs/ Shared Actions / Logic / Design tabs
├── components/ Reusable UI components (color picker, dialogs)
├── services/ Cross-cutting services
├── translations/ i18n JSON files
├── utils/ Helpers (template processor, layout, color)
├── pro/ Pro features (cloud, premium modules)
├── panels/ Ultra Card Hub sidebar
├── workers/ Web Workers
├── types.ts Single source of truth for config types
└── version.ts Version constant
See Architecture for the deeper tour.
-
Manifest — add a row to
src/modules/module-manifest-data.tswith type / title / description / category / tags. -
Type — add the new
typeliteral to theBaseModulediscriminated union insrc/types.ts, and a dedicated interface for the module's config. -
Implementation — create
src/modules/<your>-module.ts. Start fromsrc/modules/_module-template.tsand follow the canonicalrenderGeneralTabpattern in/.cursor/rules/module-general-tab.mdc. -
Register — add a lazy-loader entry in
src/modules/module-loaders.tsso the module is discoverable. -
Tests — add a unit test for any non-trivial logic (Vitest, alongside the source file or under
src/utils/*.test.ts). -
Translations — add new strings to
src/translations/en.json(the source of truth). Other languages are inherited until translated. -
Doc — write a wiki page (or update the existing one) plus
docs/modules/<your>.mdfor the README cross-link.
Run npm run release:check before pushing your PR. CI runs the same pipeline.
The Ultra Card Hub sidebar panel is served by the Ultra Card Pro Cloud integration, not by HACS:
- Panel changes (anything in
src/panels/) build intodist/ultra-card-panel.jsonnpm run build. - To ship them with the integration, run
npm run sync:panel— copies the built panel into the integration repo (default:../Ultra Card Pro Cloud, override withINTEGRATION_WWW_PATH). - A new integration release is needed for users to receive the updated panel. Updating only the card does not update the panel.
The release pipeline is in scripts/release.js:
npm run release:check # always run first
npm run build:release # creates tagged release
# or for a beta:
npm run build:prereleaseEvery tagged release builds via GitHub Actions; HACS picks up the release automatically.
-
Formatting — Prettier (
.prettierrc). Don't fight it. -
Linting — ESLint with
@typescript-eslint. Runnpm run lint:fixbefore commit. - Comments — explain why, not what. The TypeScript types should make what obvious.
-
Strict mode — TypeScript currently runs with
strict: falseandnoImplicitAny: falsefor compat. Incremental tightening is encouraged; see DEVELOPMENT.md § TypeScript strict mode. -
Use uc-form helpers — most editor inputs go through
injectUcFormStyles(),renderSettingsSection(),renderFieldSection(), etc. Don't write raw HTML form markup. See the cursor rulemodule-general-tab.mdc.
See Translations for the workflow and PR conventions.
- Bugs / features — GitHub Issues
- Discussion / showcase — Discord
- PRs welcome — see the README's Contributing section
Ultra Card · Website · Discord · GitHub Issues · HACS · MIT licensed
- Layout-System
- Logic-and-Conditions
- Templates-and-Jinja
- Actions
- Design-System
- Custom-Variables
- Presets-and-Marketplace
- Pro-and-Cloud
- Modules-Overview
- Content
- Data
- Interactive
- Layout
- Media / Background
- Animated (Pro)
- Inputs (Helpers)
- Card embeds