Docs
chromia.com

Zero to a running dapp in 10 minutes

On this page

Install the Chromia CLI, create a Rell dapp, run it on a local node, then query it and change its state with a transaction. Every command and output on this page was run on 1 November 2026 and re-run for r30 on 3 November 2026 with chr 0.34.3 · Rell 0.16.7 · Java 21.

You need: a terminal on Linux or macOS (Windows: see the full installation guide for WSL, Docker and the dev container) and sudo rights. About 10 minutes, most of it downloads.

Dapp lifecycle: write, test, run locally, then deploy to TestnetOn your machineOn TestnetWrite Rellsrc/main.rell1Testchr test2Run a local nodechr node start3Query & transactchr query · chr tx4fix & re-testLease a containerTestnet Vault · tCHR5Deploychr deployment create6Ship changeschr deployment update7ready to share
The dapp lifecycle. Steps 1–4 run on your machine with chr and PostgreSQL, with no tokens needed. Steps 5–7 put the same project on Testnet.

Install the Chromia CLI2 min

Tested 1 Nov 2026

Terminal
curl -fsSL https://apt.chromia.com/chromia.gpg | sudo tee /usr/share/keyrings/chromia.gpg >/dev/null
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/chromia.gpg] https://apt.chromia.com stable main" | sudo tee /etc/apt/sources.list.d/chromia.list
sudo apt-get update
sudo apt-get install chr

From the official docs · not run in this test

Terminal
brew tap chromia/core https://gitlab.com/chromaway/core-tools/homebrew-chromia.git
brew install chromia/core/chr

Check it worked:

Terminal
chr --version
Output
chr version 0.34.3
rell version 0.16.7
postchain version 3.49.21
EIF version 0.32.7
Java version 21.0.13

Set up PostgreSQL2 min

Rell stores your dapp’s data in PostgreSQL. Create the database and user the CLI expects by default (postchain / postchain).

Tested 1 Nov 2026

Terminal
sudo apt-get install postgresql
sudo service postgresql start
sudo -u postgres psql -c "CREATE DATABASE postchain WITH TEMPLATE = template0 LC_COLLATE = 'C.UTF-8' LC_CTYPE = 'C.UTF-8' ENCODING 'UTF-8';" -c "CREATE ROLE postchain LOGIN ENCRYPTED PASSWORD 'postchain'; GRANT ALL ON DATABASE postchain TO postchain;"

From the official docs · not run in this test

Terminal
brew install postgresql@16
brew services start postgresql@16
export PATH="$(brew --prefix postgresql@16)/bin:$PATH"
createuser -s postgres
psql -U postgres -c "CREATE DATABASE postchain WITH TEMPLATE = template0 LC_COLLATE = 'C.UTF-8' LC_CTYPE = 'C.UTF-8' ENCODING 'UTF-8';" -c "CREATE ROLE postchain LOGIN ENCRYPTED PASSWORD 'postchain'; GRANT ALL ON DATABASE postchain TO postchain;"

Create a dapp1 min

Terminal
chr create-rell-dapp
cd my-rell-dapp

You get a working project: the dapp in src/main.rell, its tests in src/test/, and the project config in chromia.yml.

Output
my-rell-dapp/
├── chromia.yml
├── src/
│   ├── main.rell
│   └── test/
│       ├── arithmetic_test.rell
│       └── data_test.rell
├── .rell_format
└── .rell_lint

The whole dapp is eleven lines:

src/main.rell
module;

object my_name {
    mutable name = "World";
}

operation set_name(name) {
    my_name.name = name;
}

query hello_world() = "Hello %s!".format(my_name.name);
  • object my_name is a single row stored on chain, starting as "World".
  • operation set_name changes state. It runs inside a transaction.
  • query hello_world reads state. Queries don’t change anything.

Run the tests1 min

Terminal
chr test
Output
====================Running unit tests====================
TEST: test.arithmetic_test:test_foo
OK: test.arithmetic_test:test_foo (0.806s)
TEST: test.arithmetic_test:test_bar
OK: test.arithmetic_test:test_bar (0.458s)
TEST: test.data_test:test_add_name
OK: test.data_test:test_add_name (1.233s)
…
SUMMARY: 0 FAILED / 3 PASSED / 3 TOTAL (2.498s)

***** OK *****

Tests run against your local PostgreSQL. If this passes, Java, the CLI and the database are all set up correctly.

Start a local node1 min

This starts a single-node Chromia blockchain on your machine and deploys your dapp to it. Leave it running and open a second terminal in my-rell-dapp for the next steps.

Terminal
chr node start --wipe
Output
Starting node with pubkey: 0324653EAC434488002CC06BBFB7F10FE18991E35F9FE4302DBEA6D2353DC0AB1C
Building Blockchain: my_rell_dapp
Started blockchain my_rell_dapp. Chain-id: 0, brid F6438317F85A756AE5E41485AF846D1D4F27EB1F8BE5FA2B6E27553AC558F091
Node is initialized

--wipe starts the chain from block 0. The node’s REST API listens on http://localhost:7740, which is where the next commands go.

Query your dapp10 s

Terminal
chr query hello_world
Output
"Hello World!"

Send a transaction1 min

Terminal
chr tx set_name Alice --await
Output
transaction with rid B28ECA83E1BFBDE7C63EE67D1957970D014882C0C49AE8A63644C126C94C222E was posted and confirmed

--await waits until the transaction is in a block. Now query again:

Terminal
chr query hello_world
Output
"Hello Alice!"

That’s a dapp running on a blockchain: state in a relational database, changed only by transactions, read with queries.

Change the code and redeploy2 min

Add a query to the end of src/main.rell:

src/main.rell
query greeting_length() = my_name.name.size();

Push the new code to the running node:

Terminal
chr node update
Output
Building Blockchain: my_rell_dapp
Configuration added at height 3
Terminal
chr tx set_name Bob --await
chr query greeting_length
Output
transaction with rid 717673BD82A69BEFDC7095247B6C2A18D8104E6944C1EF099FC58B73295D0F71 was posted and confirmed
3

Stop the node with Ctrl+C in its terminal when you’re done.

Deploy to Testnet15 min

Commands and flags checked against chr 0.34.3 · not deployed in this test

Your dapp works locally. To put it on the public Testnet you need test tokens (tCHR) and a leased container. The full walkthrough is on Deploy to Testnet; the short version, from the same project folder:

Terminal
chr keygen --key-id testnet_container_key
# lease a container at vault.testnet.chromia.com/containers with the printed pubkey,
# add the deployments block to chromia.yml, then:
chr deployment create --network testnet --key-id testnet_container_key

Next steps

How this page was tested

  • Install, project and tests (steps 1–4): run as a script on a brand-new Debian 12 machine (x86-64, 2 CPUs, 473 MB RAM) on 1 Nov 2026: first exactly as the official guide says, then with the fixes shown above. Full transcript ↗
  • Node, query, transaction, update (steps 5–8): run on a Debian 12 workstation with the same CLI, starting from an empty home directory (no keys, no config). On the 473 MB machine the node ran out of memory, so give it at least 1 GB.
  • Re-run for r30 (3 Nov 2026): steps 3 and 5–8 again with chr 0.34.3, a fresh project and an empty home directory; every output matched the page, including both transaction ids.
  • Not run here: the macOS tabs (copied word for word from the official guide), Windows, and the actual testnet deployment (step 9 needs a leased container and tCHR; its commands and flags were checked against chr --help).