Installation
Setup
Add to a Vue project
Install the Pohon UI package
pnpm add pohon-ui unocss @vinicunca/unocss-preset
yarn add pohon-ui unocss @vinicunca/unocss-preset
npm install pohon-ui unocss @vinicunca/unocss-preset
bun add pohon-ui unocss @vinicunca/unocss-preset
Add the Pohon UI Vite plugin in your vite.config.ts
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui()
]
});
import vue from '@vitejs/plugin-vue';
import laravel from 'laravel-vite-plugin';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
laravel({
input: ['resources/js/app.ts'],
refresh: true
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false
}
}
}),
ui({
router: 'inertia'
})
]
});
import inertia from '@adonisjs/inertia/client';
import adonisjs from '@adonisjs/vite/client';
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
adonisjs({
entrypoints: ['inertia/app/app.ts'],
reload: ['resources/views/**/*.edge']
}),
inertia(),
vue(),
ui({
router: 'inertia'
})
]
});
unplugin-auto-import and unplugin-vue-components, which will generate auto-imports.d.ts and components.d.ts type declaration files. You will likely want to gitignore these, and add them to your tsconfig.{
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "auto-imports.d.ts", "components.d.ts"]
}
# Auto-generated type declarations
auto-imports.d.ts
components.d.ts
create-vuebuild script runs vue-tsc in parallel with vite build (run-p type-check "build-only {@}"), so on a clean checkout type-checking can start before the files exist and fail with errors like Cannot find name 'useToast'. Run the type-check after the build instead so the declarations are generated first.{
"scripts": {
"build": "run-s build-only type-check"
}
}
tsconfig files to enable auto-completion in your vite.config.ts.{
"compilerOptions": {
"paths": {
"#build/ui": [
"./node_modules/.pohon-ui/ui"
]
}
}
}
{
"compilerOptions": {
"paths": {
"#build/ui/*": [
"./node_modules/.pohon-ui/ui/*"
]
}
}
}
Use the Pohon UI Vue plugin
import ui from 'pohon-ui/vue-plugin';
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import App from './App.vue';
const app = createApp(App);
const router = createRouter({
routes: [],
history: createWebHistory()
});
app.use(router);
app.use(ui);
app.mount('#app');
import type { DefineComponent } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import ui from 'pohon-ui/vue-plugin';
import { createApp, h } from 'vue';
const appName = import.meta.env.VITE_APP_NAME || 'Laravel x Pohon UI';
createInertiaApp({
title: (title) => (title ? `${title} - ${appName}` : appName),
resolve: (name) =>
resolvePageComponent(
`./pages/${name}.vue`,
import.meta.glob<DefineComponent>('./pages/**/*.vue')
),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(ui)
.mount(el);
}
});
import type { DefineComponent } from 'vue';
import { resolvePageComponent } from '@adonisjs/inertia/helpers';
import { createInertiaApp } from '@inertiajs/vue3';
import ui from 'pohon-ui/vue-plugin';
import { createApp, h } from 'vue';
const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS x Pohon UI';
createInertiaApp({
title: (title) => (title ? `${title} - ${appName}` : appName),
resolve: (name) =>
resolvePageComponent(
`../pages/${name}.vue`,
import.meta.glob<DefineComponent>('../pages/**/*.vue')
),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(ui)
.mount(el);
}
});
Configure UnoCSS
import { presetVinicunca } from '@vinicunca/unocss-preset';
import { pohonColors } from 'pohon-ui/unocss';
import { defineConfig } from 'unocss';
export default defineConfig({
presets: [presetVinicunca()],
theme: { colors: pohonColors },
});
Import virtual:uno.css in your Vue or Inertia entrypoint before mounting the application:
import 'virtual:uno.css';
Wrap your app with App component
<template>
<PApp>
<RouterView />
</PApp>
</template>
<template>
<PApp>
<!-- Your content goes here -->
</PApp>
</template>
<template>
<PApp>
<!-- Your content goes here -->
</PApp>
</template>
App component sets up global config and is required for Toast, Tooltip and programmatic overlays.Add the isolate class to your root container
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Pohon UI</title>
</head>
<body>
<div id="app" class="isolate"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
@inertiaHead
@vite('resources/js/app.ts')
</head>
<body>
<div class="isolate">
@inertia
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
@inertiaHead()
@vite(['inertia/app/app.ts', `inertia/pages/${page.component}.vue`])
</head>
<body>
@inertia({ class: 'isolate' })
</body>
</html>
Explore working examples
See the Nuxt playground and Vue playground for complete Pohon UI setups.
Options
You can customize Pohon UI by providing options in your vite.config.ts.
prefix
Use the prefix option to change the prefix of the components.
- Default:
P
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
prefix: 'Nuxt'
})
]
});
ui
Use the ui option to provide configuration for Pohon UI. This is the Vue equivalent of the ui key in Nuxt's app.config.ts.
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
ui: {
colors: {
primary: 'green',
neutral: 'slate'
}
}
})
]
});
dts
Use the dts option to enable or disable the generation of declaration files for auto-imported components and composables.
- Default:
true
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
dts: false
})
]
});
icon
Use the icon option to set default props for the Icon component (size, mode, customize) and to configure build-time icon bundling through clientBundle. Bundling of Pohon UI's own icons is enabled by default when their collection is installed. Set clientBundle: false to opt out.
- Default:
{}
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
icon: {
mode: 'svg',
clientBundle: {
scan: true
}
}
})
]
});
colorMode
Use the colorMode option to enable or disable the color mode integration from @vueuse/core.
- Default:
true
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
colorMode: false
})
]
});
theme.colors
Use the theme.colors option to define the dynamic color aliases used to generate components theme.
- Default:
['primary', 'secondary', 'success', 'info', 'warning', 'error']
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
theme: {
colors: ['primary', 'error']
}
})
]
});
error if you use forms since validation styles rely on it. primary is always included.The --ui-color-<alias>-* shades themselves are not generated: define them in your CSS (see CSS Variables).theme.transitions
Use the theme.transitions option to enable or disable transitions on components.
- Default:
true
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
theme: {
transitions: false
}
})
]
});
transition-colors class on components with hover or active states.theme.unstyled
Use the theme.unstyled option to remove all default theme classes from components, keeping only their structure and the classes you provide through class, ui or app.config.ui.
- Default:
false
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
theme: {
unstyled: true
}
})
]
});
Modal, Drawer or Calendar will need you to re-supply their layout, similar to PrimeVue's unstyled mode.theme.defaultVariants
Use the theme.defaultVariants option to override the default color and size variants for components.
Only defaults that are exactly primary or md are replaced, so Avatar keeps color: 'neutral' and Separator keeps size: 'xs'.
- Default:
{ color: 'primary', size: 'md' }
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
theme: {
defaultVariants: {
color: 'neutral',
size: 'sm'
}
}
})
]
});
prose
Use the prose option to enable Pohon UI Prose components and their theme.
- Default:
false
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
prose: true
})
]
});
autoImport
Use the autoImport option to disable composable auto-imports or to customize unplugin-auto-import options.
- Default:
{}
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
autoImport: false
})
]
});
pohon-ui/composables.components
Use the components option to disable component auto-imports or to customize unplugin-vue-components options.
- Default:
{}
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
components: false
})
]
});
import Button from 'pohon-ui/components/Button.vue' or import ProseCode from 'pohon-ui/components/prose/Code.vue'.router
Use the router option to configure routing integration. This is useful for applications that don't use vue-router, such as Electron apps, MPAs, or frameworks like Inertia.js or Hybridly.
- Default:
true
| Value | Description |
|---|---|
true | Uses vue-router for navigation with RouterLink component. |
false | Disables routing integration, links render as plain <a> tags. |
'inertia' | Uses Inertia.js for navigation with its Link component. |
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
router: false
})
]
});
router: false in the Vite config and passing a function when installing the Vue plugin:import { router } from 'hybridly';
import ui from 'pohon-ui/vue-plugin';
app.use(ui, {
router: (event, { href, external }) => {
if (external) {
return;
}
event.preventDefault();
router.navigate({ url: href });
}
});
false or 'inertia', vue-router is not required as a dependency.scanPackages
Use the scanPackages option to specify additional npm packages that should be scanned for components using Pohon UI. This is useful when you have a shared component library that uses Pohon UI components internally.
import vue from '@vitejs/plugin-vue';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
UnoCSS(),
vue(),
ui({
scanPackages: ['@my-org/ui-components']
})
]
});
pohon-ui is scanned. Use this option when your external packages contain Vue components that use Pohon UI.root
Use the root option to override the directory where Pohon UI generates its .pohon-ui directory (containing the theme templates). By default it uses Vite's root, but in setups like electron-vite the renderer's root points to a sub-directory (e.g. src/renderer), so the templates land in src/renderer/node_modules/.pohon-ui where UnoCSS doesn't scan them, causing theme classes like bg-background, ring-border and divide-border to be missing.
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'electron-vite';
import ui from 'pohon-ui/vite';
import UnoCSS from 'unocss/vite';
export default defineConfig({
renderer: {
root: 'src/renderer',
plugins: [
vue(),
ui({
root: __dirname
})
]
}
});
root at your project root so the generated .pohon-ui directory ends up in a node_modules that UnoCSS scans.Continuous releases
Pohon UI uses pkg.pr.new for continuous preview releases, providing developers with instant access to the latest features and bug fixes without waiting for official releases.
Automatic preview releases are created for all commits and PRs to the main branch. Use them by replacing your package version with the specific commit hash or PR number.
{
"dependencies": {
- "pohon-ui": "^2.0.0-rc",
+ "pohon-ui": "https://pkg.pr.new/pohon-ui@4c96909",
}
}