That's it. No dependency graphs, no explicit ordering, no YAML. Just components that render to actual infrastructure.
Terraform and Pulumi are great, but they're static. You write a plan, run it, and hope nothing breaks. If you need dynamic orchestration - like deploying a database, waiting for its endpoint, then using that endpoint in your API config - you're writing bash scripts or custom tooling.
CReact treats infrastructure like React treats UI. Components re-render when their dependencies change. Outputs flow naturally through context. The Reconciler figures out what actually needs to deploy.
It's reactive - when a database finishes deploying and outputs its endpoint, components that depend on it automatically re-render and deploy. No manual dependency chains.
It's a compiler - your JSX compiles to CloudDOM (basically an AST for infrastructure). You can diff it, version it, test it without cloud credentials. Only when you're ready does it materialize to real resources.
It's resilient - every deployment is checkpointed and resumable. Crash halfway through? Resume from where you left off. The Reconciler only deploys what changed, like React's virtual DOM but for cloud resources.
It works with existing tools - CReact doesn't replace Terraform or CDK. It orchestrates them. Wrap your Terraform modules as CReact components and compose them together.
Here's a real deployment - 22 resources across 3 regions, 6 reactive cycles, fully automatic:
VPC deployed first. When its outputs became available, subnets and security groups deployed in parallel. When those finished, database and cache deployed. When the database endpoint was ready, Lambdas deployed. When Lambdas got function ARNs, API Gateways deployed. When APIs were live, monitoring deployed.
You didn't orchestrate anything manually. You just wrote JSX components that reference each other's outputs. CReact figured out the rest.
CloudDOM is just a JSON tree. You can diff it like Git, version it, test it without touching AWS. It's the intermediate representation between your code and actual cloud resources.
The Reconciler Figures Out What Changed
Before deploying anything, CReact diffs the previous CloudDOM against the new one. Creates, updates, deletes, replacements - all computed ahead of time. You get a Terraform-style plan but it's just comparing two data structures.
Deployment Is Checkpointed
After each resource deploys, CReact saves a checkpoint. Crash halfway through? Run it again and it resumes from where it left off. No manual cleanup, no orphaned resources.
Outputs Trigger Re-renders
When a resource finishes deploying, its outputs (endpoint, ARN, ID) become available. Any component that depends on those outputs automatically re-renders and creates new resources. It's like useEffect but for infrastructure.
useInstance - Create Resources
Creates cloud resources and provides access to their outputs:
Key Behavior: If any prop value is undefined, creates a placeholder node that doesn't deploy. When dependencies become available, component re-renders and creates the real resource.
useState - Persistent State
Manages state that persists across deployments:
functionApp(){// State survives deployments (stored in backend)const[deployCount,setDeployCount]=useState(0);const[appVersion]=useState('1.0.0');// Update state (takes effect next deployment)setDeployCount(prev=>(prev||0)+1);return<></>;}
Advanced: Can bind to provider outputs for reactivity:
functionDatabaseComponent(){constdb=useInstance(Database,{name: 'my-db'});// This triggers re-renders when db.outputs.endpoint changesconst[endpoint,setEndpoint]=useState(db.outputs?.endpoint);return<></>;}
useContext - Share Dependencies
Shares data between components with reactivity when containing outputs:
constDatabaseContext=createContext<{endpoint?: string}>({});functionDatabaseProvider({ children }){constdb=useInstance(Database,{name: 'my-db'});return(<DatabaseContext.Providervalue={{endpoint: db.outputs?.endpoint// Makes context reactive}}>{children}</DatabaseContext.Provider>);}functionApiConsumer(){const{ endpoint }=useContext(DatabaseContext);// Re-renders when endpoint availableconstapi=useInstance(ApiGateway,{dbUrl: endpoint// Triggers re-render when endpoint changes});return<></>;}
Here's how the 5-layer enterprise application from the examples works:
functionEnterpriseApp(){return(<NetworkProvider>{/* VPC, subnets, security groups */}<DatabaseProvider>{/* Database + cache */}<StorageProvider>{/* S3 + CDN */}<ApiProvider>{/* APIs + load balancer */}<MonitoringProvider/>{/* Analytics + backups */}</ApiProvider></StorageProvider></DatabaseProvider></NetworkProvider>);}// Each provider component:functionNetworkProvider({ children }){constvpc=useInstance(VPC,{cidr: '10.0.0.0/16'});return(<NetworkContext.Providervalue={{vpcId: vpc.outputs?.vpcId}}>{children}</NetworkContext.Provider>);}functionDatabaseProvider({ children }){const{ vpcId }=useContext(NetworkContext);constdb=useInstance(Database,{ vpcId });constcache=useInstance(Redis,{ vpcId });return(<DatabaseContext.Providervalue={{dbUrl: db.outputs?.endpoint,cacheUrl: cache.outputs?.endpoint}}>{children}</DatabaseContext.Provider>);}
# Deploy your infrastructure
creact deploy --entry my-app.tsx
# Development mode with hot reload
creact dev --entry my-app.tsx --auto-approve
# Preview changes
creact plan --entry my-app.tsx