Project structure

Understand the complete structure and configuration of a Clarinet project

A Clarinet project follows a carefully designed structure that separates contracts, tests, and configuration. Understanding this structure helps you organize code effectively and configure tools for optimal development workflow.

Core project layout

Every Clarinet project contains these essential directories and files:

main.clar
traits.clar
Devnet.toml
Mainnet.toml
Testnet.toml
main.test.ts
.gitignore
Clarinet.toml
package.json
tsconfig.json
vitest.config.js

Each component serves a specific purpose in your development workflow. Let's explore how they work together to create a complete development environment.

The project manifest

Clarinet.toml

The Clarinet.toml file is the heart of your project. It defines project metadata and tracks all contracts:

Clarinet.toml
[project]
[contracts.counter]
path = 'contracts/counter.clar'
clarity_version = 3
epoch = 3.1
[repl.analysis]
passes = ['check_checker']
[contracts.traits]
path = "contracts/traits.clar"
clarity_version = 3
epoch = 3.1
[contracts.token]
path = "contracts/token.clar"
clarity_version = 3
epoch = 3.1
depends_on = ["traits"]

The manifest handles several critical functions:

  • Contract registration: Every contract must be listed here
  • Dependency management: Defines deployment order through depends_on
  • Version control: Specifies Clarity version and epoch for each contract
  • Boot sequence: Lists contracts to deploy on clarinet devnet start

Testing infrastructure

Package configuration

The package.json defines your testing environment and dependencies:

package.json
{
"name": "counter-tests",
"version": "1.0.0",
"description": "Run unit tests on this project.",
"type": "module",
"private": true,
"scripts": {
"test": "vitest run",
"test:report": "vitest run -- --coverage --costs",
"test:watch": "chokidar \"tests/**/*.ts\" \"contracts/**/*.clar\" -c \"npm run test:report\""
},
"author": "",
"license": "ISC",
"dependencies": {
"@hirosystems/clarinet-sdk": "^2.14.0",
"@stacks/transactions": "^6.12.0",
"chokidar-cli": "^3.0.0",
"typescript": "^5.6.0",
"vite": "^6.1.0",
"vitest": "^3.0.0",
"vitest-environment-clarinet": "^2.3.0"
}
}
PackagePurpose
@hirosystems/clarinet-sdkWebAssembly-compiled Clarinet for Node.js
@stacks/transactionsClarity value manipulation in TypeScript
vitestModern testing framework with native TypeScript support
vitest-environment-clarinetSimnet bootstrapping for tests

Vitest configuration

The vitest.config.js configures the testing framework:

vitest.config.js
/// <reference types="vitest" />
import { defineConfig } from "vite";
import { vitestSetupFilePath, getClarinetVitestsArgv } from "@hirosystems/clarinet-sdk/vitest";
export default defineConfig({
test: {
environment: "clarinet", // use vitest-environment-clarinet
pool: "forks",
poolOptions: {
threads: { singleThread: true },
forks: { singleFork: true },
},
setupFiles: [
vitestSetupFilePath,
// custom setup files can be added here
],
environmentOptions: {
clarinet: {
...getClarinetVitestsArgv(),
// add or override options
},
},
},
});

This configuration enables:

  • Clarinet environment: Automatic simnet setup for each test
  • Single fork mode: Efficient test execution with proper isolation
  • Coverage tracking: Generate reports in multiple formats
  • Custom setup: Add project-specific test utilities

TypeScript configuration

The tsconfig.json provides TypeScript support:

tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ESNext"],
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"strict": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": [
"node_modules/@hirosystems/clarinet-sdk/vitest-helpers/src",
"tests"
]
}

It's important to properly set the include property, by default it points to the helpers files defined in the clarinet-sdk package, and to the tests directory.

Network configurations

Environment settings

Each network has its own configuration file in the settings directory:

settings/Devnet.toml
[network]
name = "devnet"
deployment_fee_rate = 10
[accounts.deployer]
mnemonic = "twice kind fence tip hidden..."
balance = 100_000_000_000_000
[accounts.wallet_1]
mnemonic = "sell invite acquire kitten..."
balance = 10_000_000_000_000

These settings control:

  • Network ports: API, RPC, and explorer endpoints
  • Account configuration: Test wallets with STX balances
  • Chain parameters: Network-specific blockchain settings
Security Notice

Never commit mainnet private keys or mnemonics. Use environment variables for production credentials.

Common issues

Next steps