Skip to content
konsta-ui logo

Konsta UI Design Guide

konsta-ui

Guide to using Konsta UI for pixel-perfect iOS and Material Design components in Capacitor apps. Works with React, Vue, and Svelte. Use this skill when users want native-looking UI without Ionic, or prefer a lighter framework.

yeohj0710/wellnessbox0installs0stars

SKILL.md

Full skill instructions

Konsta UI Design Guide

Build pixel-perfect iOS and Material Design apps with Konsta UI.

When to Use This Skill

  • User wants native-looking UI without Ionic
  • User asks about Konsta UI
  • User wants iOS/​Material Design components
  • User is using React/​Vue/​Svelte
  • User wants lightweight UI framework

What is Konsta UI?

Konsta UI provides:

  • Pixel-perfect iOS and Material Design components
  • Works with React, Vue, and Svelte
  • Tailwind CSS integration
  • ~40 mobile-optimized components
  • Small bundle size (~30KB gzipped)

Getting Started

Installation

# React
bun add konsta

# Vue
bun add konsta

# Svelte
bun add konsta

# Required: Tailwind CSS
bun add -D tailwindcss postcss autoprefixer
bunx tailwindcss init -p

Tailwind Configuration

// tailwind.config.js
const konstaConfig = require('konsta/​config');

module.exports = konstaConfig({
  content: [
    './​src/​**/​*.{js,ts,jsx,tsx,vue,svelte}',
  ],
  // Extend or override Konsta config
  theme: {
    extend: {},
  },
});

Setup (React)

// App.tsx
import { App, Page, Navbar, Block } from 'konsta/​react';

export default function MyApp() {
  return (
    <App theme="ios"> {/​* or theme="material" */​}
      <Page>
        <Navbar title="My App" />
        <Block>
          <p>Hello Konsta UI!</​p>
        </​Block>
      </​Page>
    </​App>
  );
}

Setup (Vue)

<!-- App.vue -->
<template>
  <k-app theme="ios">
    <k-page>
      <k-navbar title="My App" />
      <k-block>
        <p>Hello Konsta UI!</​p>
      </​k-block>
    </​k-page>
  </​k-app>
</​template>

<script setup>
import { kApp, kPage, kNavbar, kBlock } from 'konsta/​vue';
</​script>

Core Components

Page Structure

import {
  App,
  Page,
  Navbar,
  NavbarBackLink,
  Block,
  BlockTitle,
} from 'konsta/​react';

function MyPage() {
  return (
    <App theme="ios">
      <Page>
        <Navbar
          title="Page Title"
          subtitle="Subtitle"
          left={<NavbarBackLink onClick={() => history.back()} />}
        />

        <BlockTitle>Section Title</​BlockTitle>
        <Block strong inset>
          <p>Block content with rounded corners and padding.</​p>
        </​Block>
      </​Page>
    </​App>
  );
}

Lists

import {
  List,
  ListItem,
  ListInput,
  ListButton,
} from 'konsta/​react';
import { ChevronRight } from 'framework7-icons/​react';

function MyList() {
  return (
    <>
      {/​* Simple list */​}
      <List>
        <ListItem title="Item 1" />
        <ListItem title="Item 2" />
        <ListItem title="Item 3" />
      </​List>

      {/​* List with details */​}
      <List strong inset>
        <ListItem
          title="John Doe"
          subtitle="Designer"
          text="Additional info text"
          media={<img src="/​avatar.jpg" className="w-10 h-10 rounded-full" />}
          link
        />
        <ListItem
          title="Settings"
          after="On"
          link
        />
      </​List>

      {/​* Form list */​}
      <List strongIos insetIos>
        <ListInput
          label="Email"
          type="email"
          placeholder="Enter email"
        />
        <ListInput
          label="Password"
          type="password"
          placeholder="Enter password"
        />
        <ListButton>Login</​ListButton>
      </​List>
    </>
  );
}

Forms

import {
  List,
  ListInput,
  Toggle,
  Radio,
  Checkbox,
  Stepper,
  Range,
} from 'konsta/​react';
import { useState } from 'react';

