Skip to content

Typed, supervised dataflow on the BEAM

Build systems.
See everything.

Turn AI-written software into a system you can understand. Small, typed blocks. Explicit connections. Checked before it runs.

events.bloccs Network compiled
An isometric network: ingest feeds validate, then by-type splits into deliver and archive. HTTP and database capabilities are marked on their nodes.
validatePure transform · Event@1 → Event@1
mix.exs{:bloccs, "~> 0.9"}
Open source · Apache-2.0Built on Elixir / OTP / Broadway

More code shouldn't mean
less understanding.

AI can write the implementation. You should still be able to see the architecture.

With bloccs, you and your AI work on the same small manifest. The graph makes the connections visible. The compiler checks the contracts. You stay in the loop.

The anatomy of a blocctransform

Small pieces.
A complete picture.

Each blocc says what comes in, what goes out, and what it can touch. Ordinary Elixir does the work inside.

Typed at the edges

Versioned schemas make every connection explicit. Ports must agree before a network compiles.

Pure at the core

Small functions you can read and test. Same input, same output, with no hidden side effects.

Explicit about effects

HTTP, database, and other capabilities are declared at the boundary. The badge makes them visible.

Meet all 12 primitives
01

Describe the system

Write a TOML manifest, or have your AI edit one. Review the graph and the functions behind it.

02

Check every connection

The compiler validates typed ports, schema compatibility, and declared capabilities.

03

Run on solid foundations

Compile to a Broadway supervision tree, with OTP fault tolerance, back-pressure, and tracing.

Confidence, before runtime

A beautiful graph.
With a compiler behind it.

Change a contract. Remove a capability. See where the network stops.

events.bloccs5 nodes / 4 edges

Event@1 /All connections agree

Try the contract
Checked

mix bloccs.validate events.bloccs

5 nodes · 4 edges · 2 declared effects. Every edge connects ports that agree on their schema, and no node reaches past what it declared. The network compiles.

Rejected

Rejected · schema mismatch on by-type.known → deliver.event

by-type.known emits Event@1. deliver.event expects Order@1. An edge may only connect ports that agree on their schema, so the compiler stops here — before a single message moves.

Rejected

Rejected · undeclared effect in deliver

deliver declares no effects, but its effect shell writes to the database. Effects are declared capabilities, not loose function calls: a node that hasn't declared the database cannot reach for it.

Illustrated validation states, based on bloccs contracts.

For the systems
you actually build.

Real backend patterns. Explicit architecture. Code you own.

Build it. Watch it.
Own all of it.

The library and the dashboard are open source. Everything you need to define, run, and observe your networks.

bloccs

Apache-2.0

The library. A readable manifest becomes a running system.

validate.bloccs
# validate.bloccs — one node
[node]
id   = "validate"
kind = "transform"

[ports.in]
order = { schema = "Order@1" }

[ports.out]
valid = { schema = "Order@1" }

[effects]        # none declared -> none allowed

[contract]
pure_core    = "MyApp.Orders.Validate.transform/2"
effect_shell = "MyApp.Orders.Validate.execute/2"
Get started

bloccs_web

Apache-2.0

The dashboard. Follow every message through the system.

The same typed topology can be observed as messages move through the runtime.
Topology · message flow · real coverage

Mount one router macro to inspect the live topology, messages, timings, and what actually executed.

See the dashboard

Before you
connect the dots.

Where bloccs fits, what it compiles to, and what to expect.

Join the discussion
Isn't this just Bubble / no-code?

They aim at opposite outcomes. No-code platforms like Bubble abstract code away so non-engineers can ship, and the result only runs inside the vendor's closed runtime. bloccs is built for engineers: the diagram is a typed spec that compiles to plain Elixir you own, review in a normal PR, and run anywhere. Its job is to make AI-written code reviewable at the speed AI produces it, not to hide the code from you.

Why not just let Claude write the code directly?

Claude writes bloccs — it isn't the alternative to it. Freeform generation means reviewing thousands of lines and trusting the model. A manifest means reviewing a small graph and trusting a compiler that catches mis-wired stages and undeclared effects before anything runs.

What stops an agent from touching things it shouldn't?

Effects are declared capabilities, not loose function calls. A block that doesn't declare HTTP or database access can't reach for it: the compiler rejects any node whose code touches the world outside its declared effects. That shrinks an AI-written change to a graph and a handful of small functions you can read, instead of thousands of lines of generated glue.

What does it compile to?

A Broadway supervision tree on the BEAM. Generated source lands in _build/ so you can read, review, and debug it like any other Elixir — no hidden runtime.

Do I need to know Elixir?

Yes. bloccs is Elixir/OTP and runs on the BEAM — blocks are real Elixir functions and it compiles to a Broadway supervision tree. If your backend already lives on Erlang/Elixir it drops in; if it doesn't, this isn't a way to skip learning the platform.

How is this different from n8n, LangGraph, or Temporal?

n8n and Zapier are closed SaaS automation — your flow runs on their runtime, untyped. LangGraph orchestrates agents in freeform Python. Temporal gives durable execution but you still hand-write every line. bloccs is the one where a typed graph compiles to plain code you own, with the compiler checking wiring and declared effects before it runs.

Is it production-ready?

Within its lane, yes. The runtime is supervised, back-pressured, and capability-checked, with retry, timeout, idempotency, and telemetry wired into every node, on the same BEAM substrate (Broadway/OTP) hardened behind Discord and WhatsApp. What's pre-1.0 is the surface: the public API and manifest format can shift between minor releases, so pin a version. The one thing bloccs leaves out by design is durability — in-flight messages live in memory, so put Oban or a broker at the edges for work that must survive a restart.

When should I not use bloccs?

When the work isn't a graph of typed stages. A single ingest → process → batch pipeline is Broadway's job, and bloccs would only add a layer. Work that must survive restarts, run exactly-once, or be scheduled is a durable job — that belongs in Oban, at the edges of a network. "Component A must be incapable of calling component B" is a module-dependency rule that boundary enforces at compile time, which bloccs doesn't replace. Ad-hoc state or one-off concurrency is a plain GenServer or Task. And it isn't a web page or content-block builder. bloccs earns its keep once you have a graph of effectful stages you want declared, checked, and reviewable.

What's free and what costs money?

The core is open source and free under Apache-2.0: the library plus a dashboard to watch systems run. A commercial Pro tier (bloccs.pro) is for teams in production — governance and audit, guarantees, support, and a hosted option. Free earns adoption; Pro is what a company needs once this is load-bearing.

Your next system.
In plain sight.

Start with a blocc. Build something you understand.

Get started
{:bloccs, "~> 0.9"}