A lightweight Vue.js UI library with a simple API, inspired by Google's Material Design.


Keen UI

Keen UI is a Vue.js UI library with a simple API, inspired by Google's Material Design.

Keen UI is not a CSS framework. Therefore, it doesn't include styles for a grid system, typography, etc. Instead, the focus is on interactive components that require Javascript. You should be able to use Keen UI with any page layout, structure, or CSS framework.

Documentation and demo




Browser support

IE 10+ (due to Flexbox support).


npm install keen-ui --save


CSS Reset

Before using Keen UI, ensure that the following CSS resets are applied to your site.

*::after {
    box-sizing: border-box;

html {
    font-size: 100%;

You can add the reset to your stylesheet (before other styles). If you are using a CSS framework, check to see if the framework already includes a reset (most CSS frameworks do). The root font size set on <html> can be customized to globally resize the components.


Use as a Vue plugin (globally registers all components):

import Vue from 'vue';
import KeenUI from 'keen-ui';
import 'keen-ui/dist/keen-ui.css';


new Vue({
    components: {
        // all Keen UI components already registered

Use individual components:

import Vue from 'vue';
import { UiAlert, UiButton } from 'keen-ui';

new Vue({
    components: {

Script tag

First, add a stylesheet link to the Keen UI CSS file in dist/keen-ui.min.css. Then, add a script tag pointing to dist/keen-ui.min.js after adding Vue.

If Keen UI detects the global Vue object, all components will be registered automatically. The components will also be made available globally via window.KeenUI.


<!-- Place this in <head> -->
<link rel="stylesheet" href="path/to/keen-ui.min.css">

<!-- Place this in <body> -->
<div id="app">
    <ui-button>Hello world!</ui-button>

<script src="path/to/vue.js"></script>
<script src="path/to/keen-ui.min.js"></script>
    new Vue({
        el: '#app',
        components: {
            // all Keen UI components already registered


You can customize many aspects of Keen UI, including theme colors, component sizes, default props, and more.

See Customization.

Using standalone components

Each component is built into a standalone file with the necessary CSS included. You can use these individual standalone components without importing the rest of the library. The standalone components are located in the lib/ folder.

NOTE: Standalone component files each contain their own dependencies, and many contain overlapping dependencies. As a result, using multiple standalone files may increase the size of your bundle due to duplicate code.

import Vue from 'vue';
import 'keen-ui/src/bootstrap'; // Required when using standalone components, should be imported only once in your project
import UiButton from 'keen-ui/lib/UiButton';

new Vue({
    components: {


Keen UI is open source and released under the MIT Licence.

Copyright (c) 2019 Josephus Paye II.

PS: Made something cool with Keen UI? I would love to know! Tweet to me at @JosephusPaye.

  • Keen UI based on vue@2.0x

    Keen UI based on [email protected]

    Just finished about all components and pass the docs as test...

    Notice that code style hasn't been justify so this pr couldn't been merged for now.. I will commit some changes soon..

    Delete the RadioGroup and make Radio replace it... 3-level two way prop is too complicated to apply for vue2.0.

    And many other changes... Meanwhile, I create a work-flow repo for keen-ui's ssr dev..

    checkout a new branch first maybe?

    opened by LucasIcarus 64
  • UiSelect @query-changed=

    UiSelect @query-changed="brandQueryChanged | debounce 500" not work

                      label="XXX" name="select-cat-2" 
                      @query-changed="brandQueryChanged | debounce 500"
                      :loading="loading.selectBrands" :options-loaded="loading.brandsOptionsLoaded"
                      :options="brandsOptionsSelect" :value.sync="goodFm.brandId"

    bad,not work

                      label="XXX" name="select-cat-2" 
                      :loading="loading.selectBrands" :options-loaded="loading.brandsOptionsLoaded"
                      :options="brandsOptionsSelect" :value.sync="goodFm.brandId"

    it's ok.


    opened by xiaolongyuan 19
  • the date&time picker is important

    the date&time picker is important

    keen-ui is so beautiful and useful; i have found the thing like it for a long time;

    I do not find a datetime component in keen-ui; and do you have a plan to support it???

    and the rich text editor like Draft.js is important too, i think

    request implemented 
    opened by kuerme 19
  • Porting to Vue 2 (Help?)

    Porting to Vue 2 (Help?)

    I'm trying to upgrade Keen-UI to support vue 2 (whose RC1 came out a few days ago). I got everything running in a simple test harness (https://github.com/thehumaneffort/keen-ui/tree/next), and fixed a few trivial errors, but doing so did not cause anything to really work. I'm unfamiliar with Vue (and Vue 2), so it's probably due to some lack of understanding. I'd love to help out and get everything moved over, but I'm going to need a bit of help understanding things. Does anybody have time to hold my hand through the first stages?

    opened by dts 17
  • UiModel issue : close button disabled

    UiModel issue : close button disabled

        <div class="ui-modal-header">
                        <slot name="header">
                            <h1 v-text="header" class="ui-modal-header-text"></h1>
                            type="clear" icon="&#xE5CD" class="ui-modal-close-button" @click="close"
                            :disabled="!dismissible" v-if="showCloseButton" v-el:close-button


    opened by xiaolongyuan 16
  • Port from stylus to SASS

    Port from stylus to SASS

    This seems to be the most complete UI Library for VueJS, but I need to be able to style it, at the moment this doesn't seem to be possible without editing the vanilla CSS file or overriding the styling.

    What would it be the easiest way of porting this to SASS (without overriding all .vue files :p)? For example, if I import a component using ES6, would I be able to add my SCSS/CSS file externally or it would possibly conflict with inline CSS added by WebPack?

    import Vue from 'vue';
    import { UiAlert, UiButton } from 'keen-ui';
    new Vue({
        components: {

    Also, sometimes I have components in different sections of the website that have different design. Is it possible to add a custom class without targeting an external component wrapper? If not, it would be nice to have some kind of :custom-class props, to target at least the main container.

    opened by microcipcip 13
  • Radio Group Missing Value Prop

    Radio Group Missing Value Prop

    When running the Basic Radio Group component from the examples page, I'm getting the following error:

    vue.runtime.esm.js:427 [Vue warn]: Missing required prop: "value"
    found in
    ---> <UiRadio> at C:\code\packages\keen-ui\src\UiRadio.vue
           <UiRadioGroup> at C:\code\packages\keen-ui\src\UiRadioGroup.vue
    opened by curly33 11
  • UiSelect still doesn't work with preselect

    UiSelect still doesn't work with preselect

    I think you still have some issues with the <ui-select> default or value. I have associated a object with the same value, but it doesn't preselect it, nothing is selected, just like 0.8.8

    opened by EmilMoe 10
  • UI-Select value field

    UI-Select value field

    Please, add value field in options for write to (:value). Its so unnaturally every time making temporary variable, lookup value from options to this variable, and then watch for changes for get new value only.

    example Options for list = [{ text: 'variant1', value:'id1' }, { text: 'variant2', value:'id2' }] data model = { .... 'selectvalue': 'id1' }

    question implemented 
    opened by gendalf 10
  • Checkbox value

    Checkbox value "on"

    I noticed that the submitted value for a checked checkbox is "on", while the synced value of the model is true. Is there a way to have the checkbox submit true instead?

    question implemented 
    opened by lowerends 10
  • UiAutocomplete


    I'm not sure where you define the value prop? But it's returning the text value. I can't see how to return the value property which contains my id?

    Ideally I would like to:

    • :text.sync=""
    • - to sync the text
    • :value.sync=""
    • - to sync the value
    • :object.sync=""
    • - to sync the whole object
    opened by EmilMoe 10
  • Build with vite (and rollup)

    Build with vite (and rollup)

    I tried to experiment a little with building with vite so we can get rid of webpack. There was a bit of complication with the lib build as vite does not allow multiple entries but I have found an elegant way of doing it.

    Please take a look once you have some time and let me know what you think.

    opened by kilobyte2007 1
  • Added the icon prop to the UiTab component

    Added the icon prop to the UiTab component

    The reason for this is that in Vue 3 we are required to use