Skip to content

Two packages, one line

The split between rendering and computing is the whole product decision, and it was made to protect the user's choices, not ours.

View as Markdown

Most component libraries make two decisions for you. They decide how your site looks, by shipping a stylesheet. And they decide how your site is built, by rendering your content.

Both feel like conveniences on day one. Both are expensive to undo in year two, when you want something the library did not anticipate and the only paths open are to fight it, fork it, or leave.

Where the line falls

@teasim/astro renders markup and carries behaviour with it. It ships no CSS.

@teasim/astra computes navigation, validates content and serves the machine-readable routes. It renders nothing.

Neither knows what the other looks like. A project can take either half alone — the elements without the content layer, or the content layer under a completely different set of components.

What the split costs us

Two packages is more surface than one. Two changelogs, two dependency graphs, and a boundary that has to be defended every time something would be slightly easier if the content layer knew about the components.

There is a rule for that: the packages take external dependencies on different terms — the element package takes none at all — and where a feature needs one, the need decides which package it belongs to, not convenience.

What it buys

A stylesheet you own. An accordion that is a details element, so it works before the JavaScript arrives and keeps working if it never does. And an exit: because nothing here is a wrapper around a widget, replacing one family with your own is a local change, not a migration.

The measure of the split is not how much it helps on day one. It is how little it costs on the day you want to leave.

A postscript

Written when there were two. The rendering half has since been cut once more, along the same kind of line: @teasim/astro is the elements, and @teasim/aster is the page-level chrome composed from them — so a project that wants a Button never installs a documentation shell. The argument is unchanged; it simply applied a second time.