Konde Design Framework

i18n is voor je vertalingen.
KDF is voor je design.
Beide leven in JSON.

Een JSON-gebaseerde design-coördinatielaag voor server-side web apps en agent-gestuurde UI. Repeterende keuzes — layout, spacing, typografie en component-styling — leven in één enkele source of truth die je agents moeiteloos uitlezen in plaats van eindeloos te raden in verspreide files, pagina's en eerdere sessies.

Kijk hoe het werkt
kdf / homepage.json → gerenderd
kdf/homepage.json
{
  "$layout": ["hero", "footer"],
  "hero": {
    "wrapper": "mx-auto max-w-6xl px-6 py-20",
    "title":   "@typography.h1",
    "cta-primary": "@button.cta"
  }
}
data-kdf="hero.title"
Bouw en ship met AI.
data-kdf="hero.body"

Eén strakke source of truth houdt elke pagina, component en agent-sessie netjes in sync.

data-kdf="hero.cta-primary"
Aan de slag →

JSON definieert · code rendert · data-kdf mapt het terug

Licentie
MIT
Runtime
Node Filesystem
Dependencies
Zero Runtime
Getest met
Next · Astro · Hono
01 — Het probleem

Design sluipt ongemerkt
je componenten in.

Wanneer class names alleen in je .tsx-files staan, divergeert elke pagina langzaam. Voor één menselijke developer is dat nog wel te fixen — maar het breekt keihard zodra AI-agents aan je UI gaan knutselen.

zonder kdf · versnipperd over files
<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

Dezelfde button krijgt stiekem vijf varianten. Spacing verspringt per pagina. Elke nieuwe agent-sessie moet de regels weer helemaal opnieuw uitvinden.

HET RESULTAAT
  • Agents improviseren er lustig op los met kleuren, spacing, typografie en layout.
  • Users moeten telkens via de chat de boel weer lopen rechttrekken.
  • Aanpassingen betekent eindeloos grep-en door je component-files.
  • Bij elke sessie verlies je iets van je design-intentie.

→ eindeloos "groter" · "meer blauw" · "naar links" itereren

02 — De oplossing

Maak design expliciet.

KDF doet voor design exact wat i18n doet voor tekst: repeterende keuzes weghalen uit je componenten en centraal beheren in JSON. De gerenderde UI gebruikt onder water nog steeds pure CSS — het enige wat verandert is het ownership.

1 — definieer het in json
{
  "hero": {
    "title": "text-5xl font-semibold tracking-tight"
  }
}
2 — render het in code
const d = getDesign("homepage");

<h1 data-kdf="hero.title" className={d("hero.title")}>
JSON definieert
Één file bepaalt de visuele richting. Users passen het direct aan als ze superstrakke controle willen.
Code rendert
Je componenten lezen de tokens en spugen het goedgekeurde design uit via normale CSS — geen black-box magic.
Agents bouwen
Agents genereren UI direct uit de JSON in plaats van wat op gevoel te proberen. Geen verzonnen spacing, kleuren, fonts of sectie-volgordes meer.
Users fixen JSON
Pas de source gewoon één keer aan in plaats van sessie na sessie via chat dezelfde visuele fix door te geven.
03 — Geen component library

Een library roept 'wat'.
KDF bepaalt 'welke'.

Een design library geeft je een Button. KDF vertelt je strak dat dit de homepage.hero.cta-primary is, toevallig gerenderd als een Button, met díé token-styling. Het slaat de broodnodige brug die libraries altijd missen: van element direct naar de design-keuze.

 Design libraryKDF
Wat het zegt"Dit is een Button.""Dit is hero.cta-primary op de homepage."
MappingEen vrijblijvend component, vol handmatige overrides.Eén harde mapping van element naar een design-key.
TraceerbaarheidNul directe link tussen je DOM en de beslissing.data-kdf wijst vanuit elke DOM-node keihard terug naar z'n JSON-pad.
Zit boven shadcn · Bootstrap · Chakra · Tailwind · platte CSS · je eigen huis-tuin-en-keuken systeem — KDF vervangt geen van allen.
04 — Het vocabulaire

Zes symbolen.
Eén grammatica.

KDF snapt class names, shared references, sectie-volgorde en CSS custom properties. Het bemoeit zich nóóit met business logic, event handlers, data fetching, rechten of a11y-gedrag.

data-kdf
De map

Elk element met een token tagt het pad mee in de DOM. Nodes wijzen zo direct terug naar de JSON — perfect voor scanners, test-suites en agent reviews.

data-kdf="hero.title"
d(path)
De accessor

Vertaalt een pad strak naar z'n className-string. d.css() spuugt het CSS custom properties object voor je uit.

className={d("hero.title")}
@
Shared reference

Prik naar een herbruikbare token in shared/. Refs kun je naadloos chainen of overriden met extra classes.

"@button.cta" shadow-xl
$layout
Volgorde & zichtbaarheid

