For the complete documentation index, see llms.txt
Create a Midnight DApp
This guide explains how to scaffold a Midnight DApp using the create-mn-app CLI tool.
Prerequisites
The following tools are required to run a Midnight DApp:
- Compact compiler
0.31.0installed. See install the toolchain for instructions. - Docker Desktop installed and running, with Docker Compose v2.
- Node.js version 22+ installed. You can use NVM to install Node.js.
Midnight CLI tool
The create-mn-app CLI tool provides starter templates for Midnight DApps. It includes a preconfigured TypeScript setup, hot reloading, and wallet operation logic.
To scaffold a new DApp, run the following command:
npx create-mn-app [project-name]
Ensure you replace [project-name] with the name of your new DApp.
The CLI tool first prompts you to choose the type of project you want to create:
- Contract
- Full DApp
If you are new to Midnight development, then starting with contract is recommended. It provides a minimal setup that focuses on compiling and deploying a Compact smart contract before working with a full application scaffold.
Contract
Selecting Contract scaffolds a minimal project for deploying a Compact smart contract. You are then prompted to choose a contract template:
| Template | Description |
|---|---|
hello-world | Default. A message-storage contract bundled with a local devnet for compiling, deploying, and interacting with a Compact contract. |
battleship | A private-board state machine, cloned from example-battleship. |
Only hello-world ships the bundled devnet and the --network flag.
Full DApp
Selecting Full DApp scaffolds a complete decentralized application with a browser-based or CLI interface for interacting with the contract. You are then prompted to choose a DApp template:
| Template | Description |
|---|---|
bboard | Default. A privacy-preserving bulletin board, cloned from example-bboard. |
leaderboard | A React + Lace browser DApp with in-browser ZK proving, cloned from midnight-leaderboard. |
dex and midnight-kitties appear as coming soon in the template picker. Full DApp templates follow their upstream repository's README rather than the bundled devnet flow described below.
For this guide, select Contract at the first prompt and then choose hello-world at the template selection prompt. Follow the remaining prompts to complete the setup.
Creating a new Midnight app in /path/to/my-app.
Template: hello-world
✔ Project structure created
✔ Dependencies installed
✔ Git repository initialized
✔ Docker is ready for proof server
✔ Contract compiled successfully
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 Success! Your Midnight app is ready.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Once the installation is complete, navigate to the my-app directory:
cd my-app
Your project structure should look similar to this:
my-app/
├── contracts/
│ └── hello-world.compact # Compact smart contract
├── src/
│ ├── cli.ts # Interact with deployed contract
│ ├── deploy.ts # Deploy contract
│ └── check-balance.ts # Check wallet balance
├── docker-compose.yml # Local devnet: node, indexer, proof server
├── package.json
└── .midnight-state.json # Deployment state (gitignored; contract address and network)
The contracts/hello-world.compact file contains the Compact smart contract code.
pragma language_version >= 0.23;
import CompactStandardLibrary;
export ledger message: Opaque<"string">;
export circuit storeMessage(customMessage: Opaque<"string">): [] {
message = disclose(customMessage);
}
Compact is Midnight's smart contract language used to define contract logic. It is similar to TypeScript but is designed for use with the Midnight runtime.
The docker-compose.yml file defines a local devnet, a Midnight node, indexer, and proof server that runs in Docker. The proof server generates Zero Knowledge (ZK) proofs for smart contracts on the Midnight network. The devnet must be running before you can deploy or interact with the contract.
Set up the project
Run the setup script:
npm run setup
npm run setup boots a local devnet in Docker (node, indexer, and proof server), compiles the contract, and deploys it. You don't need a wallet extension or a faucet — the local dev preset pre-mints NIGHT to a genesis seed, which funds the deployment automatically.
The CLI writes deployment state to .midnight-state.json (Git ignores this file), which holds the contract address and the active network. The CLI references this file when interacting with the contract.
Interact with the contract
After you deploy the contract, start the interactive CLI:
npm run cli
The CLI lets you interact with the deployed contract:
1. Store a message
2. Read current message
3. Check wallet balance
4. Exit
Choose an option from the menu and follow the prompts. To read the ledger state directly, run the end-to-end test:
npm run test:e2e
Deploy to a public testnet
The local devnet is the default. Public testnets are opt-in, pass --network to npm run setup:
npm run setup -- --network preview
The first time you target a public network, the CLI generates a wallet and prints a faucet URL to fund it. Open the preview faucet or preprod faucet to fund the wallet. The network selection is sticky; switch networks later with npm run network <name>.
| Network | Source | When to use |
|---|---|---|
undeployed | Local devnet (docker-compose.yml) | Default. No funding or wallet extension required. |
preview | Public preview (faucet) | Shared infrastructure before a release. |
preprod | Public preprod (faucet) | Closest to mainnet. |
Templates
The Midnight CLI tool provides starter templates for both contracts and full DApps. Pass a template with --template <name>, or omit it and the CLI prompts you to choose.
Hello world
The hello-world template is a message storage contract that allows you to post and retrieve messages on the blockchain. It ships with the bundled local devnet.
npx create-mn-app my-app
hello-world is the default and comes with dependencies installed. You don't need the --template flag to create a new hello-world project.
Battleship
The battleship template is a private-board state machine, cloned from example-battleship.
npx create-mn-app my-app --template battleship
Bulletin board
The bboard template is a privacy-preserving bulletin board DApp that allows you to post and remove messages, cloned from example-bboard.
npx create-mn-app my-app --template bboard
This template uses ZK proofs to verify the identity of the poster and the owner of the message without revealing their identity on-chain. To learn more about the Bulletin board DApp, see the Bulletin board DApp example.
Leaderboard
The leaderboard template is a React + Lace browser DApp with in-browser ZK proving, cloned from midnight-leaderboard.
npx create-mn-app my-app --template leaderboard
create-mn-app v0.4.2 removed the Counter template. You can still scaffold the retired Counter example with the --from flag:
npx create-mn-app@latest my-app --from midnightntwrk/example-counter
CLI options
The following options are available when creating a new DApp using the create-mn-app CLI tool:
| Option | Description |
|---|---|
-t, --template <name> | Select a template: hello-world, battleship, bboard, leaderboard |
--list | List the available templates |
--from <owner/repo> | Scaffold from a GitHub repository |
--network <name> | Set the network for the hello-world template (undeployed, preview, preprod) |
-y | Accept defaults without prompting |
--dry-run | Show what the CLI would create without writing files |
--use-npm/yarn/pnpm/bun | Force the use of a specific package manager |
--skip-install | Skip the installation of dependencies |
--skip-git | Skip the initialization of a git repository |
--verbose | Show detailed output when creating the project |
-h, --help | Show help |
-V, --version | Show the version of the CLI tool |
Next steps
Now you know how to scaffold a new DApp using the Midnight CLI tool. Check out the hello world tutorial to learn how to write your first Midnight contract using the Compact language.