Design systems,
visually.
Infra Designer is a web app for visually designing system infrastructures — a Figma for architecture diagrams, but with structured components, validation rules, and real export targets.
Drag, drop, connect, and configure. Then export to Terraform,
Docker Compose, or plain JSON.
What we're building
The core job: drag, drop, connect, and configure infrastructure components on a canvas.
- Canvas with pan / zoom, grid, and snapping
- Component palette — compute, storage, network, queues, CDN
- Drag-and-drop nodes onto canvas
- Connect nodes with typed edges — HTTP, TCP, async
- Node config panel — instance size, region, replicas
- Save / load projects per user
- Export to JSON / YAML
- Starter templates — 3-tier web app, event-driven pipeline
- Real-time collaboration
- Cost estimation per component
- Validation rules — e.g. "DB must live in a private subnet"
- Version history & diffing
- Import from live cloud providers
- Terraform / CloudFormation code generation
How it's built
React Flow handles the hard part — nodes, edges, minimap, controls, and custom node types — so we can ship an MVP fast.
High-level system
Three layers. The browser owns interaction and local state; the server owns identity, persistence and export; Postgres stores the graph.
Schema
Four entities. Nodes and edges both belong to a project and carry flexible JSON config for provider-specific settings.
model User {
id String @id @default(cuid())
email String @unique
projects Project[]
}
model Project {
id String @id @default(cuid())
name String
ownerId String
owner User @relation(fields: [ownerId], references: [id])
nodes Node[]
edges Edge[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Node {
id String @id @default(cuid())
projectId String
project Project @relation(fields: [projectId], references: [id])
type String // "server", "database", "loadbalancer"
label String
config Json // { size, region, replicas }
positionX Float
positionY Float
}
model Edge {
id String @id @default(cuid())
projectId String
project Project @relation(fields: [projectId], references: [id])
sourceId String
targetId String
type String // "http", "tcp", "async"
config Json?
}
Four weeks to MVP
Click any phase to expand it.
Decisions before we start
Five calls that shape the first commit.