Get started as a developer¶
On the Polkadot Products Devnet, an app is a static website with a .dot name. You build it, publish it to the Devnet, and people open it in the Polkadot app or in a browser. This page takes you from installing the tools to a live app.
Paseo Next v2
This page covers the PCF Products Devnet (devnet preset). For Paseo Next v2 (paseo preset), see Quick Start with the CLI or Quick Start with RevX.
What you are building¶
These docs call a published app a Product. It is a static web app: HTML, CSS and JavaScript. There is no app store, no backend for you to run and no server between your users and your app.
A Product runs inside a host: the Polkadot app (mobile or desktop) or the web gateway at dev-dot.li. The host provides the wallet, the signing prompts, storage and chain access. Your app talks to the host over a protocol called TrUAPI, so the same code runs on mobile, desktop and the web, and your users never have to handle raw keys or RPC endpoints.
To publish, you upload the bundle to the Devnet and point a .dot domain at it. The name then resolves to your bundle wherever someone opens it.
How the pieces fit¶
flowchart TD
subgraph U[Entry points]
APP[Polkadot app<br/>mobile + desktop]
GW[Web gateway<br/>dev-dot.li]
end
subgraph D[Your Product]
BUNDLE[Static web bundle<br/>.dot domain -> content]
end
subgraph S[Developer tooling]
SDK[Product SDK<br/>@parity/product-sdk]
HOST[Host protocol: TrUAPI<br/>@parity/truapi]
CLIS[CLIs: pad / dotns]
end
subgraph P[Platform services on Paseo]
NAME[DotNS naming<br/>Asset Hub contracts]
STORE[Bulletin content storage]
ID[Identity + personhood<br/>People chain]
MONEY[CASH + assets<br/>People chain / Asset Hub]
CONTRACTS[PolkaVM contracts<br/>pallet-revive]
BROWSE[Browse directory<br/>Publisher registry]
end
APP --> BUNDLE
GW --> BUNDLE
BUNDLE --> HOST
BUNDLE --> SDK
SDK --> HOST
CLIS --> NAME
CLIS --> STORE
HOST --> ID
HOST --> MONEY
HOST --> CONTRACTS
NAME --> STORE
BROWSE --> NAME The Polkadot app keeps keys on the device, runs each Product in a sandbox and speaks TrUAPI to it. You use the SDK in your app code, and the CLIs to name and publish your app. The services on the chains handle naming, storage, identity, money, contracts and discovery.
When you get stuck, first work out which of these layers the problem is in. The architecture overview explains each one, and follows a request from a .dot name to chain storage and back.
Before you start¶
You run every command below through the CLIs from step 1, and you sign with one account. If you don't have a key yet, step 4 shows how to create a throwaway one (no seed to import, no password).
Before a command can touch the chain, that account must be:
- Funded with native tokens on Asset Hub, to pay fees. Use the faucet.
- Mapped to its EVM address. Do this once with
dotns account map --env devnet. Every CLI here signs PolkaVM transactions on Asset Hub, and an unmapped account fails on the first one. - Authorized to write to Bulletin, so step 5 can upload your bundle. See Get storage authorization.
The CLIs don't share a keystore. dotns keeps its own (step 4) and pad takes --mnemonic on the command line. Both can use the same account.
1. Install the tooling¶
pad requires Node.js 22 or newer. On Node 20 it fails at startup with an unrelated-looking error (a module SyntaxError, or Missing WebSocket class), so check with node --version before installing.
npm i -g @polkadot-community-foundation/dotns-cli@latest # dotns
npm i -g @polkadot-community-foundation/polkadot-app-deploy@latest # pad, pad-bootstrap
Install only what you need: pad publishes (and can register the name for you), and dotns manages names in depth. Both are large. Expect a few minutes and roughly 1.5 GB across the global prefix and the npm cache, with no progress output while npm works.
Always take the latest release. These CLIs carry the current contract addresses and network presets inside them, so an older copy can talk to a retired deployment and report success while nothing changes. To upgrade one you already have, re-run the same command.
On some ARM64 platforms (for example Termux on Android), a transitive dependency, node-datachannel, ships no prebuilt binary, and its native build fails during npm i -g. It is only used for optional peer-to-peer CID verification, so skip the build with --ignore-scripts:
In this mode only the peer-to-peer verification path is unavailable. The CLI's gateway-based CID verification still works.
Your app code also needs the SDK, at the version the hosts speak (see Packages & tools):
2. Choose a network preset¶
Both CLIs take the network as a flag, and for this Devnet it is --env devnet. pad and dotns already default to devnet, but they also ship presets for other networks. Pass --env devnet anyway, so a command never lands on another chain by accident.
3. Build a web app with the Product SDK¶
The Product SDK (@parity/product-sdk) gives your app typed access to the host: wallet, storage, chain calls, contracts and identity.
import { createApp } from "@parity/product-sdk";
const app = await createApp({
cloudStorage: { environment: "devnet" }, // defaults to paseo
});
const result = await app.cloudStorage!.upload("hello world");
if (result.ok) console.log(result.value); // the CID
This code only works inside a host. Outside the Polkadot app or the web gateway, createApp() itself throws createApp requires a host product context. Start from the playground-app-template, which is already on the SDK version the hosts speak. For automated tests, use the test host in @parity/truapi-host, described in Use platform services from the SDK.
Build your app to a static directory. The template uses vite build, which writes to dist/.
Build with Claude Code¶
The product-sdk repo is also a Claude Code plugin marketplace. Its skills teach Claude Code the whole SDK: app scaffolding, chain connections, transactions, contracts, cloud storage, statement store, individuality, utilities, and migrating an existing codebase. Install it, then ask "build me a Polkadot app":
/plugin marketplace add paritytech/product-sdk
/plugin install product-sdk@paritytech
/reload-plugins
Each skill is a plain Markdown file under product-sdk/skills/, so other agents and editors can read them as reference too.
The skills follow the SDK's main branch, which is already past 0.39.0. Tell the agent to keep @parity/product-sdk@0.39.0, and check an API against that version when a skill and the installed package disagree.
4. Set up an account and register a .dot domain¶
Your deploy account must own the .dot domain before you can publish to it. This is a CLI signing key, separate from any account in the Polkadot app.
For a hackathon, you don't need to import a seed phrase or set a keystore password. Create a fresh account and pass its mnemonic to the CLIs through the environment:
# One fresh BIP-39 mnemonic, generated with the crypto that ships inside the CLIs
export MNEMONIC="$(NODE_PATH="$(npm root -g)/@polkadot-community-foundation/dotns-cli/node_modules" \
node -e 'const c=require("@polkadot/util-crypto");c.cryptoWaitReady().then(()=>console.log(c.mnemonicGenerate()))')"
export DOTNS_MNEMONIC="$MNEMONIC" # dotns signs with this — no `dotns auth set`, no password
dotns account address # the throwaway's address — fund THIS at the faucet
pad takes the same $MNEMONIC when it publishes (--mnemonic "$MNEMONIC"), so one account both owns the name and deploys to it. The phrase only lives in this shell session. Save it if you want to keep the name. If you discard it, the account really is throwaway.
Set a key, or you sign as a shared account
With neither DOTNS_MNEMONIC/DOTNS_KEY_URI set nor dotns auth set run, dotns falls back to a shared public dev account that anyone can control. A name registered to it is not yours, and anyone can transfer it away. dotns prints a warning on every command when this happens.
To reuse an account across sessions, store a mnemonic or key-uri in the encrypted dotns keystore instead of the environment:
dotns auth set # choose `mnemonic`, paste it, then set a password
dotns account address # confirm the active account
Every later command then needs the keystore password. Export DOTNS_KEYSTORE_PASSWORD to avoid an interactive prompt. See Register a .dot domain for details.
Fund, map and authorize the account as listed in Before you start. Then, with $MNEMONIC exported, register your name:
Pick a label whose stem (the label without any trailing digits) is nine characters or longer. Shorter ones need proof of personhood or are reserved. Registration is a commit-reveal flow that takes a few minutes, so check that it landed before you move on:
Register a .dot domain has the full rules.
5. Publish the bundle with pad¶
pad uploads your static build and points the .dot domain at it. It does not read the dotns keystore, so give it the signer that owns the name:
That account must own the name and hold a Bulletin storage authorization. A successful run ends with Verified on-chain: and the published CID.
Your app is now live as my-cool-app.dot in the Polkadot app and at https://my-cool-app.dev-dot.li on the gateway. To give it a name, description and icon in the directory, add a product config. See Add card metadata.
Next steps¶
Each step above has a full guide under the Guides tab:
-
Bundle, name, deploy and card metadata.
-
Account setup, name rules and the commit-reveal flow.
-
Use platform services from the SDK
Chains, storage, contracts and identity from your app.
To see finished Products, open Calculator or Stopwatch. The full list of reference apps is in More resources.
To try your own app as a user, install the Polkadot app and fund an account. See Create an account & get funds.
| Created: July 16, 2026