frappe-ui: a Vue component library that assumes a Frappe backend
The all-in-one toolkit for modern frontends. High-quality components, app recipes and AI-ready docs.
At a glance
- What is it?
- Fifty-odd components, a set of data composables that talk to a Frappe server directly, and a Vite plugin that turns the dev-server proxy into a one-line config change.
- Who is it for?
- frappe-ui makes the most sense once you accept that it is a component library with opinions about its backend rather than a general Vue toolkit. The composables, the dev-server proxy, the DocType type generation and the Tailwind content globs all assume a Frappe server, and the app recipes are screens from Frappe applications rather than neutral examples.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A component library that knows what a DocType is
The description calls this the all-in-one toolkit for modern frontends, and the first clue that it is not generic is in the second paragraph. There are composables called `useCall`, `useList`, `useDoc`, `useDoctype` and `useNewDoc`, and they handle fetching, caching, pagination and writes against a Frappe backend. Those five names are the Frappe data model showing through a component library.
Installation is a single package.
npm install frappe-uiThe stated floor is Node 20.19.0 or newer, Vite, Vue 3.5 or newer, and Tailwind CSS with a floor of 3.4 and a ceiling below 4. That version ceiling is a real constraint rather than boilerplate, since the library ships a Tailwind preset.
What you get on the component side is 50 or more pieces: buttons, form controls, dialogs, popovers, tabs, sidebars and app shells. The README is precise that they are built on Vue 3, Tailwind CSS and Reka UI primitives, which means the accessible behaviour comes from Reka UI and the styling comes from Tailwind. That is a reasonable stack for 2026 and it is also a dependency you inherit.
Design tokens where dark mode is a token flip
The theming section makes a specific claim: dark mode is built in, so a `dark:` variant is never needed. The mechanism is semantic tokens named `surface`, `ink` and `outline`, plus radius, typography and elevation scales, and the tokens flip under a `[data-theme="dark"]` attribute.
That is a better design than the usual Tailwind dark mode pattern, where every component carries a parallel set of dark-prefixed classes and you find out what you forgot in production. Here a component refers to `ink` and gets the right value in either theme.
The repository tree shows the design system has been through at least one significant revision. There is a top level `tailwind/` directory holding the preset and its migration script, and a curious root file called `.tokens-v2-ink-shift`, which reads like a record of a change made across the token set.
That vintage also explains the migration tooling. The package `bin` section in `package.json` registers ten scripts, one per migration: base props, list, navigation, overlays, tokens v2, shortcuts, editor, destinations, data and packaging. Shipping your own migration binaries in the published package is unusual and shows how much the public API has moved recently, which is also why the README tells you to read the migration guide before touching anything.
The Vite plugin does three jobs at once
The quick start asks for one config addition, and it is a single plugin call rather than a list of proxies and aliases.
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import frappeui from 'frappe-ui/vite'
export default defineConfig({
plugins: [frappeui(), vue()],
})The README credits the Vite plugins with four things: the Frappe dev-server proxy, Lucide icon auto-imports, DocType type generation and production builds. Three of those four would otherwise be real configuration work, and the DocType generation in particular is the piece that ties the library to its backend, since it produces types from the server's document definitions.
Tailwind gets its own pair of exports for the preset and the content globs, added in one more config file.
import preset, { content } from 'frappe-ui/tailwind'
export default {
presets: [preset],
content: [...content, './index.html', './src/**/*.{vue,js,ts}'],
}Then the stylesheet is imported once from your CSS entry.
@import 'frappe-ui/style.css';Three config files and one import is the whole ceremony, which is a reasonable ask for a library that also handles proxying and code generation.
Nine package entries, because not everything belongs in one bundle
The entry table is where the design decisions become concrete. `frappe-ui` is the core: components, data composables, `dialog` and `toast`, and directives. Then `frappe-ui/editor` for a TipTap-based rich text editor with kits and extensions, `frappe-ui/code-editor` for a CodeMirror-based editor and `CodeKit`, `frappe-ui/list` for a composable List family covering rows, cells, headers, groups and sorting, and `frappe-ui/charts` for ECharts wrappers covering area, bar, line, donut, funnel, heatmap, sankey and scatter.
The remainder are smaller: `frappe-ui/icons` for Frappe's own icons such as `StepsIcon` and `LightningIcon`, `frappe-ui/vite` for the plugins, `frappe-ui/tailwind` for the preset and content globs, and `frappe-ui/style.css` for the base stylesheet, fonts and token variables.
Splitting editors, lists and charts into separate entries is the right call for a library with this range, since most applications need a button and maybe a chart, not an editor bundle. `package.json` declares the package as ESM only, and lists `sideEffects` covering CSS, Vue files, the molecules index and the charts index, which is how the build keeps tree shaking honest.
The `imports` field adds four internal aliases, `#components/*`, `#molecules/*`, `#composables/*` and `#utils/*`, each resolving to a directory, a file and an index. That is a hint about the internal structure: components at one level, molecules at another, with shared logic in composables and utilities.
Recipes and the eight screens they are drawn from
Instead of a generic component gallery, the README points at eight full application screens built with the library, each with a desktop and a mobile layout: mail, tickets, deals and accounting among them. They are on the home page of the documentation site.
This is the most useful thing in the README for judging the library, and it is worth being clear about why. A mail screen and a tickets screen are Frappe applications, and a deals and accounting screen is a CRM. Those are the applications Frappe is actually for, which means the components have been pushed by real screens with real density rather than assembled for a demo.
The user list under Used by confirms the same thing from the other side: Frappe Cloud, Frappe CRM, Helpdesk, Frappe HR, Frappe Learning, Insights, Builder and Gameplan. All eight are first-party Frappe projects. So the library has a strong reference user base and no obvious evidence yet of third-party adoption outside the ecosystem, which is not a criticism so much as a description of the scope.
The mobile layouts matter for the same reason. Applications that agents and customers both use tend to be opened on a phone, and a component set tested against eight real screens is likelier to have solved the awkward cases than one built from a design system.
The docs are written to be read by an AI agent
Frappe UI treats machine-readable documentation as a feature. There is an `llms.txt` at the documentation site listing every docs page, and a repository skill under `skills/frappe-ui/` that teaches Claude Code, Cursor, Codex and similar tools how to use the library.
npx skills add https://github.com/frappe/frappe-ui/tree/main/skills/frappe-uiOr, as the README puts it, point the agent at `ui.frappe.io/llms.txt`. Both routes are offered because one gives an agent the component knowledge and the other just gives it an index, and the README is not precious about which you should pick.
The repository is organised to support that. `PHILOSOPHY.md` holds design rules, `CONTEXT.md` holds shared vocabulary, and `spec/` holds component contracts and decision records. The contributing section tells you to read all three before changing a public API, which is a stronger instruction than the usual request for tests.
The testing story is layered. `yarn test` runs vitest, `yarn type-check` runs vue-tsc, and the root of the tree holds a cypress config, a vitest config with its own setup file, and a `.nycrc.json` for coverage. There is also a `.semgrep.yml`, a pre-commit config, husky, and a greptile directory, which is a lot of automated review for a component library.
Editorial conclusion
frappe-ui makes the most sense once you accept that it is a component library with opinions about its backend rather than a general Vue toolkit. The composables, the dev-server proxy, the DocType type generation and the Tailwind content globs all assume a Frappe server, and the app recipes are screens from Frappe applications rather than neutral examples. Inside that boundary it is unusually well documented for a project at 1.0.0-rc.2, with a migration guide, ten migration scripts, a philosophy file and a spec directory. Two things to weigh before adopting: the package is still a release candidate while the last tagged GitHub release is from 2022, and 168 open issues suggest the component surface is still moving. Read `PHILOSOPHY.md` before you change a public API, install the agent skill if you are working with an AI assistant, and start from the recipes to see whether the eight sample screens match the screens you actually have to build.
Frequently asked questions
What does frappe-ui need to be installed?
Node 20.19.0 or newer, Vite, Vue 3.5 or newer, and Tailwind CSS from 3.4 up to but not including 4. Install it with `npm install frappe-ui`, add the `frappe-ui/vite` plugin to your Vite config, add the preset and content globs from `frappe-ui/tailwind`, and import `frappe-ui/style.css` once from your CSS entry.
How does frappe-ui handle dark mode?
Through semantic tokens rather than dark-prefixed classes. The library ships `surface`, `ink` and `outline` color tokens along with radius, typography and elevation scales, and they flip under a `[data-theme="dark"]` attribute, so the README states a `dark:` variant is never needed in a component.
Can frappe-ui be used with a backend other than Frappe?
The components themselves are ordinary Vue 3 and Tailwind, but the toolkit is built around Frappe. The data composables `useCall`, `useList`, `useDoc`, `useDoctype` and `useNewDoc` fetch, cache, paginate and write against a Frappe backend, the Vite plugin includes a dev-server proxy and DocType type generation, and the recipes are screens from Frappe applications.
How do you use frappe-ui with an AI coding assistant?
Install the bundled agent skill with `npx skills add https://github.com/frappe/frappe-ui/tree/main/skills/frappe-ui`, which the README says teaches Claude Code, Cursor, Codex and similar tools how to use the library. Alternatively point the tool at `ui.frappe.io/llms.txt`, a list of every documentation page.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/frappe-frappe-ui)