Anatomy of a Clarinet Project

Learn about how a Clarinet project is structured.


This document provides a detailed overview of the files that need to be present in a Clarinet project. And how to configure the different tools being used. Including Clarinet but also other tools like Vitest, TypeScript, etc.

Project Structure

Clarinet.toml
my-contract.clar
package.json
Devnet.toml
Mainnet.toml
Testnet.toml
my-contract.test.ts
tsconfig.json
vitest.config.js

Clarinet.toml

This is the manifest of the project. It contains the name of the project as well as a few other properties.

This is also this file that will list the smart contracts that are part of the project, including their name and the path to the file. We recommend to always set the clarity_version and epoch to the latest. Especially the epoch, since you smart contract will eventually be deployed in this epoch on mainnet.

[contracts.my-contract]
path = 'contracts/my-contract.clar'
clarity_version = 3
epoch = 3.1

package.json

Because Clarinet relies on Node.js and NPM to write unit tests for your project, there is a package.json file that will list the dependencies of the project. By default, Clarinet comes with the following dependencies:

  • @hirosystems/clarinet-sdk: The Clarinet JS SDK is a version of the Clarinet that is compiled to Wasm that can run in Node.js. It's used to interact with the Simnet.
  • vitest: This the testing framework that Clarinet uses to run the tests. Learn more on the Vitest website.
  • @stacks/transactions: This is the Stacks transactions library that is used to interact with Clarity values in JavaScript
  • chokidar-cli: This is a library that is used to watch the files and re-run tests on changes.
  • vitest-environment-clarinet: this library help bootstrapping the Simnet in the testing environment. For example, it will initialize the Simnet and makes sure it available globally in the testing environment.

As of May 2025, Clarinet 3.0 supports the latest version of these dependencies, especially:

  • vitest 3.x
  • @stacks/transactions 7.x

We recommend to always use the latest version of @hirosystems/clarinet-sdk and vitest-environment-clarinet.

vitest.config.js

This is the configuration file for Vitest. Here, we specify some important settings for the testing framework to work with Clarinet. This is what the default configuration looks like:

/// <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: {
forks: { singleFork: true },
},
setupFiles: [
vitestSetupFilePath,
// custom setup files can be added here
],
environmentOptions: {
clarinet: {
...getClarinetVitestsArgv(),
// add or override options
},
},
},
});

It exports a configuration object with export default defineConfig({ test: {}}) where we specify the following options:

  • environment: "clarinet": Tells vitest to use the vitest-environment-clarinet environment.
  • pool: "forks", now the default value in Vitest 3.x. Tells Vitest to run process in child_process, learn more in Vitest docs.
  • poolOptions: { forks: { singleFork: true } }, run all tests in the same process. Thus allowing efficient re-use of the Simnet and caching. Test isolation is provided by resetting the Simnet for each test. The setupFiles are taking care of it.

tsconfig.json

This is a regular TypeScript configuration file. The compilerOptions are customizable to suit your needs and preferences.

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. In a monorepo setup with multiple package, you might need to adjust the path to node_modules.

"include": [
"node_modules/@hirosystems/clarinet-sdk/vitest-helpers/src",
"tests"
]