function MyForm() {
  const [toggle, setToggle] = useState(false);
  const [gender, setGender] = useState('male');

  return (
    <List strongIos insetIos>
      {/​* Text inputs */​}
      <ListInput
        label="Name"
        type="text"
        placeholder="Your name"
        clearButton
      />

      <ListInput
        label="Email"
        type="email"
        placeholder="Email address"
      />

      <ListInput
        label="Bio"
        type="textarea"
        placeholder="About yourself"
        inputClassName="!h-20 resize-none"
      />

      {/​* Toggle */​}
      <ListItem
        title="Notifications"
        after={
          <Toggle
            checked={toggle}
            onChange={() => setToggle(!toggle)}
          />
        }
      />

      {/​* Radio */​}
      <ListItem
        title="Male"
        media={
          <Radio
            checked={gender === 'male'}
            onChange={() => setGender('male')}
          />
        }
      />
      <ListItem
        title="Female"
        media={
          <Radio
            checked={gender === 'female'}
            onChange={() => setGender('female')}
          />
        }
      />

      {/​* Checkbox */​}
      <ListItem
        title="Agree to terms"
        media={<Checkbox />}
      />

      {/​* Stepper */​}
      <ListItem
        title="Quantity"
        after={<Stepper value={1} min={1} max={10} />}
      />

      {/​* Range */​}
      <ListItem
        title="Volume"
        innerChildren={<Range value={50} />}
      />
    </​List>
  );
}

Buttons

import { Button, Segmented, SegmentedButton } from 'konsta/​react';
import { useState } from 'react';

function Buttons() {
  const [active, setActive] = useState(0);

  return (
    <div className="space-y-4 p-4">
      {/​* Button variants */​}
      <Button>Default</​Button>
      <Button large>Large</​Button>
      <Button small>Small</​Button>
      <Button rounded>Rounded</​Button>
      <Button outline>Outline</​Button>
      <Button clear>Clear</​Button>
      <Button tonal>Tonal</​Button>

      {/​* Colors */​}
      <Button colors={{ fillBg: 'bg-red-500', fillText: 'text-white' }}>
        Custom Color
      </​Button>

      {/​* Disabled */​}
      <Button disabled>Disabled</​Button>

      {/​* Segmented control */​}
      <Segmented strong>
        <SegmentedButton active={active === 0} onClick={() => setActive(0)}>
          Tab 1
        </​SegmentedButton>
        <SegmentedButton active={active === 1} onClick={() => setActive(1)}>
          Tab 2
        </​SegmentedButton>
        <SegmentedButton active={active === 2} onClick={() => setActive(2)}>
          Tab 3
        </​SegmentedButton>
      </​Segmented>
    </​div>
  );
}

Cards

import { Card, Button } from 'konsta/​react';

function Cards() {
  return (
    <Card>
      <img
        src="/​card-image.jpg"
        className="w-full h-48 object-cover"
        alt=""
      />
      <div className="p-4">
        <h3 className="font-bold text-lg">Card Title</​h3>
        <p className="text-gray-500 mt-2">
          Card description text goes here. This is a standard
          card with image, title, and content.
        </​p>
        <div className="flex gap-2 mt-4">
          <Button small>Action 1</​Button>
          <Button small outline>Action 2</​Button>
        </​div>
      </​div>
    </​Card>
  );
}

Dialogs and Sheets

import {
  Dialog,
  DialogButton,
  Sheet,
  Popup,
  Button,
  Page,
  Navbar,
  Block,
} from 'konsta/​react';
import { useState } from 'react';

