Skip to content

App-Compose

Scale your app. Actually control it.

Scaling a frontend app is easy. Keeping it under control is not. Features develop high coupling, startup order becomes unpredictable, and things break in unexpected places. Every team works around these problems differently.

Sound familiar?

High coupling

Change one feature — and you’re touching three others.

Reuse means copy-paste

You need the same feature, just slightly different — so you duplicate it.

Silent breaks

You changed something small and the app broke somewhere else — no clear error.

What's running here?

You open a page and have no idea which features are active on it.

No control over startup order

Startup order is a guess — non-critical stuff runs first, the important parts wait. You find out it’s wrong at runtime.

Performance black box

No idea which initialization step is slow — or whether your last change made it worse.

Meet App-Compose

App-Compose is a TypeScript library that structures your frontend app around isolated tasks, explicit context, and predictable startup — by design.

These examples are interactive — open on desktop to run and edit them live.
import {
bind, compose, createTag, createTask
} from "@grlt-hub/app-compose"
const user = createTask({
name: "user",
run: { fn: () => ({ id: 14 }) },
})
const userId = createTag<number>({ name: "userId" })
const analytics = createTask({
name: "analytics",
run: {
// 👇 isolated: depends on a tag, not on "user"
context: userId.value,
fn: (userId) => console.log(`Analytics ready. User ID: ${userId}`),
},
})
compose()
.stage({ steps: [user] })
.stage({ steps: [bind(userId, user.result.id)] })
.stage({ steps: [analytics] })
.run()