DaisyUI v5

Less markup. More shipping.

DaisyUI is the fastest way to build UI in a Go/Templ project. kraft-ui wraps every component in typed Go so you get IDE autocomplete, compile-time safety, and half the code.

A registration form. Three fields.

Something every Go dev has written. Here is what it looks like with and without kraft-ui.

Without kraft-ui
47 lines
html
<form method="POST" action="/register"
  class="space-y-4 w-full max-w-sm">

  <fieldset class="fieldset">
    <legend class="fieldset-legend">Full Name</legend>
    <input
      type="text"
      name="name"
      placeholder="Jane Smith"
      class="input input-bordered w-full"
    />
    if errors["name"] != "" {
      <p class="label text-error text-sm">
        { errors["name"] }
      </p>
    }
  </fieldset>

  <fieldset class="fieldset">
    <legend class="fieldset-legend">Email</legend>
    <input
      type="email"
      name="email"
      placeholder="you@example.com"
      class="input input-bordered w-full"
    />
    if errors["email"] != "" {
      <p class="label text-error text-sm">
        { errors["email"] }
      </p>
    }
  </fieldset>

  <fieldset class="fieldset">
    <legend class="fieldset-legend">Password</legend>
    <input
      type="password"
      name="password"
      placeholder="Min. 8 characters"
      class="input input-bordered w-full"
    />
    if errors["password"] != "" {
      <p class="label text-error text-sm">
        { errors["password"] }
      </p>
    }
  </fieldset>

  <button type="submit"
    class="btn btn-primary w-full mt-2">
    Create account
  </button>

</form>
With kraft-ui
24 lines
go
<form method="POST" action="/register"
  class="space-y-4 w-full max-w-sm">

  @daisyui.Input(daisyui.InputProps{
    Label:       "Full Name",
    Placeholder: "Jane Smith",
    Error:       errors["name"],
  })

  @daisyui.Input(daisyui.InputProps{
    Type:        "email",
    Label:       "Email",
    Placeholder: "you@example.com",
    Error:       errors["email"],
  })

  @daisyui.Input(daisyui.InputProps{
    Type:        "password",
    Label:       "Password",
    Placeholder: "Min. 8 characters",
    Error:       errors["password"],
  })

  @daisyui.Button(daisyui.ButtonProps{
    Variant: daisyui.ButtonPrimary,
    Class:   "w-full mt-2",
  }) { Create account }

</form>

That is 23 fewer lines. Per form.

A typical app has 8 to 15 forms. That is 185 to 345 lines of markup you never write, never maintain, and never typo. When DaisyUI changed its fieldset markup between v4 and v5, raw-DaisyUI users had to update every template by hand. kraft-ui users updated one component file. Every form in the app was fixed instantly.

49%

less markup

1

file to fix

Half the markup

Each field goes from 14 lines of fieldset boilerplate to a 4-line props struct. The same HTML is generated, you just never type it.

Caught at go build

Mistype a variant constant and the compiler stops you before your users see a broken badge. No more hunting for silent class-string bugs.

30+ themes, one attribute

Set data-theme on your HTML element. Every daisyui component in your app adapts with zero extra work.

Components driven by your data

Show a coloured order status badge. Here is what building that variant switch looks like in raw DaisyUI versus a typed Go function.

Without kraft-ui class strings, no IDE help
html
<span class={
  func() string {
    switch order.Status {
    case "shipped":
      return "badge badge-primary"
    case "delivered":
      return "badge badge-success"
    case "cancelled":
      return "badge badge-error"
    default:
      return "badge badge-neutral"
    }
  }()
}>{ order.Status }</span>

// "badge-primry" compiles fine.
// Your users find the typo.
With kraft-ui typed, autocompletable, refactorable
go
@daisyui.Badge(daisyui.BadgeProps{
  Variant: orderVariant(order.Status),
}) { { order.Status } }

func orderVariant(s string) daisyui.BadgeVariant {
  switch s {
  case "shipped":
    return daisyui.BadgePrimary
  case "delivered":
    return daisyui.BadgeSuccess
  case "cancelled":
    return daisyui.BadgeError
  default:
    return daisyui.BadgeNeutral
  }
}

// daisyui.BadgePrimry does not compile.
// Rename a constant: IDE finds every usage.

The right side is fully refactorable. Use your IDE to find all usages of daisyui.BadgePrimary across the entire project in one step.

Themes: one attribute, everything changes

This is the same code rendered with four DaisyUI themes. No conditional classes. No per-theme components.

html
<html data-theme={ user.PreferredTheme }>
  <!-- every daisyui.* component adapts automatically -->
lightActive
darkActive
cupcakeActive
cyberpunkActive

Open source. No magic. No lock-in.

kraft-ui does not hide DaisyUI behind an opaque layer. Open pkg/daisyui/ and you will understand any component in 30 seconds. Copy it into your own project, change anything, or contribute a better version back. MIT licensed. Free forever.

1

Copy, do not depend

Vendor the components you need. You own the code completely.

2

No black box

If a component does not behave as expected, open the file. No mystery.

3

Contribute back

Found a better pattern? Open a PR. This library grows with the community.

All components, live

Buttons

Badges

Primary Secondary Accent Success Warning Error Info Outline Ghost xs sm md lg

Alerts

Card

Order #1042

Your order has been confirmed and is on its way.

Inputs

Invalid input

Explore component docs