This is a full-stack mono-repo example for web3 projects.
It includes a NextJS front-end, a Node.js back-end, and a foundry subproject to maintain smart contracts.
The smart contracts produce Typescript bindings for use in both the frontend and backend, allowing for type safety across the entire stack.
The frontend and backend are set up to communicate with each other using tRPC.
- Setup postgres on local dev for
prisma
- Run:
# Use the project's node version nvm use # Install dependencies pnpm install
To start the whole stack for development, run the following command:
pnpm dev
Note
Notice that you don't have to run any build steps.
The repo doesn't use any postinstall
scripts either.
Everything is handled robustly by Turbo.
Turborepo is used to manage task dependencies in a highly performant way. It does so by parallelizing tasks and caching where appropriate. The onus is on the developer to define the dependencies between tasks and whether their respective outputs can be cached.
This drastically improves DX by automating steps in the development process that would otherwise be manual.
- Code generation + compilation:
graph LR c[contracts .sol] --generate--> a[artifacts .json] a --generate--> ts[typescript\nbindings] ts --imported--> backend ts --imported--> frontend backend --generate--> sdk sdk --imported--> frontend
- Full-stack development:
graph LR s((dev)) --> c c[code generation + compilation] --> backend[start:backend] c --> frontend[start:frontend] c --> chain[start:testing-chain] chain --> deploy[deploy:contracts] backend --> e((ready)) frontend --> e deploy --> e
Traditionally, one would have to either:
- Manually run each step during build / development - painful and time-consuming
- Write scripts (imperatively) to automate the process - error-prone, no built-in caching
Turbo allows us to declaratively define the dependencies between tasks and let it handle the rest.
This entire process can be run in watch
mode, which means any changes to any source code will
trigger the necessary downstream tasks to be re-run.