Agentic apps from day one
ACRYL is an agentic IDE that writes its own plugins while it runs. It is built with ACRYL Blends, an open framework where any app, from an IDE to a drum machine, is a set of plugins with an agent inside that operates it and grows it.
A new kind of software: composable software 2.0, agentic from day one
It writes itself
Ask for a feature and the agent inside builds it as a plugin, live, while you keep working.
It repairs itself
The agent tests what it built, finds what is wrong and fixes it; a broken plugin is reverted without a trace.
It adapts to its use
Two people start from the same app and end up with two different apps, each shaped by how they work.
It is made of parts
Small plugins you can add, swap, remove, version, share and reuse, so nothing is rebuilt from zero.
And it is yours: it runs on your machine, with your data, from files you can commit to your own git.
Why now: the SaaSpocalypse
When agents write code, any product that is not agentic can be copied, rebuilt cheaper, or open-sourced.
Features are no longer a moat
A competitor's agent rebuilds your feature list in a weekend.
Fixed software ages instantly
Every user wants it slightly different; a fixed product serves the average user, and no one exactly.
What stays valuable
Software that keeps evolving with each user, with an agent inside that knows the app and grows it.
blend.yamlwhich plugins, how they compose
blend.lock.jsonexact versions, sources, checksums
Cordis: the plugin kernel under DeepSeek Harness and ACRYL
Cordis began as the plugin kernel of Koishi, a cross-platform chatbot framework (Discord, Telegram, Matrix and more) with more than 4,000 community plugins. It was extracted in 2022 as a meta-framework that knows nothing about LLMs, agents or tools. DeepSeek Harness forked it as @deepseek-ai/cordis and built the whole agent as Cordis plugins: model adapters, tools, sessions, sandboxes, storage and the interface. The design is described in the paper A Programming Paradigm for Spatiotemporal Composability (Peking University and DeepSeek-AI).
Why it exists: the session outlives its parts
A group chat or a coding session runs for days while its capabilities arrive, leave and get replaced. Cordis gives two guarantees so that never breaks the session.
Temporal composability
When a component leaves, everything it did to the shared environment is reverted: routes, tools, timers, subscriptions. No residue, and unrelated work survives.
Spatial composability
Components declare what they need. A consumer activates only when its requirements exist, keeps a stable resolution while running, and stops before its provider is withdrawn.
component = requirements + provisions + effects with undo
How it works
A plugin definition, mounted with ctx.plugin(), becomes a Fiber; the Fiber owns its Context, its effects and its child Fibers.
| Part | What it is |
|---|---|
Context | The scoped environment a plugin receives; services, events and effects live on it. |
Service | A named capability such as ctx.tools or ctx.llm, replaceable by another provider. |
inject | A live dependency contract: the plugin stays PENDING until every named service exists; a provider change reactivates it. |
| Effects | Every registration is owned and has an inverse; unloading runs the inverses in reverse order. |
| Fiber | One mounted plugin instance: PENDING, LOADING, ACTIVE, FAILED, UNLOADING, DISPOSED. |
| Loader | Rows in cordis.patch.yml become the live plugin tree; change a row and the tree updates. |
Context: each plugin sees the world through its own ctx; isolate gives two groups their own provider of the same service name.
Fiber lifecycle. PENDING is not an error: the plugin is mounted and waiting for what it injects.
Services and inject: consumers depend on a name; a replaced provider reactivates them.
Events: emit, parallel, serial, bail and waterfall.
Waterfall: each listener wraps the next; next() continues, returning without it answers or vetoes.
Effects: registered 1, 2, 3; reverted 3, 2, 1 when the plugin unloads.
Loader: rows of cordis.patch.yml become the live tree of Fibers.
// a Cordis plugin, simplified: needs the tools service, adds one tool
export const name = 'word-count'
export const inject = ['tools']
export function apply(ctx) {
ctx.tools.register(defineTool({
name: 'word_count',
description: 'Count words in a text',
parameters: { text: { type: 'string' } },
async execute({ text }) { return text.split(/\s+/).filter(Boolean).length },
}))
// unloading the plugin unregisters the tool: no cleanup code
}What Cordis does not do
Cordis composes a running process. It does not describe, version or share an app: a profile is a local list of bundles on one machine, nothing pins exact versions and checksums, and there is no registry of whole apps to start from. That gap is why the DeepSeek Harness community already has thousands of plugins that solve the same problems again and again.
ACRYL Blends: a protocol for composable software people can share and reuse
The stack, bottom to top.
ACRYL IDE, GTD, accounting, music, anything, each with an agent inside.
blend.yaml manifest, blend.lock.json, registries, plugin hub (pull, share, verify), save to git, acryl new --from, the acrylblends CLI.
The agent loop, tools, models and sessions, as Cordis services.
Context, services, inject, revertible effects, fibers, Loader.
An app in one file
kind is a Blueprint to start from, or a Blend grown from one. extends inherits another app's rows so you override only what differs. rows are Cordis plugins and their config, the same rows the Loader runs. @webboxes/blends-core validates it, and the lock pins every plugin by version and checksum.
# registry/blends/acryl.music/blend.yaml (real)
apiVersion: blends.acryl.dev/v1alpha1
kind: Blueprint
metadata:
id: acryl.music
name: Music
version: 0.1.0
category: creative
license: MIT
visibility: public
spec:
runtime: cordis
extends: acryl.blank
rows:
- id: brand
name: acryl-brand
config: { name: Music, tagline: Say the beat, hear the beat. }
- id: acryl-music
name: acryl-musicWhy we built it: write a piece once, everyone can reuse it
Compose
An app is rows of Cordis plugins. Add, override or remove one without forking anything.
Lock
The lock pins every plugin: a local folder by content hash, npm by integrity, a pulled plugin by source and sha512.
Share
Push a plugin or a whole app to git or a registry, private or public. Others pull it by name, verified.
Reuse and grow
acryl new --from starts from anyone's app; the agent inside adds plugins; a snapshot records it all again.
ACRYL and the open framework run the same packages: @webboxes/blends-core, @webboxes/plugin-hub and @webboxes/app-persistence on npm, MIT.
How it all fits together
Above Cordis everything is plugins in rows. An app, the IDE included, is a choice of rows and their config: a Blend.
The whole map, from the Cordis kernel to the surfaces.
ACRYL IDE is a Blend
The IDE is the Blank core plus IDE plugins plus your own; /blend snapshot shares it like any app.
Three apps, one shape
GTD, Accounting and Music each extend acryl.blank with a brand row and one domain plugin.
One worktree per idea, any coding agent in it
Projects and worktrees
One tree for projects, git worktrees and plain folders. A new branch gets its own worktree and its own chat.
Every agent as a tab
Claude Code, Codex, Grok, GitHub Copilot, OpenCode, Pi and ACRYL's own agent, next to terminal, browser, editor, diff, board and doc tabs.
Review loop
Comment on a line, send it to the agent, review changes and commit in the right panel.
Shared brief
A context document every agent in the workspace reads, whichever tool it is.
Ask for what your workflow lacks; it becomes a plugin, live
The agent reads ACRYL's plugin documentation, writes the plugin, verifies and installs it, then clicks its own button to test it. In the rehearsal it noticed the button's label changed every second, an accessibility flaw, and fixed it while the timer kept running.
This time the plugin is a tool for the agent itself, available in every later conversation.
How ACRYL builds a plugin while it runs.
Name, version, what the plugin needs and provides.
Host side: services and agent tools.
UI side: fills a slot such as the session header.
Where the plugin sits in the app's composition.
Same framework, very different apps
Each app is a Blueprint in the public registry. Its domain is also a set of agent tools, so the agent operates the app in plain language. The app's own window is its UI, with the agent beside it, and it changes while you watch.
acryl.gtd · Getting Things Done
acryl new my-planner --from acryl.gtdacryl.accounting · invoices, expenses, VAT
acryl new my-books --from acryl.accountingSix agent tools over the app's data. Asking for a CSV export makes the agent write a new plugin with its tests in about two minutes.
acryl.music · a step sequencer
acryl new my-beats --from acryl.musicReal ACRYL Blend apps, running
Each made with acryl new --from from the public registry and run isolated with the real model on 2026-10-19.
Snapshot an app, clone it, it restores itself
The life of a Blend.
/plugin pull github:inboxxobni/acryl-quick-notes@0.3.0/blend snapshotacryl new planner-copy --from ./my-planner{
"formatVersion": 3,
"origin": { "id": "app.my-planner", "kind": "Blend" },
"lineage": { "blueprint": "acryl.gtd", "blueprintVersion": "0.1.0" },
"parameters": {},
"modules": [
{ "name": "acryl-quick-notes", "origin": "pulled",
"version": "0.3.0",
"spec": "github:inboxxobni/acryl-quick-notes@0.3.0",
"digest": "sha512-m9bN..." }
]
}The lock records where every plugin came from: a folder inside the app (by content checksum), npm, or a plugin pulled from GitHub (by source and sha512). The same lock format is written by ACRYL and by the acrylblends framework.
One registry for Blends, one for plugins, read live
Blends reading acrylblends.github.io
Cordis plugins reading cordisplugins.github.io
Both are static indexes on GitHub Pages. acryl.dev/blends and acryl.dev/packages mirror them.
A new agentic app in about three seconds
npx acrylblends@0.2.0 init my-agent --agent --yescd my-agent && npm install && npm startcurl -X POST $URL/ask -H 'content-type: application/json' -d '{"question":"create route hello /hello Hello"}'curl $URL/helloThe agent adds the route as a plugin while the server runs. Node 22.19 or newer; MIT; on npm and GitHub.
95 features built today, in 13 areas
| # | Feature | Where | Status |
|---|
macOS, Windows, Linux · Desktop, Web, terminal
Desktop
Installers for macOS (Apple silicon and Intel), Windows 10 and 11, Ubuntu and Debian (amd64, arm64).
Web
The same app in your browser, served from your machine.
Terminal
A terminal UI and CLI: npm install -g acryl
curl -fsSL https://acryl.dev/install | bashWhat we are building now
- nextThe Blends page: save, share, and pull another Blend with a diff of every plugin change.
- nextSoftware factory: see every agent session on the machine and hand off in one click. Moving work between Claude Code, Codex and Pi through the shared workspace brief works today.
- nextWorkflows that travel with a Blend: one main agent, worker agents in isolated worktrees, spec-driven.
- nextSettings and workspaces inside a Blend.