The repository is organized in a monorepo structure initialized using Turborepo.
A monorepo allows to keep both client and server apps in the same repository, and to share common code between them.
The apps folder contains client and server folders. Inside packages a single api-client folder contains the shared API definition for both client and server.
The root package.json defines all the shared dependencies and scripts. In this project, the only relevant shared dependency is typescript.
All the apps share some other dependencies like
effectand@effect/schema, which you may consider adding as root dependencies as well. Doing this allows to have the same version of these dependencies in all the apps.The example project instead keeps them separate.
Two turbo command have been added to the root package.json:
typecheck: runs the TypeScript compiler to check for any type errors in the codebasetest: runs thetestscript in all the apps that have it defined (onlyserverin this example)
"scripts": {
"build": "turbo build",
"dev": "turbo dev",
"lint": "turbo lint",
"typecheck": "turbo typecheck",
"test": "turbo test",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
}Other than that, the monorepo configuration doesn't differ much from the initial turborepo setup. I generally prefer to keep the configuration minimal, and only add features when necessary.
You may also consider other monorepo tools like Nx or Lerna.
