New project
A new Vue app from the Vite template, with Tailwind 4 and grani.
1. Create the app
npm create vite@latest my-app -- --template vue-tscd my-app
2. Add Tailwind
Install Tailwind 4 and its Vite plugin, then add the plugin to the config.
npm i tailwindcss @tailwindcss/vitevite.config.tsimport { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import tailwindcss from '@tailwindcss/vite' export default defineConfig({ plugins: [vue(), tailwindcss()],})
3. Install grani
npm i grani4. Register grani
Register grani on your Vue app with
createGrani().src/main.tsimport { createApp } from 'vue'import { createGrani } from 'grani'import './style.css'import App from './App.vue' createApp(App).use(createGrani()).mount('#app')
6. Try a form
Replace
src/App.vue.UiToasterdisplays notifications: mount it once near the root of your app, andUiConfirmbeside it when you ask questions withuseConfirm(). Enter a name and select Save: a toast confirms the example is working.src/App.vue<script setup lang="ts">import { ref } from 'vue'import { UiButton, UiField, UiInput, UiToaster, useToast } from 'grani' const name = ref('')const toast = useToast()function save() { toast.success(`${name.value} saved`)}</script> <template> <form class="flex flex-col gap-4 p-4" @submit.prevent="save"> <UiField label="Client name"><UiInput v-model="name" /></UiField> <UiButton type="submit" :disabled="!name.trim()">Save</UiButton> </form> <UiToaster /></template>
7. Run it
npm run devOptional: auto-import components
Automatically import grani components used in your templates with
GraniResolver.npm i -D unplugin-vue-componentsvite.config.tsimport { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import tailwindcss from '@tailwindcss/vite'import Components from 'unplugin-vue-components/vite'import { GraniResolver } from 'grani/resolver' export default defineConfig({ plugins: [vue(), tailwindcss(), Components({ resolvers: [GraniResolver()] })],})