Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions content/docs/stacks/clarinet/guides/anatomy-of-a-clarinet-project.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
title: Anatomy of a Clarinet Project
description: Learn about how a Clarinet project is structured.
---

import { File, Folder, Files } from 'fumadocs-ui/components/files';

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

<Files className='pointer-events-none'>
<File name="Clarinet.toml" />
<Folder name="contracts" defaultOpen>
<File name="my-contract.clar" />
</Folder>
<File name="package.json" />
<Folder name="settings" defaultOpen>
<File name="Devnet.toml" />
<File name="Mainnet.toml" />
<File name="Testnet.toml" />
</Folder>
<Folder name="tests" defaultOpen>
<File name="my-contract.test.ts" />
</Folder>
<File name="tsconfig.json" />
<File name="vitest.config.js" />
</Files>

## 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.

```toml
[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](https://vitest.dev/).
- `@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:

```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: {
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](https://vitest.dev/config/#pool).
- `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.

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