Publishing from the command line
If you keep a widget, theme or partial in a folder, perhaps in a git repository, the tiledash command checks it, packs it and publishes it to the store without opening the app.
It does what the store does when you publish from the editor, and it can pull what others published into a folder of your own.
Install it
You need Node.js 22.22, 24.15 or 26 and newer.
npm install -g tiledashtiledash --helpOr run it without installing, as npx tiledash ….
Sign in
tiledash auth loginThis opens your browser, where you sign in the usual way with your Homey account and choose Allow. The command can then publish under your store name, and nothing else: it cannot change your widgets, dashboards or account.
On a machine without a browser (over SSH, in a container), or with --device, it shows a code instead:
Open https://my.tiledash.app/device on any device and enter: W D J B - M J H TOpen that address on your phone or laptop, type the code and choose Allow. The code works for 10 minutes.
tiledash auth status shows who you publish as and until when, and tiledash auth logout revokes the login at Tiledash and forgets it on this computer.
The login is kept in your system’s keychain, or, where there is none, in ~/.config/tiledash/credentials.json, which only you can read.
The command never prints it.
You can also end the login from the app, under Account → AI assistants.
A package folder
tiledash init widget clocktiledash init theme and tiledash init partial make a theme’s or a partial’s folder the same way.
This makes a folder you can check and publish straight away:
tiledash.json: the id (@your-handle/clock), version, title, summary, licence and, for a widget, its settings and sizes, or for a partial, its parameters.template.liquidandstyle.cssfor a widget,theme.jsonandtheme.cssfor a theme, orpartial.liquidandpartial.cssfor a partial.- For a widget, the partials it brings in
partials/:partials/row.liquid,partials/row.css, andpartials/row.jsonwith what that partial declares ({ "params": [...] }). A copy of a store partial sits under its id,partials/@ann/sprinkler.liquid, andtiledash.jsonsays which version it is underuses. README.md, the description on the store page, andCHANGELOG.md, with a section per version..github/workflows/publish.yml, which publishes the folder when you push a version tag.
Edit tiledash.json to put your own store name in the id if init did not know it (signing in first lets it fill it in).
Pictures are optional: icon.png and up to a few files in screenshots/.
Everything else in the folder, such as .git, node_modules and notes, is left out of what you publish.
A partial’s folder
A partial’s tiledash.json declares its parameters under partial.params, each with its name, type, label and whether it is required or what its default is (see Partials):
{ "kind": "partial", "id": "@you/sprinkler", "version": "1.0.0", "title": "Sprinkler", "summary": "A sprinkler that turns while it waters.", "licence": "MIT", "partial": { "params": [ { "name": "on", "type": "boolean", "label": "Running", "required": false, "default": false }, { "name": "zone", "type": "text", "label": "Zone", "required": false }, { "name": "flow", "type": "choice", "label": "Flow", "required": false, "options": [ { "value": "gentle", "label": "Gentle" }, { "value": "strong", "label": "Strong" } ], "default": "gentle" } ] }}The types are boolean (yes/no), number (with min, max and unit if you like), text, choice (with its options), color, icon, device and any.
The starter that tiledash init partial writes names its classes and its animation after the folder, and takes its durations from the theme.
Check it
tiledash check clockThis runs the store’s own checks on your computer: the template and its partials against Tiledash’s demo data, the settings, devices named by their id (a store widget is for every Homey, so use a device setting), and pictures loaded from outside addresses. A partial is checked at its defaults and with each yes/no both ways; it may render only Tiledash’s partials, and names in its style that don’t start with its own name are a warning. Each problem is printed with its file and line, so your editor can jump to it:
clock/template.liquid:3: error: Template syntax: tag "unknowntag" not foundIt exits with a non-zero code when there is an error, so you can use it in scripts and in CI. The store checks your styles and fonts too when you publish.
Publish it
tiledash publish clockThe command packs the folder, uploads it as a new version and prints what the store now has:
Published @you/clock 1.1.0 (widget)Content hash 3f9a…Raise version in tiledash.json for every publish: a version is never changed once it is published.
A version that can break what people made with the one before has to be a new major: for a widget, settings removed or retyped; for a partial, a parameter removed or retyped, or a required one added.
If the folder’s CHANGELOG.md has a section for the version (## 1.1.0), it becomes the version’s notes; otherwise give them with --changelog "What changed".
The commit the version came from is recorded: --commit, else GITHUB_SHA in GitHub Actions, else the current commit when your git working tree is clean.
When the store refuses the package it says why, file by file, and the command exits with a non-zero code.
tiledash pack clock -o clock.zip writes the same zip without uploading it.
Publish from GitHub Actions
Nobody is there to allow a login in CI, so use a publish token instead.
Make one in the app, on the publisher dashboard, and keep it in your repository’s secrets as TILEDASH_TOKEN.
The workflow that tiledash init writes does the rest:
name: Publish to the Tiledash storeon: push: tags: ['v*']jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 24 - run: npx tiledash publish . env: TILEDASH_TOKEN: ${{ secrets.TILEDASH_TOKEN }}When TILEDASH_TOKEN is set, it is used instead of a login.
Compare and pull
tiledash diff @anna/clock@1.2.0 @1.3.0tiledash diff @anna/clock@1.2.0 ./clockThis shows what changed between two versions, or between a published version and your folder, file by file in colour. Without a second version it compares with the latest.
tiledash pull @anna/clocktiledash pull @anna/clock@1.2.0 my-clock --as @you/my-clockThis writes a published version as a folder.
With --as it is your own fork, starting at version 1.0.0; the folder names the version it came from, so the store shows the fork’s lineage when you publish it.
Without --as, set the id to your own store name before you publish.
Another Tiledash
Use --api-url (or the TILEDASH_API_URL environment variable) to talk to another Tiledash than my.tiledash.app, such as one on your own server.