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.
Specification
- Skill ID
- cap-go/capgo-skills/konsta-ui
- Publisher
- cap-go
- Repository
- capgo-skills
- Installs
- 0
- Files
- 2
- Synced
- Sep 23, 2026
How to use it
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
cap-go/capgo-skills/konsta-uiInstalls these files- SKILL.md
- metadata.json
What this skill tells the agent
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
npm install konsta
# Vue
npm install konsta
# Svelte
npm install konsta
# Required: Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -pTailwind 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>
</>
}
/>
More from cap-go
Use this skill in a project
Open any RiverX project, search the Skills panel for cap-go/capgo-skills/konsta-ui, and install it in one click.
