Project Structure ​
In traditional frameworks, you run an init command and are instantly handed a rigid folder structure that you have to force your application to fit into.
Carotene does the exact opposite. Your folder structure is a direct, dynamic reflection of your architectural blueprints. The monorepo is not pre-determined; it is Contract-Driven.
Let's look at how your project evolves from a blank canvas into a fully scaffolded microservice architecture.
Phase 1: The Blank Canvas (carrot init) ​
When you start a new project by running carrot init my-company, the CLI does not assume anything about your architecture. It simply gives you the minimal workspace needed to start designing:
my-company/
├── carotene.toml # Global workspace configuration
└── system.carrot # Your blank architectural blueprintAt this stage, there are no frontends, no backends, and no generated code. It is just you and the blueprint.
Phase 2: Defining the Topology ​
Inside your .carrot files, you define the physical blocks of your system. Carotene uses the names you assign to your backend and frontend blocks to determine exactly what the monorepo should look like.
Let's say you write the following in system.carrot:
// Define a central backend
backend CoreAPI {
function ProcessRefund(orderId: String) { ... }
}
// Define an internal dashboard
frontend AdminPanel {
view RefundDashboard() { ... }
}
// Define a public-facing mobile app API
backend MobileGateway {
function GetUserProfile(userId: String) { ... }
}Phase 3: Contract-Driven Scaffolding (carrot build) ​
The moment you run carrot build (or carrot dev), the Carotene compiler reads your topology and dynamically generates the monorepo to match it perfectly.
The resulting project structure will look exactly like this:
my-company/
├── carotene.toml
├── system.carrot
│
└── apps/ # 🚀 Dynamically generated based on your blocks
│
├── AdminPanel/ # Matching: frontend AdminPanel {}
│ ├── .generated/ # (Read-only) API clients, types, and routing
│ └── src/ # Your standard frontend UI and components
│
├── CoreAPI/ # Matching: backend CoreAPI {}
│ ├── .generated/ # (Read-only) Routers and structural tests
│ ├── src/ # Implementation stubs (ProcessRefund.ts)
│ └── tests/ # AI-generated business logic tests
│
└── MobileGateway/ # Matching: backend MobileGateway {}
├── .generated/
├── src/ # Implementation stubs (GetUserProfile.ts)
└── tests/The Boundary Rules ​
This dynamic generation creates incredibly clean boundaries between your services:
- The
.generated/Folders (The Boilerplate): Carotene isolates all the tedious networking, typing, and structural tests into these read-only folders. If you renameCoreAPItoBillingAPIin your blueprint, Carotene automatically renames the folder and updates all the internal imports. - The
src/Directory (The Stubs): When Carotene discovers a new function in your blueprint, it generates a human-editable stub inside the corresponding app'ssrc/folder. The AI fills in your@(...)operators here, but you retain full control to edit the code manually. - The
tests/Directory (Editable AI Proofs): The AI-generated business logic tests are placed alongside yoursrc/code, allowing you or your team to manually inspect, tweak, or expand the assertions.
By making the folder structure an output of the compiler rather than a static starting point, Carotene ensures your monorepo never drifts from your architecture. Your codebase is always a mathematically perfect reflection of your .carrotblueprints.