Every control,
under control.
Permissions, feature flags, user analytics, audit logsand prototyping. Running inside your product. Anyone on your team can read it. An engineer installs it once.
Click a control — the panel answers for it. Placing a control that does not exist yet.
Orders
Click any control
2 of 3 controls are governed by something.
Counted for this screen. It moves as you walk the product.
Fulfillment link
- Address
- chrome.fulfillment-link
- Operation
- order.fulfill
You hold the fulfillment desk, so you may open it. Tomas Reyes and June Alcott do too.
Export CSV
- Address
- admin.orders.export
- Operation
- customer.export
Exporting customers is the store manager’s. You do not hold that seat.
Refund
- Address
- admin.orders.refund
Nothing governs this control — no access rule, no flag, no recorded use.
Anyone who reaches this screen can refund any order, and nothing will record that they did.
Restrict to
Written from here. No deploy.
Refund
- Address
- admin.orders.refund
- Operation
- order.refund
Now governed. Every refund from here on is recorded, refusals included.
Components
Juniper Lane StorybookPlacing against admin.orders.refund
Controls
Primary button
button
Quiet button
button
Text field
input
Note
label
Back office
Orders table
table
Status badge
badge
Quiet button
Juniper Lane Storybook · control
- Anchor
- admin.orders.refund
- Position
- Beside it
The address is the specification. A developer stamps it on a real control, and neither of you can have meant a different button.
Nothing is written into your app. The sketch lives in the proposal.
Partial refund
- Operation
- order.refund.partial new
Decided before it exists — so the day it ships it is already the desk’s, and nobody has to remember to come back.
Asking for 1 thing
Partial refund
beside admin.orders.refund
Why
June Alcott · Founder · no seat required to ask
Proposals
1Partial refund
Builtadmin.orders.refund.partial
- Proposed · June Alcott, Tuesday
- Built · derived from build 4e19a2, 3 minutes ago
- Live · waiting on somebody who may ratify
Nobody moved a card. Built means a build published a manifest carrying that address.
Open the panel on a screen you already shipped. It counts what governs each control in front of you — two of these three.
Ask a control who may press it. Exporting customers is the store manager’s, and the answer is for whoever is actually looking.
Refund answers with nothing at all. No rule, no flag, no record — anyone who reaches this screen can refund any order.
So restrict it from where you found it. The padlock lands on the button. No deploy, and every refund from here is recorded — refusals included.
Now the control that does not exist yet. The desk wants partial refunds, so pick the piece off your own shelf — your design system, not our widgets.
Put it where it goes. It anchors to an address — beside admin.orders.refund — rather than to a paragraph about which button you meant.
Say who may press it before anybody builds it. The rule is written against the act, so the control arrives governed instead of being governed later.
Hand a developer an address, not a ticket. One sentence about what is missing and for whom, and the request carries everything the ticket was going to say.
A build lands, and the request marks itself delivered. Built is a fact about what shipped — not a card somebody dragged. Nobody reopens anything.
Yours to poke at. Click any control and the panel answers for it — the story picks back up whenever you press play.
Two modes, one panel
Read what is there. Ask for what is not.
Same install, same addresses, same panel. The second mode only works because the first one gave every control a name.
Four features, one control
Everything you already buy separately,answered in one place.
Permissions, feature flags, usage and audit are four readings of the same act. The Overlay puts them on the control itself, rather than in four consoles that have never rendered your product.
It replaces the basics of a tool in each of these categories. Not the deep end of any one of them, and that is the trade: one answer per control, in the product, instead of four subscriptions and four tabs.
Who may press this?
Replaces the basics of Permit.io, Cerbos, or the roles table you wrote yourself.
Ask it standing on the button, and get an answer for whoever is actually looking. Change it here too — name the seats that may perform the act, or detach the rule entirely.
The subject is the act, not the button. Two controls that refund an order cannot disagree about who may refund one.
View as
Is this on, and for whom?
Replaces the basics of LaunchDarkly, Statsig, Unleash.
Flip a feature from inside the product, on the control it affects — no hunting for refund_v2_enabled in a list and hoping it still means this button.
A new flag arrives proposed and governs nothing until somebody with the authority puts it in force. Writing a rule and making it decide are separate grants.
Policies · 2 attached
Governs nothing until somebody ratifies it.
Is anyone actually using it?
Replaces the basics of Amplitude, Mixpanel, PostHog.
How often this control has been used and by how many people, on a window the panel states rather than assumes. A control nothing has happened to has no Used row at all, rather than a row of zeroes.
And it is read, never collected — no event taxonomy to maintain, and no handlers attached to buttons you own.
128
times
14
people
The window is stated, not assumed.
Who did it, and who was stopped?
Replaces the basics of WorkOS Audit Logs, or the events table nobody reads.
Everything that has happened to this control, newest first, with the refusals drawn as refusals. Not a separate export you reconcile later — the same reading, on the same button.
Somebody who could not say who they were tried to refund an order is the most interesting line a log can hold, so an unidentified attempt is recorded like any other rather than dropped for want of a name.
Activity
Four steps, one address
Ask for a control thatdoes not exist yet.
The panel that reads your controls can also place one. Pick a piece off your own shelf, put it where it goes, say who it is for — and hand a developer an address instead of a ticket.
Pick it off your own shelf.
The shelf is your design system — your Storybook, grouped the way your product is grouped. Nothing on it is ours, so what you place reads as your product rather than as a wireframe of somebody else’s.
A library is registered once. After that the person asking is choosing from the same pieces the person building would have reached for anyway — which is most of the argument a mockup usually has to win.
Controls
Primary button
button
Quiet button
button
Text field
input
Note
label
Back office
Orders table
table
Status badge
badge
Filter bar
toolbar
Empty state
panel
Put it where it goes.
Draw it in the running product, against a real control. It anchors to that control’s address — beside admin.orders.refund — instead of to a paragraph about which button you meant.
That address is the specification, and it is machine-checkable. A developer stamps it on a real control, and neither of you can turn out to have meant a different button.
Anchored to
beside admin.orders.refund
Say who may press it — first.
Name the act it will perform, the seats that may perform it, and whether it is on at all. The rule attaches to the act, which already exists as a concept even when the button does not.
So the control arrives governed rather than being governed later, and the release starts proposed — written down, deciding nothing, until somebody with the authority puts it in force.
Decided before it exists — so the day it ships it is already the desk’s, and nobody has to remember to come back and lock it.
Then stop tracking it.
A proposal is what is being asked for, where it goes, and one sentence about what is missing and for whom. Anyone may ask; nothing they ask for governs anything until it is built and put in force.
When that address turns up in a build, the proposal reports Built on its own — a fact about what shipped rather than a card somebody dragged. Somebody holding ratify makes it live.
Partial refund
beside admin.orders.refund
“Support is refunding whole orders when one item arrives damaged.”
- Proposed · June Alcott · Tuesday
- Built · derived from build 4e19a2 · 3 minutes ago
- Live · waiting on somebody who may ratify
Nobody moved a card. Built means a build published a manifest carrying that address.
It is not a tracker, and it does not want to be.
No sprints, estimates, assignees or roadmaps, and nothing that has no address — a proposal only holds things you can point at on a screen. What it does hold is a status nobody has to keep up to date.
Prototype mode is included from Team upward, along with registering your own component library.
Partners
Working with design partners across three domains
We are looking for design partners we can be genuinely useful to.
Installing it
One call. That is the whole install.
No provider to mount, no components to adopt, no concepts to learn first.
// vite.config.ts — the whole installation
import { dna } from "@dna/react/vite";
export default defineConfig({
plugins: [dna({ host: "app-billing", key: "pk_live_…" }), react()]
});That one call stamps every element with an address, writes the overlay’s script tag into your document, publishes the build manifest if your pipeline holds a key, and prints coverage at the end of the build.
// app/layout.tsx — the whole installation
import { DnaOverlay } from "@dna/react";
<body>
{children}
<DnaOverlay dnaKey={process.env.NEXT_PUBLIC_DNA_KEY ?? ""} />
</body># after the build, in CI
- run: npx dna publish app
env: { DNA_HOST: app-billing, DNA_API_KEY: "${{ secrets.DNA_KEY }}" }No next.config entry, no loader, no SWC plugin, and no opinion about Turbopack. Declared addresses are literal props, and React forwards them to the DOM unaided — so they arrive with no build integration at all. One answer covers the App Router and the Pages Router, Turbopack and webpack, because none of them is involved.
On anything else, npx dna publish reads your source directly — nothing about it is bundler-specific.
What that gets you
Addressable
Every control carries a stable address. You can point at a button and be understood — in a rule, in a ticket, in a conversation — instead of guessing which flag key somebody meant.
Bindable
An address reaches an operation — the act the control performs. Now the button has a subject, and two buttons that do the same thing are known to do the same thing.
Governable
Rules attach to the act. Permissions — who may perform it. Release — whether it is on at all. Usage — how often, by how many people. Audit — everything that has happened, refusals included, and who was refused.
@dna/react is in private beta. It is not on npm yet. Early-access customers get the package and half an hour of setup with us.
Seven things it will never do
It arrives in a product nobody asked it about. Every one of these is enforced, not promised.
Your markup is unchanged
Rendered output is byte-identical apart from data-dna attributes, and removing the install restores every file byte-for-byte.
It never listens to your buttons
Usage is read from occurrences the platform already writes — never collected by attaching handlers to controls you own.
It cannot fail your build
Unreachable, slow, refusing, or answering a proxy’s HTML — publishing resolves and reports. Your key is never printed, including in transport errors.
The key in your markup is powerless
It identifies the application and nothing more. Which environment this is, whether the overlay may run here, and what the viewer may do are all the server’s answer.
Nothing publishes without a key
A developer’s local build, and a pull request from a fork where the secret is unavailable, send no request at all rather than one that would be refused.
Refusals are enforced twice
The panel hides what you may not do; the server checks again and names which gate stopped a request forged past it. A rule that only exists on the client is not a rule.
Removal is one call
Take the install out and the page is exactly what it was — container, watchers, outlines and both sessionStorage entries, gone.
The same install is what makes the other mode possible: the panel can place a control that does not exist yet, drawn from your own design system and handed to a developer as an address rather than a ticket. See Prototype mode →
Included in every paid plan.
The Overlay is a surface on your model, not a product beside it, so it is never sold separately. Reading the panel is free and unlimited on all plans; we charge for authority, not for looking.
FAQ
Do I have to replace my feature flags?
No. Start with the controls that have no governance at all, which is most of them, and leave what works alone. Teams that later consolidate do it because they wanted one answer per control, not because we required it.
What does it do to my bundle?
Almost nothing. The overlay is fetched separately rather than bundled, and can be served only where you want it. What lands in your own output is attributes, and your markup is byte-identical apart from those.
Can anyone who loads my page see our rules?
No. The publishable key carries no capabilities at all. Until somebody identifies, the panel can inspect and nothing more, and names of people are only ever returned to a caller who may govern. A roster served to anyone who views source would be a staff directory.
Does it work if my app is not React?
Vite and Next.js have a one-step install today. Beyond those, npx dna publish reads your source directly. Nothing about it is bundler-specific, so you get addresses and governance without a framework integration at all. Tell us your stack on the form; which one we deepen next is decided by who is asking.
What happens when I turn it off?
The page is exactly what it was. stop() removes the container, the watchers, the outlines and both sessionStorage entries, and taking the install out restores every file byte-for-byte.
Is this ready for production?
It runs against a live stack and every screenshot on this page was taken walking a real script. It is early access rather than generally available: the package is private, we set you up by hand, and we are looking for design partners we can be genuinely useful to.
See it on your own controls.
Install it, open the panel, and read what governs each button in your product. The answer is nothing more often than most teams expect, and that is usually a more interesting conversation than the install was.
Got it, thank you.
We read every one of these by hand. Expect a reply from a person, usually within a day.