Build UIs that look and feel like Frappe products by composing frappe-ui components and styling with the library's semantic Tailwind tokens.
Quick start
<script setup>
import { Button, Dialog, FormControl } from 'frappe-ui'
import { ref } from 'vue'
const open = ref(false)
const name = ref('')
</script>
Where to look
Prop names, prop value types, slot names and token names live in these files, not here. Open the one you need before you write markup.
| Writing this | Open this first |
|---|---|
| any component, any page, any Tailwind class | CORE.md |
| anything that fetches or writes data | DATA.md |
| a fresh Vite + Vue 3 project | SETUP.md |
Contracts
These hold across components. Everything else is per-component, and lives in CORE.md.
- Pick the component. Every interactive element comes from
CORE.md. Raw HTML is for layout: grids, flex, spacing wrappers. - Color is two props:
variantandtheme. The value sets differ per component —CORE.mdlists each one. In your own markup, colors come from the semantic scales:bg-surface-*,text-ink-*,border-outline-*. - Two-way state is
v-model. Inputs takev-model. Overlays takev-model:open.ComboboxandMultiSelectadd optionalv-model:query.Listaddsv-model:selectionandv-model:active. - Icons are CSS classes.
<span class="lucide-edit size-4" aria-hidden="true" />. A prop namedicontakes the string"lucide-edit". - Slot names are per component, never universal. Read the component's
entry in
CORE.mdbefore writing a<template #…>. - Frappe API calls go through the
use*composables —useCall,useList,useDoc,useDoctype,useNewDoc, all exported fromfrappe-ui. Each one takes its own option set and returns its own shape; DATA.md lists them separately.