Introduction
What the library is, who it is for and how it is organized.
@akhatmirzo is a toolkit for React apps that speak Uzbek: components, design tokens, hooks and
utility functions. Phone numbers come out as +998 90 123 45 67, amounts as 1 250 000 so'm,
search treats "Gʻuzor", "G'uzor" and "Ғузор" as the same word, and the calendar starts on Monday.
All of this works out of the box, so you stop rewriting it in every project.
Sinab ko'ring: chir, ғуз, fargona, qo'qon
- Shahrisabz
- Шаҳрихон
'use client';
import { searchMatch, splitByRanges } from '@akhatmirzo/core';
import { Field, Input } from '@akhatmirzo/ui';
import { useState } from 'react';
const CITIES = [
'Toshkent',
'Samarqand',
'Buxoro',
"Farg'ona",
'Qo‘qon',
'Shahrisabz',
'Chirchiq',
'Ғузор',
'Ўрта Чирчиқ',
'Шаҳрихон',
];
export default function CoreSearch() {
const [query, setQuery] = useState('шаҳ');
const results = CITIES.map((city) => ({ city, ...searchMatch(city, query) })).filter(
(r) => r.match,
);
return (
<div className="flex w-full max-w-md flex-col gap-3">
<Field label="Shahar qidirish" description="Sinab ko'ring: chir, ғуз, fargona, qo'qon">
<Input value={query} onChange={(e) => setQuery(e.target.value)} clearable />
</Field>
<ul className="flex flex-wrap gap-2">
{results.map(({ city, ranges }) => (
<li key={city} className="rounded-lg border border-border bg-surface px-3 py-1.5 text-sm">
{splitByRanges(city, ranges).map((part, i) =>
part.match ? (
<mark key={i} className="rounded-sm bg-primary-soft text-primary-soft-foreground">
{part.text}
</mark>
) : (
<span key={i}>{part.text}</span>
),
)}
</li>
))}
{results.length === 0 && <li className="text-sm text-text-muted">Hech narsa topilmadi</li>}
</ul>
</div>
);
}
The search above is a single function from @akhatmirzo/core. A Cyrillic query finds Latin
names and vice versa, and the matched part is highlighted in the original text.
Principles
- Built for Uzbek. Built-in labels, month and weekday names are in Uzbek. There are ready
fields for phones (
+998), Uzcard and Humo cards and amounts in so'm. Search ignores the difference between Latin and Cyrillic and between every apostrophe variant ('ʻ‘’). - Accessible. Overlays, menus and tabs sit on top of Radix UI,
so focus management, keyboard support and ARIA come for free.
Fieldwires the label, description and error message to its control automatically. - One rule, one place. Colors only come from semantic tokens (
bg-surface,text-text-muted). Dark mode and the brand color change in a single CSS file — the components stay untouched. - A consistent API. Every control takes
size="sm" | "md" | "lg"(32 / 40 / 48px), a controlled value isvalue+onValueChange, open state isopen+onOpenChange. Learn one component and you can guess the rest. - No dead weight. The packages are ESM with
sideEffects: false, so only what you import ends up in your bundle. Your own Tailwind build generates the CSS — there is no runtime CSS-in-JS.
Packages
The toolkit ships as four independent packages. They live in one repository, but you install and version them separately.
| Package | What you get | Dependencies |
|---|---|---|
@akhatmirzo/ui | 32 component families: forms, overlays, tables, calendar | Radix, TanStack, cmdk, react-day-picker |
@akhatmirzo/tokens | Colors, typography, radii, shadows, motion — CSS and Tailwind | none (CSS only) |
@akhatmirzo/core | Formatting, validation, text, storage, API client | none, not even React |
@akhatmirzo/hooks | 12 React hooks: useDebounce, useHotkeys and more | react only |
@akhatmirzo/ui builds on the other three, but not the other way around: you can run core on a
server or in another framework, and use hooks without any components.
When to use
- Products for Uzbekistan — admin panels, CRMs, internal tools, online stores. Phones, cards, so'm, dates and Uzbek-aware search are small jobs that eat time; here they are done.
- React + Tailwind CSS v4 projects. Components are styled with Tailwind classes and compiled by your Tailwind build.
- When you only need the functions — install
@akhatmirzo/coreon its own. It has no React and no dependencies, and it runs in Node.js too. - When it is not a fit: projects without Tailwind (components render unstyled) and React Native — only the web is supported for now.
Status
The current version is 0.1.0, published on npm under the MIT license. While the version starts
with 0., the API can still change: a minor release (0.1 → 0.2) may include breaking changes.
See Versions for details.