function Dialogs() {
  const [dialogOpen, setDialogOpen] = useState(false);
  const [sheetOpen, setSheetOpen] = useState(false);
  const [popupOpen, setPopupOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setDialogOpen(true)}>Open Dialog</​Button>
      <Button onClick={() => setSheetOpen(true)}>Open Sheet</​Button>
      <Button onClick={() => setPopupOpen(true)}>Open Popup</​Button>

      {/​* Alert dialog */​}
      <Dialog
        opened={dialogOpen}
        onBackdropClick={() => setDialogOpen(false)}
        title="Dialog Title"
        content="Dialog content goes here."
        buttons={
          <>
            <DialogButton onClick={() => setDialogOpen(false)}>
              Cancel
            </​DialogButton>
            <DialogButton strong onClick={() => setDialogOpen(false)}>
              OK
            </​DialogButton>
          </>
        }
      />

      {/​* Bottom sheet */​}
      <Sheet
        opened={sheetOpen}
        onBackdropClick={() => setSheetOpen(false)}
      >
        <div className="p-4">
          <h2 className="font-bold text-lg mb-4">Sheet Title</​h2>
          <p>Sheet content</​p>
          <Button onClick={() => setSheetOpen(false)} className="mt-4">
            Close
          </​Button>
        </​div>
      </​Sheet>

      {/​* Full page popup */​}
      <Popup opened={popupOpen} onBackdropClick={() => setPopupOpen(false)}>
        <Page>
          <Navbar
            title="Popup"
            right={
              <Button clear onClick={() => setPopupOpen(false)}>
                Close
              </​Button>
            }
          />
          <Block>Popup content</​Block>
        </​Page>
      </​Popup>
    </>
  );
}

Tabbar Navigation

import { App, Page, Tabbar, TabbarLink, Icon } from 'konsta/​react';
import { Home, Search, Person } from 'framework7-icons/​react';
import { useState } from 'react';

function TabsApp() {
  const [activeTab, setActiveTab] = useState('home');

  return (
    <App theme="ios">
      <Page>
        {/​* Page content based on active tab */​}
        {activeTab === 'home' && <HomeContent />}
        {activeTab === 'search' && <SearchContent />}
        {activeTab === 'profile' && <ProfileContent />}

        {/​* Tabbar */​}
        <Tabbar labels className="left-0 bottom-0 fixed">
          <TabbarLink
            active={activeTab === 'home'}
            onClick={() => setActiveTab('home')}
            icon={<Home />}
            label="Home"
          />
          <TabbarLink
            active={activeTab === 'search'}
            onClick={() => setActiveTab('search')}
            icon={<Search />}
            label="Search"
          />
          <TabbarLink
            active={activeTab === 'profile'}
            onClick={() => setActiveTab('profile')}
            icon={<Person />}
            label="Profile"
          />
        </​Tabbar>
      </​Page>
    </​App>
  );
}

Theming

Theme Selection

import { App } from 'konsta/​react';

// Auto-detect platform
<App theme="parent">

// Force iOS style
<App theme="ios">

// Force Material style
<App theme="material">

Dark Mode

import { App } from 'konsta/​react';

// Auto dark mode (follows system)
<App dark>

// Explicit dark mode
<App dark={true}>

// Explicit light mode
<App dark={false}>

Custom Colors with Tailwind

// tailwind.config.js
const konstaConfig = require('konsta/​config');

module.exports = konstaConfig({
  theme: {
    extend: {
      colors: {
        primary: {
          DEFAULT: '#6366f1',
          dark: '#4f46e5',
        },
      },
    },
  },
  // Override Konsta's primary color
  konpistaConfig: {
    colors: {
      primary: '#6366f1',
    },
  },
});

Component-Level Styling

// Override individual component colors
<Button
  colors={{
    fillBg: 'bg-indigo-500',
    fillActiveBg: 'bg-indigo-600',
    fillText: 'text-white',
  }}
>
  Custom Button
</​Button>

<Toggle
  colors={{
    bgChecked: 'bg-green-500',
  }}
/>

With Capacitor

Safe Area Handling

import { App, Page } from 'konsta/​react';

function MyApp() {
  return (
    <App
      theme="ios"
      safeAreas  // Enable safe area handling
    >
      <Page>
        {/​* Content respects safe areas */​}
      </​Page>
    </​App>
  );
}

Capacitor Integration

import { App, Page, Button } from 'konsta/​react';
import { Capacitor } from '@capacitor/​core';

