# Typical dapp project structure

**URL:** <https://forum.flow.com/t/typical-dapp-project-structure/814>\
**Category:** 🛠 Developer Tools\
**Created:** [January 25, 2021, 9:10pm UTC](https://forum.flow.com/t/typical-dapp-project-structure/814 "2021-01-25T21:10:13Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![pete](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/pete/32/191_2.png) [@pete](https://forum.flow.com/u/pete)\
**Post date:** [January 25, 2021, 9:10pm UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/1 "2021-01-25T21:10:13Z")

</div>

There’s been some discussion about how to best structure the codebase of a Flow application. Often this means finding a home for the following:

- Cadence smart contracts
- Cadence transactions and scripts
- Frontend web app (JS)
- Backend app (optional, any language)

While we don’t want to prescribe a rigid structure for dapps, we also want to make sure that the Flow tooling and examples demonstrate common patterns that promote composability and ease-of-use for developers.

@flowjosh previously defined a pattern for Cadence-only repositories, which you can see on display here: [GitHub - onflow/flow-core-contracts: Cadence smart contracts that define core functionality of the Flow protocol](https://github.com/onflow/flow-core-contracts/)

[Kitty Items](https://github.com/onflow/kitty-items) is an example of a fully-fledged dapp that includes both Cadence and JavaScript code in the same repository. While a single repo may not be scalable for larger development teams (e.g. teams with separate smart-contract and frontend engineers), it works quite well for small projects.

My opinion is that our tools should define patterns that work for both mono and multi-repo applications, and I’d love to explore what that looks like.

---

<div class="post-metadata">

**Author:** ![chase](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/chase/32/247_2.png) [@chase](https://forum.flow.com/u/chase)\
**Post date:** [January 26, 2021, 9:46pm UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/2 "2021-01-26T21:46:10Z")

</div>

Excited to check out Kitty Items!

Would love to get your thoughts on [DappStarter](https://dappstarter.decentology.com/). We try to do exactly what you’re describing here ‒ provide code with best practices and common patterns to make it easier to build on Flow 🙂

---

<div class="post-metadata">

**Author:** ![pete](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/pete/32/191_2.png) [@pete](https://forum.flow.com/u/pete)\
**Post date:** [January 27, 2021, 12:55am UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/3 "2021-01-27T00:55:18Z")

</div>

Thanks for sharing Chase! I haven’t looked at DappStarter recently – I’ll spin up a new project with it and post my thoughts here

---

<div class="post-metadata">

**Author:** ![flowjosh](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/flowjosh/32/362_2.png) [@flowjosh](https://forum.flow.com/u/flowjosh)\
**Post date:** [January 27, 2021, 2:28am UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/4 "2021-01-27T02:28:16Z")

</div>

I’ve spent some time thinking about this, and with as complicated as Cadence smart contract interactions can be, I believe that that contracts and transactions should be front and center in a typical repo/project, with application code and language-specific packages either being of equal importance, or of lesser importance in the project hierarchy. The contracts and transactions are the core of how the projects function, are agnostic to whatever language everyone is choosing, and are fairly critical for a developer to understand and know where to find when first encountering a project.

This reasoning informed how I structured the repos for the Flow smart contracts, specifically flow-ft, flow-nft, dapperlabs/nba-smart-contracts, and [flow-core-contracts](https://github.com/onflow/flow-core-contracts) which I will use for my example. (my reasoning applies to all).

The important directories are:

```auto
contracts/
transactions/
lib/

```

_ **contracts/** _: This should house the main contracts for the project. Easily accessible from the top level.  
_ **transactions/** _: This should house all of the transactions and scripts that interact with the contracts and act as a single source of truth. The contents of this directory can be organized any way the developer wants, but would probably have a directory for each contract, with subdirectories for different types of users of the contract, and scripts, as I did with the staking contract:

```auto
idTableStaking/
    admin/
    delegation/
    node/
    scripts/

```

I’m not sold on the `transactions` name, so if there is a better idea for the name, I’m all ears.

Last is the _ **`lib/`** _ directory. This is where I believe language-specific packages and libraries should live. As you can imagine, developers coming from many different backgrounds will be wanting to learn how to interact with the contracts and repos, and exposing access to the contracts isn’t as simple as publishing an ABI that every language can import like in Solidity. Each language needs a set of packages for generating common transactions and scripts for the contracts.  
In a mature contract repo, I would imagine something like this for `lib/`

```auto
lib/
    js/
    python/
    cplusplus/
    go/
    rust/

```

Then each language could have a contracts, templates, and test package, or whatever organization makes sense for the specific language or project. These packages would take the templates in `contracts/` and `transactions/` (source of truth top level directories) and package them for their specific language.  
Right now, too many projects are just copying and pasting transactions into their application code, which works fine short term, but if there is ever a breaking change in Cadence or in the contract or transaction code, updating that copied and pasted code will be a huge hassle for projects. Like any other software projects, contracts should publish releases for their transaction and contract packages in the languages they want to support, then projects that depend on them can simply update their versions.

This is how I have it for my contract repos, but unfortunately I haven’t gotten enough help in building packages for languages besides Go. If anyone is interested in helping, I would appreciate it very much!

I could imagine that another top level directory could contain `tests/` that are written in Cadence once the Cadence testing framework is ready.

Lastly, the application code needs a place. This is where I have the least experience from app development best practices, but I think a project could choose between two options.

- Option 1: Use a different repo for the application: Since an application isn’t directly tied to a smart contract, an argument can be made that it should be in a different repo, and then import the packages from the main contract repo. This encourages the decentralized mindset, allows projects to protect proprietary application code, and de-clutters the main contract repo so that the focus can be on the most important part, the contracts.
- Option 2: Use the same repo, but put the application in one or more top level directories. This would make testing and running the application easier, but could complicate the organization of the repository.

I lean towards option 1, but I might be a little biased because I am primarily a smart contract developer. I acknowledge that I am probably missing some pros and cons for the different options for everything I’ve talked about, so I am definitely open for feedback. Even if my structure is deemed the preferred, it still needs a lot of streamlining to be the best it can be.

I’m excited to hear what everyone thinks! I’d like to start coming to consensus soon so apps can start standardizing this. 🙂

---

<div class="post-metadata">

**Author:** ![chase](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/chase/32/247_2.png) [@chase](https://forum.flow.com/u/chase)\
**Post date:** [January 27, 2021, 4:26pm UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/5 "2021-01-27T16:26:26Z")

</div>

That’d be awesome, I appreciate that!

I’m particularly interested in hearing your thoughts in the context of this conversation. We’re always looking for feedback and thoughts on how we can make it easier for devs to build on Flow (and a lot of that is based in this idea of demonstrating common patterns and best practices that devs can copy / learn from). So we’re open to exploring anything and everything you think would simplify the development experience!

---

<div class="post-metadata">

**Author:** ![flowjosh](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/flowjosh/32/362_2.png) [@flowjosh](https://forum.flow.com/u/flowjosh)\
**Post date:** [January 27, 2021, 10:30pm UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/6 "2021-01-27T22:30:47Z")

</div>

@chase @pete @qvvg @JeffreyDoyle @robmyers@hlee @bjartek @ebreuers @MaxStarka @daniel

What do you think about my proposal above? I’ve been thinking about it a lot.

---

<div class="post-metadata">

**Author:** ![bjartek](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bjartek/32/143_2.png) [@bjartek](https://forum.flow.com/u/bjartek)\
**Post date:** [January 27, 2021, 10:39pm UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/7 "2021-01-27T22:39:09Z")

</div>

I like it!

Another issue that I think is worth looking at here is the accounts for the contracts. Right bow the tooling in vscode has to have hard coded address imto the contracts to work properly. However that scales poorly to a model where rhe accounts are differnet on emulator/testnet/mainnet.

In the examples st the start of the thread placeholders that are replaced in are used. However that does nor work with the tooling.

So can the vscode extension get support for a lookup of an account from an alias or something?

---

<div class="post-metadata">

**Author:** ![Mackenzie](https://avatars.discourse-cdn.com/v4/letter/m/3da27b/32.png) [@Mackenzie](https://forum.flow.com/u/Mackenzie)\
**Post date:** [January 31, 2021, 5:30pm UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/8 "2021-01-31T17:30:05Z")

</div>

Hey all, I added an issue to the VSCode extension repo re this:

> <https://github.com/onflow/vscode-cadence/issues/34>
>
> From https://forum.onflow.org/t/typical-dapp-project-structure/814/7
> 
> "Right n…ow the tooling in vscode has to have hard coded address imto the contracts to work properly. However that scales poorly to a model where the accounts are different on emulator/testnet/mainnet. So can the vscode extension get support for a lookup of an account from an alias or something?"

Feel free to ‘flesh it out’ with the details.

---

<div class="post-metadata">

**Author:** ![pete](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/pete/32/191_2.png) [@pete](https://forum.flow.com/u/pete)\
**Post date:** [February 11, 2021, 6:42am UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/9 "2021-02-11T06:42:24Z")

</div>

@flowjosh I’ve been thinking about this more while building the CLI deployment tool and I think your proposed structure makes a lot of sense.

IMO it feels a bit cleaner to have scripts pulled out into their own directory:

```auto
/contracts
/transactions
/scripts

```

Regarding multi- vs mono-repo, I think that’s up to the developer! This structure supports both, and I think our tooling should, too.

I’m also realizing that we shouldn’t be _too_ prescriptive when it comes to file structure. Developers will have their own preferences regarding code organization, and our tools should be flexible enough to support any project structure. However, I still think there’s value in defining a canonical format for us to follow, especially in the early days when so many people are learning.

---

<div class="post-metadata">

**Author:** ![pete](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/pete/32/191_2.png) [@pete](https://forum.flow.com/u/pete)\
**Post date:** [February 11, 2021, 7:05am UTC](https://forum.flow.com/t/typical-dapp-project-structure/814/10 "2021-02-11T07:05:47Z")

</div>

Hey @chase! I created a new DappStarter project and took some notes:

- I think the `cadence` directory here can be flattened so that `transactions` and `scripts` are at the same level as `contracts`: [diligent-tusoupum/packages/dapplib at master · DappStarter/diligent-tusoupum · GitHub](https://github.com/DappStarter/diligent-tusoupum/tree/master/packages/dapplib)
- The `dapplib/src` folder is really cool! I had no idea you were transpiling the Cadence code like that. We’ve been working on something a bit similar lately – it’d be great to collaborate
- Out of curiosity, did you consider making `dapplib/src` a reusable library rather than embedding it directly into each project?
- I was a bit confused when I saw the `src` directory. At first I assumed that it held the Cadence source files, but it looks like it contains JS files that aren’t supposed to be edited. Is that correct?
- I think `dapplib` itself could even just be called `cadence` for simplicity. Does `dapplib` have a special meaning in the context of DappStarter?

This is awesome stuff, looking forward to exploring it more!
