Build & publish a dApp
This is the full publishing path for a first Product app: start from a Product
SDK frontend, build a static bundle, register a .dot name, and publish with
the pad deploy CLI. When it works, the app is reachable as <name>.dot inside
the Polkadot app and at https://<name>.dev-dot.li on the web gateway.
This is a devnet
The Polkadot Products Devnet is a public developer preview. Devnet tokens have no real value, and flows may change. Never paste a mnemonic or private key into a shared terminal, a config file you commit, or a support request.
How publishing works
An app is a static bundle. The pad CLI merkleizes your build directory into a
content-addressed DAG-PB archive, uploads its blocks to the Bulletin Chain, then
writes the resulting root CID as an ENS-style contenthash into the DotNS
ContentResolver contract on Asset Hub. The web gateway resolves the name to
that CID entirely client-side and renders the bundle.
flowchart TD
A[Built static dist/] --> B[pad: merkleize to DAG-PB CAR]
B --> C[Chunk ~2 MiB + skip unchanged blocks]
C --> D[Bulletin: TransactionStorage.store_with_cid_config]
D --> E[Store DAG-PB root node = content root CID]
E --> F{DotNS on Asset Hub}
F -->|not owned| G[register name]
F -->|owned| H[skip]
G --> I[setContenthash node = 0xe301 + CIDv1]
H --> I
I --> J[optional Publisher.publish label]
J --> K[Live at name.dot and https://name.dev-dot.li]
Prerequisites
Install the SDK and the CLIs you will use:
npm i @parity/product-sdk
npm i -g @parity/polkadot-app-deploy # deploy CLI (bin: pad)
npm i -g @parity/dotns-cli # DotNS CLI (bin: dotns)
npm i -g @polkadot-community-foundation/cdm-cli # contract manifest CLI (bin: cdm)
The publishing CLIs (pad and dotns) select a network with
--env <network>. CDM uses -n/--name <network> instead. The concrete preset
name for the public devnet is provided by the team operating the network — see
Networks & endpoints.
You need storage authorization
The deploy account must own the .dot name and hold a live Bulletin
storage authorization (TransactionStorage.Authorizations). The CLI never
self-authorizes and fails fast if the authorization is missing or expired;
the network operator grants quota. Fund the account from the
faucet first.
1. Scaffold with the Product SDK
Start from a reference template rather than an empty directory. The playground
template (playground-template.dev-dot.li,
source
playground-app-template)
is a minimal React + Vite + TypeScript app wired to the Host API: it surfaces the
app-scoped product account (SS58 and H160 addresses) and signs a message via
@parity/product-sdk-signer. For a plain HTML/CSS/JS starting point, use
dotli-starter,
which detects the host container with @parity/product-sdk-host and submits
extrinsics through the host provider.
Your app runs as a Product inside the Polkadot host (mobile, desktop, or the
web gateway), which lends it a signer and routes all chain RPC. Reach the
platform through @parity/product-sdk — createApp(config) returns an app with
wallet, chain, and cloud-storage APIs, and the SDK also exposes contract and
identity modules. See
Use platform services from the SDK.
2. Build the frontend
Produce a static build directory. With a Vite template:
The output (dist/) is what you publish. If your app is contract-backed, deploy
and register its PolkaVM contracts first and record them in a cdm.json
manifest with the cdm CLI — see
Deploy & register contracts.
3. Register a .dot name
Names are .dot domains managed by DotNS. Check availability and register with
the DotNS CLI:
Label eligibility depends on length and personhood tier — short or reserved names are gated behind proof of personhood. See Register a .dot name and the Naming architecture for the full rules.
Tip
pad will register the name for you during deploy if the signing account
does not already own it, so this step is optional when you deploy with an
account that will hold the name.
4. Publish with pad
Point pad at your build directory and the target name:
pad uploads the bundle to Bulletin (skipping unchanged blocks on repeat
deploys), registers the name if needed, and writes the content hash on Asset
Hub. Add --publish to also list the app in the on-chain Publisher registry so
directory apps such as Browse can enumerate it:
Once the transaction settles, the app is live at <name>.dot in the Polkadot
app and at https://<name>.dev-dot.li on the web gateway. See
List your app in Browse for discovery.
Reference apps to study
These are working, deployed examples (source under paritytech):
- Simple Survey — storage-indexed app: survey JSON on Bulletin, an Asset Hub contract indexes response CIDs.
- CDM Frontend and DotNS UI — reference tools for contracts and names.