We tried Flowise. We tried n8n. We understood what they were built for, and we understood that it wasn’t what we needed.
Flowise is well built for what it is: a visual tool for wiring LLM chains quickly. The problem is that under real load, it eats memory. Not because it’s poorly designed. Because its architecture makes tradeoffs that are reasonable for a general-purpose tool and wrong for what we are building. When you are running dozens of concurrent AI agents with complex orchestration logic, the overhead compounds fast.
n8n is a different problem. It is an excellent automation tool for integrating services. But when you try to use it as the backbone for heavy multi-agent structures, you feel immediately that it was not designed for that. The abstraction layer it gives you is the wrong one. You are bending a workflow automation tool into something it was not meant to be, and the architecture fights you.
So Bryan, Dimas, and I started building Klayen Agents. It is the first product of Klayen, the agency I am involved in now.
Bryan and Dimas are the kind of engineers you don’t find easily. Bryan has a sense for interfaces that I rarely see: he thinks in systems and in user experience at the same time, and he doesn’t stop until the thing feels right. Dimas goes deep. When he takes ownership of a layer, he owns it completely. He reads the spec, he asks the hard questions, and then he ships something that makes you think he’s been thinking about this problem for years.
Working with both of them has made the project better than it would have been in any other configuration. It has also changed me. Watching how Bryan approaches a problem from the interface down, and how Dimas approaches the same problem from the domain up, has sharpened how I think about architecture and about what good engineering actually looks like in practice. I came into this with a direction. They are helping me understand it more clearly.
The core idea is this: AI agents should be designed visually and compiled into something that runs on bare metal with minimum overhead. Not interpreted at runtime by a platform that adds its own layer between the logic and the machine. Compiled. Like a program.
The output format is called .wf. Internally it is a zip: a config.json with trigger declarations and dependency metadata, an index.js produced by bun build, and a source.json that keeps the original graph for hot editing. When you build a workflow in Klayen Studio, you are not saving a configuration file that some runtime interprets later. You are producing an artifact that runs directly on Bun.
There are two execution modes. During development you use the GraphRunner, which interprets the graph in real time. It supports bidirectional callbacks between nodes, a short-lived ContextStore for shared state across the graph, and hot reload. It is slow relative to production but it is designed for that: you want to see what is happening while you build. In production you switch to the CompiledRunner, which executes the bundled artifact directly. The interpretation layer disappears.
The core is pure TypeScript with zero infrastructure dependencies. No database calls. No file system access. No HTTP. The domain and application layers know nothing about how things are stored or executed. They define what a workflow is, what a node is, what an agent is, and what operations can be performed on them. Everything else comes through ports. Hexagonal Architecture applied seriously, not as a label.
The composition root is a single function:
createKlayenEngine({
repository, // WorkflowRepository
source, // WorkflowSource
bundler, // WorkflowBundler
store, // CompiledArtifactStore
})
Four adapters. The core does not care whether the repository is in-memory or PostgreSQL, whether the bundler runs locally or in a Bun worker pool, whether the store writes to the local filesystem or S3. You swap the adapter. The core does not move. That is what lets you run the same domain logic in a CLI, a web server, and an MCP server without duplicating business rules. We have all three planned.
The monorepo is managed with Turborepo, persistence with Drizzle ORM, the visual studio with React Flow.
Where we are right now: the domain layer is solid, the composition root is working, the web app is wiring capabilities against an in-memory repository. The bundler and compiled runner are next. Bryan is leading the frontend. Dimas is deep in the core, which is exactly where you want someone who thinks the way he does. I am holding the architectural boundaries and making sure the adapters stay clean.
I don’t know exactly when this ships. We are three people building something that has to work completely or not at all, there is no partial version of it that is useful. That is fine. I would rather build something real slowly than build something half-baked fast.
We are building it anyway.
