The Problem: Four Tools, Zero Cohesion
Every cloud architecture project I worked on followed the same fragmented playbook: sketch a diagram in
Excalidraw, write the actual IaC in VS Code, run validation scripts in the terminal, then try to keep the
diagram and the code even vaguely in sync as the architecture evolved. It's 2026 and we're still copy-pasting
CIDR blocks between a drawing app and a .tf file like it's 2015.
The problem isn't any single tool — it's that there's no single workspace. Architects think visually, but infrastructure lives in code. CloudForge was built to close that loop: a visual canvas where every drag, drop, and connection is the infrastructure definition, and deployment-ready code is a side-effect of the design.
Architecture: How the Pieces Fit Together
CloudForge is a full-stack TypeScript monorepo managed with npm workspaces. The repo splits
cleanly into artifacts/ (deployable apps) and lib/ (shared packages), which kept
cross-package imports explicit and prevented the usual monorepo spaghetti.
├── cloudforge/ # React + Vite web app → /
├── api-server/ # Express 5 API → /api
└── cloudforge-mobile/ # Expo (iOS + Android) → /mobile
lib/
├── api-spec/ # OpenAPI spec (single source of truth)
├── api-client-react/ # Generated React Query hooks (Orval)
├── api-zod/ # Generated Zod schemas (Orval)
└── db/ # Drizzle ORM schema + migrations
The guiding principle was code-generate everything that could be generated. The
api-spec package owns the OpenAPI definition. Running
npm run codegen -w @workspace/api-spec regenerates fully-typed React Query hooks and Zod validation
schemas via Orval. The result: frontend types are never manually maintained, and if the API
changes, the TypeScript compiler catches every mismatch at build time — not at 2am in production.
| Layer | Technology | Why |
|---|---|---|
| Monorepo | npm workspaces |
Simple, native, no Nx/Turborepo overhead |
| Language | TypeScript 5.9 · Node 24 | End-to-end type safety; native ESM |
| Frontend | React + Vite + Tailwind v4 | Fast HMR; CSS-first Tailwind architecture |
| Canvas | @xyflow/react (ReactFlow v12) |
Battle-tested graph primitives, extensible node API |
| API | Express 5 | Stable, familiar, async-first error handling |
| Database | PostgreSQL + Drizzle ORM | Type-safe queries without the Prisma magic-proxy |
| Validation | Zod + drizzle-zod | Single schema, runtime + compile-time safety |
| API codegen | Orval | OpenAPI → React Query + Zod, zero manual sync |
| AI | GPT-4.1 via Replit AI | Context-aware prompting with canvas state |
| Mobile | Expo (React Native) | Single codebase, iOS + Android, Expo Go compatible |
| Build | esbuild | Sub-second API server builds |
The Canvas: ReactFlow as Infrastructure Primitive
The visual canvas is the core of CloudForge. I chose @xyflow/react (ReactFlow v12) because it
treats nodes and edges as first-class React state — each cloud component is just a custom React node with its
own config panel, and connections between nodes map 1:1 to resource dependencies in the generated IaC. The
component registry covers 32 services: EC2, VPC, Lambda, RDS, S3, EKS on AWS; AKS, Azure Functions on Azure;
Cloud Run, BigQuery on GCP — each with provider-specific config fields and a validation profile.
State management was the real challenge at scale. A large architecture diagram can have dozens of nodes with deeply nested config objects, real-time validation overlays, and undo/redo history — all of which need to stay in sync without re-rendering the entire canvas on every keystroke. The solution was colocating node state inside ReactFlow's internal store, lifting only the "committed" architecture state to React Query for API persistence, and debouncing writes aggressively.
# The visual connection model maps directly to Terraform dependency graph:
resource "aws_vpc" "app_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "CloudForge-VPC", ManagedBy = "CloudForge" }
}
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.app_vpc.id # ← drawn as an edge on the canvas
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.app_vpc.id # ← another edge
tags = { Name = "CloudForge-IGW" }
}
Design insight: Every edge drawn on the canvas carries semantic meaning — it encodes a
depends_on or attribute reference in the output IaC. Visually drawing a line from a subnet to a
VPC is writing vpc_id = aws_vpc.app_vpc.id. This is what makes the diagram and the code
the same artifact.
Terraform Reverse-Engineering: The Hard Part
Importing an existing .tf file and turning it into a clean canvas layout was the hardest
engineering problem in this project. Terraform HCL is designed to be written by humans, not parsed by tools:
resources use string interpolation for references ("${aws_vpc.main.id}"), modules abstract entire
sub-graphs, locals create intermediate values, and for_each meta-arguments can instantiate multiple
resources from a single block. None of this maps cleanly to a node-edge graph without genuine semantic
understanding.
My approach: build a lightweight HCL AST parser that walks the resource blocks, extracts attribute values, and
runs a reference-detection pass to find implicit dependencies (string interpolation patterns,
depends_on blocks, count/for_each iterators). Detected resources are
matched against the 32-component registry by type, unrecognized resources fall back to a generic "Custom
Resource" node. Then a force-directed auto-layout algorithm (with provider-grouping hints) positions the nodes
so AWS, Azure, and GCP resources cluster visually. It's not perfect on pathological Terraform, but it handles
the 80% case — real-world single-provider infra — cleanly.
// hot take Visual IaC tools failed in the past because they tried to replace code with diagrams. The right abstraction is the opposite: make code the canonical truth and let the diagram be a live, editable view of it. CloudForge succeeds because exporting HCL is a read operation on the canvas state — there's no translation layer that can drift. — Shweta Suryavanshi
The AI Assistant: Context-Aware, Not Generic
The floating AI chat panel is powered by GPT-4.1 via Replit AI Integrations. The key design decision was what context to pass. Generic "ask AI about cloud architecture" tools give you textbook answers. CloudForge serializes the current project state — component types, provider labels, connection topology, and active validation errors — and prepends it as a structured prompt context before every message. The result: "Should I add a NAT gateway?" gets an answer that looks at your actual canvas, not a five-paragraph essay about NAT gateways in general.
Prompt orchestration lives in the /api/ai/chat route on the Express server, not the client. This
keeps the context-assembly logic server-side, makes it easy to iterate on prompt structure without app
redeployments, and avoids leaking the OpenAI API key to the browser.
Multi-Format Export: One Model, Four Outputs
The export engine (POST /api/export) takes the canvas node-edge graph and a format
parameter, then walks the same dependency-ordered graph to emit the target syntax. Each cloud component has a
code-generator interface with four implementations: toTerraform(), toCloudFormation(),
toKubernetes(), toYAML(). Supporting multiple outputs from one visual model forces you
to build a genuinely provider-agnostic internal representation — which paid dividends when adding new
components, since you only write the graph model once and all four exporters just work.
What's Coming Next
The roadmap is AI-heavy. I'm building automated cost estimation that annotates components with monthly spend projections directly on the canvas, security hardening suggestions that flag specific misconfigurations with remediation steps, and a resiliency scorer that grades the architecture's high-availability posture. The endgame is turning the canvas into a live architecture health dashboard, not just a design tool.
On the collaboration side: Google-Docs-style real-time multi-user editing via WebSockets, GitOps pipeline
integration (push to a branch, CI runs terraform plan), and infrastructure drift detection that
re-imports the live state and highlights canvas divergences. The vision is CloudForge as the operating system
for cloud architecture — design, validate, deploy, and monitor, all in one place.