Getting Started
Build point-of-sale systems with composable UI primitives
Tally UI is an open-source library of composable UI components designed for building point-of-sale systems. It works with any backend through a pluggable connector system.
How It Works
Tally UI sits between your backend API and your UI. A connector maps each backend's data shape into a standard trait interface that components consume.
┌─────────────────────────────────────┐
│ UI Components │
│ <ProductTitle> <ProductPrice> ... │
└──────────────┬──────────────────────┘
│ uses traits
┌──────────────▼──────────────────────┐
│ Trait Layer │
│ getName() getPrice() getSku() ... │
└──────────────┬──────────────────────┘
│ implemented by
┌──────────────▼──────────────────────┐
│ Connector │
│ WooCommerce │ Medusa │ Vendure ... │
└──────────────┬──────────────────────┘
│ syncs with
┌──────────────▼──────────────────────┐
│ RxDB (Local Database) │
│ Offline-first, reactive │
└─────────────────────────────────────┘Quick Start
Install the core packages and a connector:
pnpm add @tallyui/core @tallyui/database @tallyui/components @tallyui/theme @tallyui/connector-woocommerceWrap your app with the connector provider:
import { useMemo } from 'react';
import { ConnectorProvider } from '@tallyui/core';
import { createWooCommerceConnector } from '@tallyui/connector-woocommerce';
function App({ session }: { session: object }) {
// One connector per store session: a new one on each sign-in or store change.
const connector = useMemo(() => createWooCommerceConnector(), [session]);
return (
<ConnectorProvider connector={connector}>
<YourPOSApp />
</ConnectorProvider>
);
}Use components that work with any backend. Style with Tailwind classes via Uniwind:
import { ProductTitle, ProductPrice } from '@tallyui/components';
function ProductCard({ doc }) {
return (
<View className="bg-card rounded-lg p-4 gap-1">
<ProductTitle doc={doc} className="text-lg font-bold" />
<ProductPrice doc={doc} currencySymbol="$" />
</View>
);
}