i18n håndterer oversettelsene dine.
KDF håndterer designet ditt.
Begge bor i JSON.
Et JSON-basert koordineringslag for design for server-side web-apper og agent-assistert UI. Gjentakende beslutninger — layout, spacing, typografi, styling av komponenter — samles i én source of truth som agentene dine kan lese direkte, så de slipper å gjenoppdage alt på tvers av filer, sider og gamle chattehistorikker.
{ "$layout": ["hero", "footer"], "hero": { "wrapper": "mx-auto max-w-6xl px-6 py-20", "title": "@typography.h1", "cta-primary": "@button.cta" } }
Én source of truth holder hver side, komponent og agent-økt konsekvent.
JSON definerer · koden rendrer · data-kdf mapper tilbake
Designet sklir ut i
komponentene dine.
Når klassenavn bare eksisterer i .tsx-filer, begynner sidene sakte å sprike. Det funker kanskje for én menneskelig utvikler — men det blir fort skjørt når AI-agenter begynner å mekke på UI-et ditt.
<section className="mx-auto max-w-6xl px-6 py-20"> <h1 className="text-5xl font-semibold tracking-tight"> // …and again, slightly different, on the next page
Den samme knappen får plutselig fem uoffisielle varianter. Spacingen endrer seg fra side til side. For hver ny agent-økt må de lære reglene på nytt helt fra bunnen.
- — Agenter improviserer farger, spacing, typografi og layout.
- — Brukere må sitte og korrigere resultatet via chat, hver eneste gang.
- — Endringer betyr at du må grave gjennom komponentfiler.
- — Gjentatte økter mister rett og slett designintensjonen.
→ uendelig "større" · "mer blått" · "flytt til venstre" iterering
Gjør designet eksplisitt.
KDF gjør for design hva i18n gjør for tekst: det flytter gjentakende beslutninger ut av komponentfilene og inn i JSON. Det ferdige UI-et bruker fremdeles vanlig CSS — det som endres er hvem som eier reglene.
{ "hero": { "title": "text-5xl font-semibold tracking-tight" } }
const d = getDesign("homepage"); <h1 data-kdf="hero.title" className={d("hero.title")}>
Et bibliotek sier hva.
KDF sier hvilken.
Et designbibliotek gir deg en knapp (Button). KDF forteller deg at dette er homepage.hero.cta-primary, rendret som en knapp, og stylet med dette tokenet. Det fikser den ene koblingen bibliotekene utelater — fra element til designbeslutning.
Seks symboler.
Én grammatikk.
KDF lagrer klassenavn, delte referanser, seksjonsrekkefølge og CSS custom properties. Det lagrer aldri forretningslogikk, eventhandlere, datafetching, permissions eller tilgjengelighetsatferd.
Hvert element som bruker et token, bærer med seg en matchende sti. DOM-noder kan spores rett tilbake til JSON — perfekt for skannere, tester og code reviews av agenter.
Oversetter en sti til en className-streng. d.css() returnerer CSS custom properties som et objekt.
Peker på et gjenbrukbart token i shared/. Referanser kan kjedes sammen og utvides med ekstra klasser.
En array med seksjonsnøkler. Listede seksjoner rendres i riktig rekkefølge; de som mangler skjules av appen.
Metadata for agenter og verktøy — som forteller hvilken komponent som rendrer dette tokenet, pluss hint om variant og størrelse.
Verdier som ikke kan uttrykkes som gjenbrukbare klasser, lagt til som inline style-variabler via d.css().
Delte standardverdier.
Side-overstyringer.
Design tokens bor på to steder: som gjenbrukbare standardverdier i shared/, og per side som bare overstyrer det som trengs. To CSS-filer, som du kontrollerer fullt ut, dekker 'first paint' og unntakstilfeller.
kdf/ shared/ button.json ← reusable defaults card.json color.json typography.json homepage.json ← page composition konde-server.css ← critical, first paint konde.css ← non-critical tweaks
En referanse som @button.cta hentes fra sidens shared/, deretter fra parent shared/, og så fra selve sidens tokens. Maler overstyrer kun de delene de trenger og arver resten.
Designet resolveres på serveren; nettleseren får bare ferdige klassestrenger. Kritisk CSS leveres i first paint, resten lastes inn etterpå — ingen rendringsstraff dyttes over på svake klienter.
Importeres av appen slik at designvariabler og no-FOUC overstyringer dukker opp allerede i first paint — lenge før noe rekker å blinke.
/* konde-server.css */ :root { --kdf-primary: #1F8F47; } [data-kdf="hero.slider"] { display: none; }
Lastes inn etter rammeverket og appens CSS for tweaks, eksperimenter og escape hatches — finjusteringer som aldri bør blokkere renderingen.
/* konde.css */ [data-kdf="hero.title"] { letter-spacing: -0.02em; } [data-kdf="hero.wrapper"] { gap: 3rem; }
→ KDF oppretter begge filene én gang og overskriver dem aldri. Pluginen gjør stiene tilgjengelige via env - appen din står for selve importen; ingenting magisk injiseres for deg.
Bytt design
like lett som å bytte språk.
Akkurat som i18n lar deg bytte språk, lar KDF deg bytte designmaler. Samme app, samme komponenter, samme kode — bare pek KDF_DIR mot en annen designmappe for å endre hele looken.
designs/ lander/ shared/ homepage.json newlander/ shared/ homepage.json
// next.config.ts withKDF({ dir: "./designs/lander" })(nextConfig);
Resolv på serveren.
Send strenger ned.
KDF core leser JSON rett fra disken, så det kjører nydelig server-side: Next.js Server Components, Astro, Hono-handlere. Resolv klassene der, og send deretter rene strenger ned til klientkomponentene.
import { getDesign, cn } from "@kondeio/kdf"; const d = getDesign("homepage"); <button data-kdf="hero.cta" className={cn(d("hero.cta"), isActive)}>Start</button>
→ ferdig resolved className-streng
→ CSS custom properties-objekt
Slå sammen betingede klasser, dropp falsy verdier og dedupliser — strippet for semantikk ut av boksen.
Produksjon cacher aggressivt; i dev revalideres det automatisk på mtime og størrelse.
Det ligger på toppen
av stacken din.
STYLING — LAGRER KLASSENAVN, IKKE CSS
KDF er ingen CSS-motor. Tokens inneholder nøyaktig de klassestrengene stylingsystemet ditt forstår. Skanner rammeverket ditt kildefiler, ber du det bare skanne JSON-filene også: @source "../kdf/**/*.json".
RUNTIME — SERVER-SIDE JAVASCRIPT
Installer én gang.
Init setter opp resten.
Installasjonen scuffolder også en enkel kdf/-mappe for å få deg i gang, hvis du ikke har en fra før. Eksisterende filer blir selvsagt aldri overskrevet.
import withKDF from "@kondeio/kdf/plugin"; export default withKDF({ dir: "./designs" })(nextConfig);