ICVOSS DJANGO PACKAGE REGISTRY

The package index django-brickwork Adopting brickwork into an existing app (the strangle pattern)

Adopting brickwork into an existing app (the strangle pattern)

Documentation

INTEGRATION.md covers a greenfield install. This guide covers the harder, more common case: strangling an existing UI kit (a hand-built shell plus a c-/x- component library) onto brickwork cluster by cluster, keeping the old kit alive until the last screen moves. It is a checklist distilled from a real console cutover, not a theory; the structure below is reusable for the next brownfield adopter.

Principle: strangle, do not big-bang

brickwork is pre-1.0 and releasing rapidly. A whole-app commit before 1.0 carries real churn risk: every rapid minor could touch a contract you depend on across every screen at once. Migrate incrementally so that at any moment most of the app still runs on the proven old kit and only the migrated cluster carries brickwork risk. Keep rollback trivial at every step.

The sequence

1. Pilot one screen cluster first

Pick one coherent cluster (a settings area, one resource's list+detail+form) and move only that. The pilot's job is to prove the four load-bearing seams end to end on real screens:

Wire each per INTEGRATION.md. If all four hold on the pilot cluster, the rest is repetition; if one fights you, you have found the real adoption cost before committing the whole app.

2. Migrate cluster by cluster, each its own PR

One cluster per PR keeps every step reviewable and independently revertable. Do not let a half-migrated cluster straddle a release. The old kit and the brickwork shell coexist for the duration: two base templates live side by side, screens extend whichever kit they currently belong to, and you move screens across one cluster at a time. This is expected and fine; plan for months of coexistence, not a weekend.

3. Draw the boundary explicitly

Decide, up front and in writing, what migrates and what does not:

Writing the boundary down stops scope creep mid-migration, where "while we are in here" quietly pulls non-goals into the cutover.

4. Gate the final "delete the old kit" step on a stability signal

The last step, removing the old kit entirely, is the one with no rollback. Gate it on a stability signal rather than doing it the moment the last screen moves: a brickwork release you have pinned and validated across the migrated app, ideally 1.0 or a release-candidate you trust. Until then, keeping the old kit's code in the tree (even with no screens using it) costs nothing and preserves the escape hatch.

Two wrinkles a real brownfield cutover hits (brickwork#49)

Multi-host projects (the shell branches per host)

A project served on several hosts (django-hosts: a merchant host, an agency host, an account host, each branching the shell) must decide per host whether that host's screens are in the migration. The clean pattern: each host resolves its own base template, and you migrate host by host as well as cluster by cluster. A host still on the old shell and a host on the brickwork shell coexist with no shared state beyond your own context; the per-request brand / theme resolver (BRICKWORK_THEME_RESOLVER, see INTEGRATION.md section 3) is where a multi-host app branches brand per host. Do not try to run one shared base template across hosts mid-migration; let each host cross the line on its own schedule.

Legacy-shell / brickwork-shell asset coexistence

While both shells are live, both asset pipelines are live. The classic pairing is django-vite hashed bundles (the legacy kit) alongside brickwork's plain {% static %} artefacts. These coexist cleanly: brickwork never enters your bundler, and your bundler never needs to touch brickwork's static. Points to hold:

The htmx floor, if you are brownfield on htmx 1.9 (brickwork#48)

brickwork's interaction contracts are built and CI-gated on htmx >= 2.0 only (BR-BW-HTMX-010); htmx 1.9 is out of contract. If your app is on htmx 1.9, treat the htmx 1 -> 2 upgrade as a prerequisite workstream that lands before the brickwork cutover, not something to reconcile screen by screen mid-migration. htmx 2 changed default response handling in ways the 422 swap loop relies on; running the cutover on 1.9 means wiring htmx:beforeSwap by hand on a path brickwork does not test. Sequence the htmx upgrade first, then strangle onto brickwork on a supported floor.

What a worked instance looks like

The console cutover this guide is distilled from ran as an ADR plus a staged plan: one ADR recording the decision and boundary, then a plan enumerating the clusters in migration order with the "delete the old kit" step gated last. That shape (decision + boundary in an ADR, ordered clusters in a plan) is worth copying: it makes the migration auditable and the boundary durable against scope creep.