function MyApp() {
  const isNative = Capacitor.isNativePlatform();

  return (
    <App
      theme={Capacitor.getPlatform() === 'ios' ? 'ios' : 'material'}
      safeAreas={isNative}
    >
      <Page>
        <Button onClick={handleNativeAction}>
          Native Action
        </​Button>
      </​Page>
    </​App>
  );
}

Comparison: Konsta vs Ionic

FeatureKonsta UIIonic
Bundle Size~30KB~200KB
Components~40~100+
Tailwind IntegrationNativePossible
RoutingExternalBuilt-in
Framework SupportReact, Vue, SvelteReact, Vue, Angular
Native FeaturesUI onlyUI + Plugins

Choose Konsta when:

  • You want Tailwind-first approach
  • You need smaller bundle size
  • You're using Svelte
  • You want simpler setup

Choose Ionic when:

  • You need comprehensive component library
  • You want built-in routing
  • You need more complex components
  • You prefer all-in-one solution

Best Practices

Performance

// Lazy load heavy components
import { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./​HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</​div>}>
      <HeavyComponent />
    </​Suspense>
  );
}

Accessibility

// Konsta components are accessible by default
// Add labels for screen readers
<ListInput
  label="Email"
  type="email"
  placeholder="Enter email"
  // aria-label is automatically set from label
/>

// For icon-only buttons
<Button aria-label="Close menu">
  <Icon name="close" />
</​Button>

Resources

More skills from yeohj0710

vercel-composition-patterns logo
yeohj0710/wellnessbox

vercel-composition-patterns

Composition patterns for building flexible, maintainable React components. Avoid boolean prop proliferation by using compound components, lifting state, and composing internals. These patterns make codebases easier for both humans and AI agents to work with as they scale.

0 0
View

Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.

0 0
View
next-upgrade logo
yeohj0710/wellnessbox

next-upgrade

Upgrade Next.js to the latest version following official migration guides and codemods

0 0
View
capacitor-deep-linking logo
yeohj0710/wellnessbox

capacitor-deep-linking

Complete guide to implementing deep links and universal links in Capacitor apps. Covers iOS Universal Links, Android App Links, custom URL schemes, and navigation handling. Use this skill when users need to open their app from links.

0 0
View
tailwind-capacitor logo
yeohj0710/wellnessbox

tailwind-capacitor

Guide to using Tailwind CSS in Capacitor mobile apps. Covers mobile-first design, touch targets, safe areas, dark mode, and performance optimization. Use this skill when users want to style Capacitor apps with Tailwind.

0 0
View
vercel-deploy logo
yeohj0710/wellnessbox

vercel-deploy

Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".

0 0
View
capacitor-keyboard logo
yeohj0710/wellnessbox

capacitor-keyboard

Guide to handling keyboard in Capacitor apps including visibility detection, accessory bar, scroll behavior, and input focus. Use this skill when users have keyboard-related issues.

0 0
View
frontend-design logo
yeohj0710/wellnessbox

frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beaut...

0 0
View
ios-android-logs logo
yeohj0710/wellnessbox

ios-android-logs

Guide to accessing device logs on iOS and Android for Capacitor apps. Covers command-line tools, GUI applications, filtering, and real-time streaming. Use this skill when users need to view device logs for debugging.

0 0
View
vercel-react-native-skills logo
yeohj0710/wellnessbox

vercel-react-native-skills

Comprehensive best practices for React Native and Expo applications. Contains rules across multiple categories covering performance, animations, UI patterns, and platform-specific optimizations.

0 0
View
capacitor-app-store logo
yeohj0710/wellnessbox

capacitor-app-store

Complete guide to publishing Capacitor apps to Apple App Store and Google Play Store. Covers app preparation, screenshots, metadata, review guidelines, and submission process. Use this skill when users are ready to publish their app.

0 0
View
develop-ai-functions-example logo
yeohj0710/wellnessbox

develop-ai-functions-example

Develop examples for AI SDK functions. Use when creating, running, or modifying examples under examples/ai-functions/src to validate provider support, demonstrate features, or create test fixtures.

0 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View