Skip to content

From scratch

Build a minimal Vue app with Vite, Tailwind CSS and grani. This guide walks through each file without using a starter template.

  1. 1. Install the packages

    npm i vue graninpm i -D vite @vitejs/plugin-vue tailwindcss @tailwindcss/vite
  2. 2. Configure Vite

    vite.config.ts
    import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import tailwindcss from '@tailwindcss/vite' export default defineConfig({  plugins: [vue(), tailwindcss()],})
  3. 3. Write the page

    Save it as index.html in the root of the app.

    <!doctype html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>My app</title>  </head>  <body>    <div id="app"></div>    <script type="module" src="/src/main.ts"></script>  </body></html>
  4. 4. Start the app

    Register grani on your Vue app with createGrani().

    src/main.ts
    import { createApp } from 'vue'import { createGrani } from 'grani'import './style.css'import App from './App.vue' createApp(App).use(createGrani()).mount('#app')
  5. 5. Import the styles

    To customize the theme, add your token overrides below these imports. See Theming for details, or generate brand colors on the Theme page.

    src/style.css
    @import 'tailwindcss';@import 'grani/style.css';
  6. 6. Try a form

    UiToaster displays notifications: mount it once near the root of your app, and UiConfirm beside it when you ask questions with useConfirm(). 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. 7. Run it

    npm exec vite
  8. Optional: auto-import components

    Automatically import grani components used in your templates with GraniResolver.

    npm i -D unplugin-vue-components
    vite.config.ts
    import { 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()] })],})