Gewoon een array van sectie-keys. Wat in de array zit, wordt netjes op volgorde gerenderd; de rest klapt je app slim dicht.

["hero", "features", "footer"]
$
Component identiteit

Handige metadata voor agents en devtools — hint meteen welke component (en variant of size) deze token afhandelt.

"$": "Button"
css
Aangepaste eigenschappen

Losse waarden die je niet als class kwijt wil, gewoon direct als inline style variables ingeschoten via d.css().

{ "--kdf-accent": "#4F46E5" }
05 — Architectuur

Shared defaults.
Page overrides.

Design tokens leven slim op twee plekken: solide defaults in shared/, en per pagina kleine overrides voor wat maatwerk. Twee losse CSS-files regelen perfect de first paint én je snelle ontsnappingsroutes.

project structuur
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
Cascade op meerdere niveaus

Een call naar @button.cta checkt eerst de page shared/, dan root shared/ en dan de pure page tokens. Templates overriden dus puur wat lokaal afwijkt.

Standaard lichtgewicht

Design-resolutie gebeurt op de server; de browser hapt alleen statische class-strings weg. Critical CSS belandt veilig in de first paint, de bulk laadt pas daarna — dus nul onnodige lagere framerates.

TWEE EIGEN CSS-BESTANDEN · TWEE LAADMOMENTEN
konde-server.css
critical · first paint

Geïmporteerd in de root zodat core variables en anti-FOUC hacks direct in de first paint landen — nog vóórdat er überhaupt iets kan knipperen.

/* konde-server.css */
:root { --kdf-primary: #1F8F47; }
[data-kdf="hero.slider"] { display: none; }
konde.css
non-critical · ná app css

Laadt ontspannen na je framework CSS in; ideaal voor snelle tweaks, tests en escape hatches. Blokkeert je paint niet.

/* konde.css */
[data-kdf="hero.title"] { letter-spacing: -0.02em; }
[data-kdf="hero.wrapper"] { gap: 3rem; }

→ KDF genereert beide files eenmalig en komt er dan nooit meer aan. De paden staan in je env, je importeert ze zelf — nul enge magie of build injecties.

06 — Multi-template

Wissel van design
zoals je van taal wisselt.

Net zoals i18n tussen talen swapt, schiet KDF tussen complete design templates. Zelfde app, zelfde componenten, zelfde code — gooi gewoon KDF_DIR naar een andere directory en heel je look-and-feel draait om.

designs/ — twee templates, één app
designs/
  lander/
    shared/
    homepage.json
  newlander/
    shared/
    homepage.json
// next.config.ts
withKDF({ dir: "./designs/lander" })(nextConfig);
$layout Herschik secties on the fly zonder überhaupt een component te hoeven openen.
@button Pas via één master token elke CTA over de hele app heen aan.
KDF_DIR Swap razendsnel de hele designlaag om, perfect als je whitelabelt.
07 — Runtime API

Resolve op de server.
Geef strings door.

De KDF-core slikt JSON zo van disk en draait dus loeisnel server-side: in Next.js Server Components, Astro of Hono. Pak de classes daar en geef schone, platte strings door aan de client.

server component
import { getDesign, cn } from "@kondeio/kdf";

const d = getDesign("homepage");

<button data-kdf="hero.cta" className={cn(d("hero.cta"), isActive)}>Start</button>
d("hero.title")

→ uitgepakte className string

d.css("hero.title")

→ kant-en-klaar CSS custom-properties object

cn · cx · dedupeClasses

Merge slim class-strings, strip falsy shit en drop dubbelingen — out-of-the-box.

cache: auto · always · none

Cacht stevig in prod; in dev ververst 'ie snel op mtime & filesize changes.

08 — Compatibel by design

Het draait puur bovenop
jouw bestaande stack.

STYLING — SLAAT CLASS NAMES OP, GEEN CSS

TailwindshadcnBootstrapChakraCSS ModulesPlain CSSYour own system

KDF bemoeit zich niet met je CSS engine. De tokens bevatten simpelweg class-strings van wat jij gebruikt. Werkt jouw framework met file-scanners (zoals Tailwind)? Point 'm dan even naar de JSON: @source "../kdf/**/*.json".

RUNTIME — SERVER-SIDE JAVASCRIPT

Next.js getest · plugin
Astro getest
Hono getest
Aan de slag

Installeer eenmalig.
Init zet alles voor je klaar.

Bij de eerste run zet de setup meteen de hele kdf/ mappenstructuur op. Heb je al wat staan? Dan blijft 'ie daar mooi van af.

$npm install @kondeio/kdf
$pnpm add @kondeio/kdf
$bun add @kondeio/kdf
$npm exec -- kdf init # of bouw het gewoon met de hand op
next.config.ts
import withKDF from "@kondeio/kdf/plugin";

export default withKDF({ dir: "./designs" })(nextConfig);