Package Exports
- @prokodo/ui
- @prokodo/ui/accordion
- @prokodo/ui/animated
- @prokodo/ui/animatedText
- @prokodo/ui/avatar
- @prokodo/ui/base-link
- @prokodo/ui/button
- @prokodo/ui/calendly
- @prokodo/ui/card
- @prokodo/ui/carousel
- @prokodo/ui/chip
- @prokodo/ui/createIsland
- @prokodo/ui/createLazyWrapper
- @prokodo/ui/datePicker
- @prokodo/ui/dialog
- @prokodo/ui/drawer
- @prokodo/ui/dynamic-list
- @prokodo/ui/form
- @prokodo/ui/grid
- @prokodo/ui/headline
- @prokodo/ui/icon
- @prokodo/ui/image
- @prokodo/ui/image-text
- @prokodo/ui/input
- @prokodo/ui/inputOTP
- @prokodo/ui/label
- @prokodo/ui/link
- @prokodo/ui/list
- @prokodo/ui/loading
- @prokodo/ui/lottie
- @prokodo/ui/map
- @prokodo/ui/post-item
- @prokodo/ui/post-teaser
- @prokodo/ui/post-widget
- @prokodo/ui/post-widget-carousel
- @prokodo/ui/progressBar
- @prokodo/ui/quote
- @prokodo/ui/rich-text
- @prokodo/ui/select
- @prokodo/ui/sidenav
- @prokodo/ui/skeleton
- @prokodo/ui/slider
- @prokodo/ui/snackbar
- @prokodo/ui/stepper
- @prokodo/ui/switch
- @prokodo/ui/table
- @prokodo/ui/teaser
- @prokodo/ui/theme.css
Readme
prokodo UI (Beta)
Empowering Digital Innovation
Modern, customizable UI components built with React and TypeScript — developed by prokodo for high-performance web interfaces.
🇺🇸 Need help shipping production Next.js (App Router) fast?
prokodo — Next.js Agency → click here🇩🇪 Sie suchen eine Next.js Agentur (App Router, SEO, Performance)?
prokodo — Next.js Agentur → hier klicken
Further reading: Next.js guides (SEO · Performance · Migration)
SEO (Metadata API, hreflang):
https://www.prokodo.com/en/guide/next-js/next-js-seo/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=seo_enPerformance (LCP/INP/CLS, Streaming SSR):
https://www.prokodo.com/en/guide/next-js/next-js-performance/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=perf_enMigration Playbook (RACI, Canary, Rollback):
https://www.prokodo.com/en/guide/next-js/next-js-migration/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=migration_en
✨ Features
- ✨ Adaptive Island Components (AIC): A rendering strategy where each component loads only the JavaScript it needs — when needed.
- ⚡️ Modern stack: Vite, React 19, TypeScript, and SCSS Modules
- 💅 Design consistency: Theming via design tokens and BEM-style naming
- 🧩 Component-rich: 40+ reusable UI components
- 🧪 Reliable: Fully tested with Jest and Testing Library
- 📚 Storybook: Explore the components at ui.prokodo.com
- 📦 Ready-to-install: Distributed via npm for non-production use under the BUSL-1.1 license
- 🧱 Optimized for SSR: Works great with Next.js and React Server Components
⚡ Lightweight by Design
Adaptive Island Components (AIC) are fully modular and optimized for modern frameworks (Next.js, Remix, etc.).
Each component is built for lazy loading, works seamlessly with React Server Components (RSC), and can be tree-shaken out when unused.
Total bundle (all components): ~195 kB gzipped
- Only 5–20 kB are typically loaded per page
- Zero-JS on initial render for most components
- Hydration is deferred until interaction or visibility
- Shared styles are minimal: only ~16.5 kB gzipped
This makes @prokodo/ui ideal for modern SSR apps using Next.js or Remix, with excellent Time-to-Interactive (TTI) and Core Web Vitals.
🚀 Getting Started
1. Install the package
⚠️ ESM-only: This package does not support CommonJS (
require()).
pnpm add @prokodo/ui
# or
npm install @prokodo/ui2. Use a component
React
import { Button, type ButtonProps } from "@prokodo/ui/button"
export default function Layout() {
// Renders to HTML on the server with zero‐JS.
// On the client, it will hydrate when scrolled into view or the user interacts.
return <Button title="Click me" />
}Next.js (RSC + AIC, lazy‐hydrate when visible/interacted)
import { Button, type ButtonProps } from "@prokodo/ui/button"
export default function Layout() {
// Renders to HTML on the server with zero‐JS.
// On the client, it will hydrate when scrolled into view or the user interacts.
return <Button title="Click me" />
}Next.js (RSC + AIC, force immediate hydration with priority)
import { Button, type ButtonProps } from "@prokodo/ui/button"
export default function AboveTheFoldHero() {
// Because this lives above the fold, we want it to hydrate right away:
return <Button priority title="Welcome to prokodo" />
}Next.js ("use client" wrapper, immediate hydration - above the fold)
"use client"
import { Button, type ButtonProps } from "@prokodo/ui/button"
import { type FC, memo } from "react"
// In a pure‐client file, you can wrap the AIC export.
// The `priority` prop here ensures hydration runs immediately when mounted.
export const HeadlineClient: FC<ButtonProps> = memo(props => {
return <Button {...props} priority />
})Next.js (hydrate on visibility only, default behavior)
import { Headline, type ButtonProps } from "@prokodo/ui/button"
export default function GalleryPage() {
return (
<div style={{ height: "200vh" }}>
<p>Keep scrolling…</p>
<div style={{ marginTop: "100vh" }}>
{/* This will render as HTML on the server;
on the client, it only hydrates when this element scrolls into view. */}
<Button title="I hydrate when you see me" />
</div>
</div>
)
}📦 Available Components
Compatibility of the components
- ✅ = Available as AIC (renders zero-JS RSC and self-hydrates when needed) and can also be used as a client‐only entry.
- - = RSC (AIC) only; no client‐side bundle needed. (Usable in both, but best practice to use in RSC only)
| Component | ✅ AIC (RSC + optional client) | ✅ SSR-Compatible ("use client") |
|---|---|---|
| Accordion | ✅ | ✅ |
| Animated | ✅ | ✅ |
| AnimatedText | ✅ | ✅ |
| Avatar | ✅ | ✅ |
| BaseLink | ✅ | ✅ |
| Button | ✅ | ✅ |
| Calendly | ✅ | ✅ |
| Card | ✅ | ✅ |
| Carousel | ✅ | ✅ |
| Chip | ✅ | ✅ |
| DatePicker | ✅ | ✅ |
| Dialog | ✅ | ✅ |
| Drawer | ✅ | ✅ |
| DynamicList | ✅ | ✅ |
| Form | ✅ | ✅ |
| FormResponse | ✅ | – |
| Grid/GridRow | ✅ | – |
| Headline | ✅ | - |
| Icon | ✅ | – |
| Image | ✅ | – |
| ImageText | ✅ | - |
| Input | ✅ | ✅ |
| Label | ✅ | – |
| Link | ✅ | ✅ |
| List | ✅ | – |
| Loading | ✅ | – |
| Lottie | ❌ | ✅ |
| Map | ❌ | ✅ |
| PostItem | ✅ | ✅ |
| PostTeaser | ✅ | ✅ |
| PostWidget | ✅ | ✅ |
| PostWidgetCarousel | ✅ | ✅ |
| ProgressBar | ✅ | ✅ |
| Quote | ✅ | – |
| RichText | ✅ | ✅ |
| Select | ✅ | ✅ |
| SideNav | ✅ | ✅ |
| Skeleton | ✅ | – |
| Slider | ✅ | ✅ |
| Snackbar & Provider | ✅ | ✅ |
| Stepper | ✅ | ✅ |
| Switch | ✅ | ✅ |
| Table | ✅ | – |
| Teaser | ✅ | - |
How to create my own Island Component?
1. Create your island component (Navbar.tsx):
Island architecture lets you render components on the server and hydrate them on the client only when needed.
import { createIsland } from "@prokodo/ui/createIsland"
import { NavbarServer } from "./Navbar.server"
import type { NavbarProps } from "./Navbar.model"
export const Navbar = createIsland<NavbarProps>({
name: "Navbar",
Server: NavbarServer,
loadLazy: () => import("./Navbar.lazy"),
// Optional: Force client-side hydration as soon as someone uses an action
// We are automatically recognizing onChange, onKeyDown, ... events. Only needed for custom attributes.
isInteractive: (p: NavbarProps) => p.customEvent === true,
})2. Create your lazy-hydrate wrapper (Navbar.lazy):
"use client"
import { createLazyWrapper } from "@prokodo/ui/createLazyWrapper"
import { NavbarClient } from "./Navbar.client"
import { NavbarServer } from "./Navbar.server"
import type { NavbarProps } from "./Navbar.model"
export default createLazyWrapper<NavbarProps>({
name: "Navbar",
Client: NavbarClient,
Server: NavbarServer,
// Optional: Defer hydration until the component becomes visible in the viewport (Default: true)
// Can be controlled by priority attribute.
hydrateOnVisible: false,
// Optional: Force client-side hydration as soon as someone uses an action.
// We are automatically recognizing onChange, onKeyDown, ... events. Only needed for custom attributes.
isInteractive: (p: NavbarProps) => p.customEvent === true,
})🎯 Next steps
- Add more ✨ fancy styling, UI polish and properties
- Improve accessibility to meet WCAG 2.2 AAA standards
- Detailed Documentation about the components
Examples (Next.js + Headless CMS)
Real-world setups we ship:
- Next.js + Strapi content models
- Next.js + Contentful entries & preview
- Migration from Headless WordPress to Next.js
Need help or a quick scoping?
- 🇺🇸 Next.js Agency (EN) → https://www.prokodo.com/en/next-js-agency/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=examples_cta_en
- 🇩🇪 Next.js Agentur (DE) → https://www.prokodo.com/de/next-js-agentur/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=examples_cta_de
Further reading: Next.js guides (SEO · Performance · Migration)
SEO (Metadata API, hreflang):
https://www.prokodo.com/en/guide/next-js/next-js-seo/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=seo_enPerformance (LCP/INP/CLS, Streaming SSR):
https://www.prokodo.com/en/guide/next-js/next-js-performance/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=perf_enMigration Playbook (RACI, Canary, Rollback):
https://www.prokodo.com/en/guide/next-js/next-js-migration/?utm_source=github&utm_medium=readme_examples&utm_campaign=ui&utm_content=migration_en
📘 Documentation
Explore all components and examples in the official Storybook:
🛠 Local Development
pnpm i
pnpm dev # Start Vite dev server
pnpm storybook # Start Storybook locallyTo build:
pnpm run build
pnpm run storybook:build📄 License
This library is published under the Business Source License 1.1 (BUSL-1.1).
© 2025 prokodo — All rights reserved. Visit us at prokodo.com.