@xtandard/lib
v0.5.3
Published
Lightweight, type-safe TypeScript utilities
Maintainers
Readme
Install
npm install @xtandard/libRelease process notes live in docs/RELEASING.md.
Entry Points
| Import | Description | Dependencies |
| -------------------------------------- | -------------------------------------------------------- | ------------------------------------ |
| @xtandard/lib | Core utilities (isomorphic, zero deps) | none |
| @xtandard/lib/interval | Generic Interval<T> (Guava Range) | none |
| @xtandard/lib/dinero | Money intervals (Interval of money) | dinero.js |
| @xtandard/lib/decimal | Exact-decimal intervals (decimal.js) | decimal.js |
| @xtandard/lib/big | Exact-decimal intervals (big.js) | big.js |
| @xtandard/lib/bignumber | Exact-decimal intervals (bignumber.js) | bignumber.js |
| @xtandard/lib/fraction | Exact-rational intervals (fraction.js) | fraction.js |
| @xtandard/lib/semver | Semantic-version range intervals | semver |
| @xtandard/lib/ip | IPv4/IPv6 address & CIDR intervals | ipaddr.js |
| @xtandard/lib/pagination | Pagination + keyset helpers | none |
| @xtandard/lib/pagination/drizzle | Drizzle adapter for pagination keysets | drizzle-orm |
| @xtandard/lib/pagination/drizzle-rqb | Drizzle RQB v2 keyset (where/orderBy objects) | none |
| @xtandard/lib/pagination/kysely | Kysely adapter for pagination keysets | kysely |
| @xtandard/lib/pagination/knex | Knex adapter for pagination keysets | none |
| @xtandard/lib/pagination/mongo | Mongo/Mongoose adapter for keysets | none |
| @xtandard/lib/pagination/prisma | Prisma adapter for pagination keysets | none |
| @xtandard/lib/filters | Filter model (types) + portable compiler + sort/describe | none |
| @xtandard/lib/filters/valibot | Ready-made valibot schemas for the model | valibot, @js-temporal/polyfill |
| @xtandard/lib/filters/zod | Ready-made Zod schemas for the model | zod, @js-temporal/polyfill |
| @xtandard/lib/filters/arktype | Ready-made ArkType schemas for the model | arktype, @js-temporal/polyfill |
| @xtandard/lib/filters/effect | Ready-made Effect schemas for the model | effect, @js-temporal/polyfill |
| @xtandard/lib/filters/drizzle | Drizzle WHERE builder + keyset from filters | drizzle-orm |
| @xtandard/lib/filters/drizzle-rqb | Drizzle RQB v2 where object from filters (db.query) | none |
| @xtandard/lib/filters/kysely | Kysely WHERE builder from filters | kysely |
| @xtandard/lib/filters/knex | Knex raw-SQL WHERE builder from filters | none |
| @xtandard/lib/filters/mongo | Mongo filter object from filters | none |
| @xtandard/lib/filters/prisma | Prisma where object from filters | none |
| @xtandard/lib/web | Browser/FormData utilities | none |
| @xtandard/lib/tanstack | nuqs-style URL query state (TanStack Router) | react, @tanstack/react-router |
| @xtandard/lib/tanstack/server | Framework-free parsers/serializer/loader | none |
| @xtandard/lib/tanstack/testing | Headless testing adapter (no router) | react |
| @xtandard/lib/tanstack/temporal | Temporal-kind URL parsers | @js-temporal/polyfill, valibot |
| @xtandard/lib/tanstack/rison | Rison value codec for parseAsCodec | @effective/rison, valibot |
| @xtandard/lib/ulid | Prefixed ULID generation + helpers | ulid |
| @xtandard/lib/temporal | Date/time/duration + Temporal intervals | @js-temporal/polyfill, itty-time |
| @xtandard/lib/dataloader | DataLoader factory | dataloader |
| @xtandard/lib/unstorage | Cache helpers with unstorage | unstorage, ohash |
| @xtandard/lib/valibot | Branded TimeZone schema (valibot) | valibot |
| @xtandard/lib/zod | Branded TimeZone schema (Zod) | zod |
| @xtandard/lib/arktype | Branded TimeZone schema (ArkType) | arktype |
| @xtandard/lib/effect | Branded TimeZone schema (Effect) | effect |
| @xtandard/lib/sonner | Toast streaming for iterables | sonner, react |
| @xtandard/lib/react | React hooks + components | react, @tanstack/react-query |
Sub-entry dependencies are optional peer deps — only install what you use.
Core Utilities (@xtandard/lib)
Error Handling
| Export | Description | Source | Tests |
| --------------------------- | -------------------------------------------- | ------------------------------- | --------------------------------------- |
| tryCatch | [data, error] tuples — sync/async adaptive | src | tests |
| tryCatchSync (deprecated) | Use tryCatch — kept for backwards compat | src | tests |
| assertNotNull | Throws if null/undefined, narrows type | src | tests |
| valueOrThrow | Returns value or throws | src | tests |
| AssertError | Custom error class | src | tests |
Async
| Export | Description | Source | Tests |
| --------------------- | ---------------------------------------- | ------------------------------------- | --------------------------------------------- |
| wait | Typed setTimeout delay | src | tests |
| Completer | Externally resolvable Promise | src | tests |
| collect | Drain any iterable into T[] (adaptive) | src | tests |
| asyncOf | Create AsyncGenerator from values | src | tests |
| AsyncChannel | Push-based AsyncIterable with modes | src | tests |
| resolveMaybePromise | Resolve T \| Promise<T> → Promise<T> | src | tests |
Iterables & Generators
| Export | Description | Source | Tests |
| --------------------- | --------------------------------------------------- | --------------------------------- | ----------------------------------------- |
| range / rangeLazy | Numeric range (array / generator) | src | tests |
| enumerate | [index, value] tuples — sync/async adaptive | src | tests |
| enumerateAsync | Always-async; awaits Promise values in sync sources | src | tests |
| toIterator | Normalize to Iterator | src | tests |
| toAsyncIterable | Normalize to AsyncGenerator | src | tests |
Type Guards
| Export | Description | Source | Tests |
| --------------------------------------------------------- | ---------------------- | ---------------------------------- | ------------------------------------------ |
| isPromise | Promise-like check | src | tests |
| isIterable | Iterable check | src | tests |
| isAsyncIterable | AsyncIterable check | src | tests |
| isIterator | Iterator check | src | tests |
| isGenerator | Generator check | src | tests |
| isAsyncGenerator | AsyncGenerator check | src | tests |
| isDisposable / isAsyncDisposable / isSyncDisposable | Disposable checks | src | tests |
Disposable Utilities
| Export | Description | Source | Tests |
| --------------------- | --------------------------------------- | ------------------------------- | --------------------------------------- |
| defer / deferSync | Cancellable using/await using | src | tests |
| makeDisposable | Add Symbol.asyncDispose to any object | src | tests |
Strings
| Export | Description | Source | Tests |
| ------------------------------------------------------------- | ---------------- | ---------------------- | ------------------------------ |
| ensureString / naturalSortCompare / jaroWinklerDistance | String utilities | src | tests |
Misc
| Export | Description | Source | Tests |
| ------------------------------------------- | --------------------------------------- | ------------------------------------- | --------------------------------------------- |
| cast<T> | Unsafe as T type cast | src | tests |
| log | console.log that returns its argument | src | tests |
| prepareLoaderResult | Map DB rows to DataLoader key order | src | tests |
| resolveStreamSource | Resolve StreamSource<T> | src | tests |
| secondsToMs / minutesToMs / hoursToMs | Time unit converters | src | tests |
Interval Utilities (@xtandard/lib/interval)
A generic, immutable Interval<T> over any ordered type — modeled on Guava's
Range + DiscreteDomain. The engine knows nothing about T except through an
injected IntervalDomain<T> (compare, optional successor/measure/format/parse,
and the domain's ±∞ values). Zero dependencies. Full guide:
docs/INTERVAL.md.
import { NumberInterval, IntegerInterval } from "@xtandard/lib/interval";
const r = new NumberInterval({ start: 0, startClose: true, end: 10, endClose: false }); // [0,10)
r.contains(5); // true
r.union(NumberInterval.closedOpen(10, 20))?.toString(); // "[0,20)"
NumberInterval.parse("(-Infinity,5]").contains(-3); // true
// discrete domains merge epsilon-adjacent ranges:
IntegerInterval.closed(1, 5).union(IntegerInterval.closed(6, 10))?.toString(); // "[1,10]"| Export | Description | Source | Tests |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -------------------------------- | ---------------------------------------- |
| Interval | Immutable interval engine (set algebra over a domain) | src | tests |
| defineIntervalType | Bind a domain → new-able interval class + statics | src | tests |
| parseInterval / mergeIntervals | Parse [a,b) strings; merge a bag into disjoint pieces | src | tests |
| numberDomain / integerDomain / bigIntDomain / dateDomain / stringDomain | Built-in IntervalDomain<T>s (zero-dep) | src | tests |
| NumberInterval / IntegerInterval / BigIntInterval / DateInterval / StringInterval | Ready-to-use classes (incl. lexicographic strings) | src | tests |
| createOrdinalInterval(labels) | Discrete intervals over an ordered label list (enums) | src | tests |
Temporal intervals (@xtandard/lib/temporal, peer @js-temporal/polyfill) — the
same engine bound to the TC39 Temporal types:
InstantInterval, ZonedDateTimeInterval, PlainDateInterval (discrete, ε 1 day),
PlainDateTimeInterval, PlainTimeInterval (+ the matching instantDomain … exports).
Ordering/membership are nanosecond-exact; length()/middle() are millisecond-granular
(day-granular for PlainDate) — see docs/INTERVAL.md.
import { PlainTimeInterval, InstantInterval } from "@xtandard/lib/temporal";
import { Temporal } from "@js-temporal/polyfill";
const shift = PlainTimeInterval.closedOpen(
Temporal.PlainTime.from("09:00"),
Temporal.PlainTime.from("17:00"),
);
shift.contains(Temporal.PlainTime.from("12:30")); // true
shift.length(); // 28_800_000 (ms = 8h)Money intervals (@xtandard/lib/dinero, peer dinero.js) — the engine bound to
dinero.js v2 values, discrete with the epsilon being one minor unit (1 cent for
USD, 1 yen for JPY) so adjacent ranges merge and length() counts amounts. Build a
class per currency with createDineroInterval(currency) — see
docs/INTERVAL.md.
import { createDineroInterval } from "@xtandard/lib/dinero";
import { dinero, USD } from "dinero.js";
const UsdInterval = createDineroInterval(USD);
const tier = UsdInterval.closed(
dinero({ amount: 5_000, currency: USD }),
dinero({ amount: 10_000, currency: USD }),
);
tier.contains(dinero({ amount: 7_500, currency: USD })); // true ($75 ∈ [$50, $100])
tier.toString(); // "[5000,10000]" (minor units)Decimal intervals (@xtandard/lib/decimal, peer decimal.js) — an exact, continuous
alternative to NumberInterval when IEEE-754 float fuzz is unacceptable. Ordering,
membership, and the string form are exact arbitrary-precision; see
docs/INTERVAL.md.
import { DecimalInterval } from "@xtandard/lib/decimal";
import Decimal from "decimal.js";
DecimalInterval.closed(new Decimal("0.1"), new Decimal("0.3")).length(); // 0.2 (not 0.19999999999999998)
DecimalInterval.closed(new Decimal("0.1"), new Decimal("0.3")).toString(); // "[0.1,0.3]"Same exact-decimal model, different backing library (pick the one you already use):
@xtandard/lib/big (BigInterval, peer big.js — smaller) and @xtandard/lib/bignumber
(BigNumberInterval, peer bignumber.js).
Fraction intervals (@xtandard/lib/fraction, peer fraction.js) — exact rationals:
1/3 is lossless (never rounds, even where decimals can't) and renders as "1/3". See
docs/INTERVAL.md.
import { FractionInterval } from "@xtandard/lib/fraction";
import Fraction from "fraction.js";
const third = (n: number) => new Fraction(n, 3);
FractionInterval.closed(third(1), third(2)).toString(); // "[1/3,2/3]"
FractionInterval.closed(third(1), third(2)).contains(new Fraction(1, 2)); // trueSemver intervals (@xtandard/lib/semver, peer semver) — a version range IS an interval
([">=1.2.0","<2.0.0")). Exact precedence ordering; see
docs/INTERVAL.md.
import { SemverInterval } from "@xtandard/lib/semver";
const compatible = SemverInterval.closedOpen("1.2.0", "2.0.0");
compatible.contains("1.5.3"); // true
compatible.contains("2.0.0"); // falseIP intervals (@xtandard/lib/ip, peer ipaddr.js) — IPv4/IPv6 ranges, discrete (ε = one
address), CIDR-aware. See docs/INTERVAL.md.
import { Ipv4Interval } from "@xtandard/lib/ip";
const lan = Ipv4Interval.cidr("192.168.0.0/16");
lan.contains(Ipv4Interval.ip("192.168.1.50")); // true
lan.length(); // 65536Strings and ordered enums need no extra dependency — StringInterval (lexicographic) and
createOrdinalInterval([...]) (ordered labels) ship in @xtandard/lib/interval.
Pagination Utilities (@xtandard/lib/pagination)
Source-agnostic pagination: import from @xtandard/lib/pagination, provide fetchers for your data source (SQL, Drizzle, Prisma, Mongoose, HTTP...), and the paginator handles input styles (page/pageSize, limit/offset, cursor), hasNextPage lookahead, backward (scroll-up) pagination, and a uniform result envelope. Full guide: docs/PAGINATION.md — backend recipes for SQL drivers, ORMs/query builders, Mongo, Firestore, DynamoDB, Redis sorted sets, Elasticsearch/OpenSearch, analytics warehouses, HTTP APIs, REST/GraphQL endpoints, cursor codecs, and frontend integration.
Sync/async adaptive: pass all-sync fetchers and codec (e.g. an in-memory array) and paginate() returns plain values — no await needed; any async piece (even just an async cursor encoder) makes results Promises, reflected in the types. The pattern is documented in docs/sync-async-adaptive.md.
| Import | Export | Description | Source | Tests |
| -------------------------------------- | --------------------------- | -------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------- |
| @xtandard/lib/pagination | createPaginator | Paginator over user-provided fetchers; pages()/items() async iteration | src | tests |
| @xtandard/lib/pagination | toOffsetWindow | Page/offset input → { limit, offset } | src | tests |
| @xtandard/lib/pagination | createCursorCodec | Pluggable opaque-cursor codec (JSON + base64url) | src | tests |
| @xtandard/lib/pagination | createKeysetSpec | Portable keyset where()/orderBy() AST | src | tests |
| @xtandard/lib/pagination | keysetSqlExpression | Mark server-owned computed SQL expressions for raw keyset helpers | src | tests |
| @xtandard/lib/pagination | toKeysetWhereSql | Keyset WHERE → parameterized SQL + params | src | tests |
| @xtandard/lib/pagination | toKeysetOrderBySql | Keyset order → SQL ORDER BY fragment | src | tests |
| @xtandard/lib/pagination/drizzle | toDrizzleKeyset | Keyset AST → Drizzle where/orderBy helpers | src | tests |
| @xtandard/lib/pagination/drizzle-rqb | toDrizzleRqbKeyset | Keyset AST → Drizzle RQB v2 where/orderBy objects (db.query) | src | tests |
| @xtandard/lib/pagination/kysely | toKyselyKeyset | Keyset AST → Kysely where/orderBy helpers | src | tests |
| @xtandard/lib/pagination/knex | applyKeysetToKnex | Apply keyset AST to Knex whereRaw/orderByRaw | src | tests |
| @xtandard/lib/pagination/mongo | toMongoKeyset | Keyset AST → Mongo/Mongoose filter/sort objects | src | tests |
| @xtandard/lib/pagination/prisma | toPrismaKeyset | Keyset AST → Prisma where/orderBy objects | src | tests |
| @xtandard/lib/pagination | parsePaginationParams | Query params → PaginationInput (with clamping) | src | tests |
| @xtandard/lib/pagination | fromRelayArgs | Relay first/after/last/before → input | src | tests |
| @xtandard/lib/pagination | toRelayConnection | Result → Relay connection (edges, pageInfo) | src | tests |
| @xtandard/lib/pagination | toRestEnvelope | Result → { data, meta } REST envelope | src | tests |
| @xtandard/lib/pagination | infinitePaginationOptions | TanStack useInfiniteQuery config (dep-free) | src | tests |
import {
createPaginator,
fromRelayArgs,
parsePaginationParams,
toRestEnvelope,
} from "@xtandard/lib/pagination";
const paginator = createPaginator({
fetchOffset: ({ limit, offset }) => ({ items: db.query(/* LIMIT/OFFSET */) }),
fetchCursor: ({ limit, cursor, direction }) => ({ items: db.query(/* keyset */) }),
cursor: { fromItem: (u) => ({ id: u.id }) }, // codec optional — defaults to JSON + base64url
maxLimit: 100,
});
// REST route
const result = await paginator.paginate(parsePaginationParams(url.searchParams));
return Response.json(toRestEnvelope(result));
// GraphQL/Relay resolver
const result = await paginator.paginate(fromRelayArgs(args));
return toRelayConnection(result, paginator.cursorFor);Cursor tokens are produced by a two-stage codec (serializer + encoder, both replaceable) signature-compatible with drizzle-cursor, so the same custom encoder/decoder (encryption, signing...) can be shared between both.
Web Utilities (@xtandard/lib/web)
| Export | Description | Source | Tests |
| ----------------------- | ----------------------------------- | ----------------------------------------- | ------------------------------------------- |
| formDataToObject | FormData → plain object | src | tests |
| fetchWithProgress | Fetch with upload/download progress | src | tests |
| createHttpInterceptor | Intercept fetch + XHR with rules | src | tests |
Sonner Utilities (@xtandard/lib/sonner)
Toast helpers for streaming iterables/generators through Sonner.
| Export | Description | Source | Tests |
| ------------------ | ----------------------------------------------------------------------- | ---------------------------- | ------------------------------------ |
| toastStream | Blocking/awaitable stream toast; resolves to { items, returnValue } | src | tests |
| toastStreamAsync | Non-blocking stream toast; returns toast id immediately with unwrap() | src | tests |
Use toastStream when the caller should wait for completion:
import { toastStream } from "@xtandard/lib/sonner";
const { items, returnValue } = await toastStream(source, {
loading: "Loading...",
streaming: ({ count }) => `Received ${count}`,
success: ({ count }) => `Done: ${count} items`,
});Use toastStreamAsync when the caller should continue immediately, matching
Sonner's toast.promise(...).unwrap() style:
import { toastStreamAsync } from "@xtandard/lib/sonner";
const toastId = toastStreamAsync(source, { loading: "Loading..." });
const { items, returnValue } = await toastId.unwrap();React Utilities (@xtandard/lib/react)
| Export | Description | Source | Tests |
| ------------------------------ | ----------------------------------- | -------------------------------------- | ----------------------------------------------- |
| Providers / provider | Compose providers without nesting | src | tests |
| usePreventAutoFocus | Prevent auto-focus in modals | src | tests |
| useDynamicRefs | Dynamic ref registry by key | src | tests |
| useStream / StreamRenderer | Stream consumption hook + component | src | tests |
TanStack URL State (@xtandard/lib/tanstack)
nuqs-style, component-owned URL query state for TanStack Router (and Start).
useQueryState behaves like useState, but backed by the URL — reusable
components own "their" query key without importing a route object. Per-key
parsers, an optimistic store, rate-limited URL commits, shallow-by-default
updates, atomic multi-key batching, a framework-free server/loader/serializer
core, and a validateSearch-ready Standard Schema. Full guide:
docs/TANSTACK.md.
import { NuqsAdapter, useQueryState, parseAsInteger } from "@xtandard/lib/tanstack";
// once, inside RouterProvider (e.g. your __root route component):
<NuqsAdapter>{/* app */}</NuqsAdapter>;
function Pagination() {
const [page, setPage] = useQueryState("page", parseAsInteger.withDefault(1));
return <button onClick={() => setPage((p) => p + 1)}>Next</button>; // setPage(null) removes the key
}| Import | Export | Description | Source |
| --------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------ | -------------------------------------------------- |
| @xtandard/lib/tanstack | useQueryState / useQueryStates / useUrlSearchString | nuqs-style hooks backed by the URL | src |
| @xtandard/lib/tanstack | NuqsAdapter / TanStackQueryStateAdapter | Bridges the store to TanStack Router | src |
| @xtandard/lib/tanstack | parseAs* (15 built-ins) / createParser / parseAsCodec / withTransport | Per-key parsers + custom codec/transport combinators | src |
| @xtandard/lib/tanstack/server | createLoader / createSerializer / createStandardSchemaV1 | Framework-free (loaders, validateSearch, server fns) | src |
| @xtandard/lib/tanstack/testing | QueryStateTestingAdapter | Drive hooks from a static search string, no router | src |
| @xtandard/lib/tanstack/temporal | parseAsInstant / parseAsPlainDate / … / parseAsTimeZone | URL parsers for the six Temporal kinds | src |
| @xtandard/lib/tanstack/rison | risonCodec | Readable, canonical Rison codec for parseAsCodec | src |
keepSubDelims (keep ( ) , : ! ' raw in the address bar, e.g. for Rison
tokens) lives in @xtandard/lib/web and is also
re-exported from @xtandard/lib/tanstack.
Filters (@xtandard/lib/filters)
One typed filter system spanning frontend ↔ API ↔ any query builder, built like
pagination: a portable core + per-driver adapters. Full guide:
docs/FILTERS.md.
- Core (
@xtandard/lib/filters) is validation-library-free and driver-free: the model is plain TS types (a two-level discriminated union —kind× Drizzle-alignedoperator), andcompileFilters({ spec, filters, resolveDate })lowers a request to a portableCompiledWhereAST. Validate the request with whatever you use (valibot/zod/arktype/effect/…) — the core never imports one. - Validation (optional): ready-made schemas for valibot, Zod, ArkType, and
Effect at
@xtandard/lib/filters/{valibot,zod,arktype,effect}that validate into the model types (a*.test-d.tsasserts each one has no drift). Or bring your own Standard Schema. - Adapters render the AST per driver:
@xtandard/lib/filters/{drizzle,kysely,knex,mongo,prisma}— each with typeddateField/textField/… spec builders (allow-list) +buildWhere. - The
datekind is injected — its DST-awareresolveDate(→[gte, lt)) and chip-labeldescribeDateare passed in, so no date library is bundled.
import { FiltersRequestSchema } from "@xtandard/lib/filters/valibot"; // optional validation
import { buildWhere, textField, numberField, dateField } from "@xtandard/lib/filters/drizzle";
import * as v from "valibot";
const filters = v.parse(FiltersRequestSchema, await req.json());
const spec = {
name: textField({ column: t.name }),
amount: numberField({ column: t.amount }),
createdAt: dateField({ column: t.createdAt }),
};
const { where } = buildWhere({ spec, filters, resolveDate }); // resolveDate injected for `date`
db.select().from(t).where(where);| Import | Export | Source |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| @xtandard/lib/filters | model types (FieldFilter/ColumnFilter/FilterNode/DatePreset/…) | src |
| @xtandard/lib/filters | compileFilters/compileFilterNode → CompiledWhere (+ DateFilterResolver) | src |
| @xtandard/lib/filters | *_OPERATORS / OPERATORS_BY_KIND / parseSortParam / describeFieldFilter / ResourceMetadata | src |
| @xtandard/lib/filters/{valibot,zod,arktype,effect} | FieldFilterSchema / FiltersRequestSchema / FilterNodeSchema / SortSchema (same names per validator) | src |
| @xtandard/lib/filters/drizzle | buildWhere/buildFilterNode, dateField/…, buildOrderBy, createDrizzleKeyset | src |
| @xtandard/lib/filters/drizzle-rqb | buildWhere/buildFilterNode → RQB v2 where object (db.query), dateField/… | src |
| @xtandard/lib/filters/kysely | buildWhere/buildOrderBy (+ toKyselyWhere) | src |
| @xtandard/lib/filters/knex | buildWhereSql/applyFiltersToKnex (raw, parameterized) | src |
| @xtandard/lib/filters/mongo | buildFilter → Mongo filter object | src |
| @xtandard/lib/filters/prisma | buildWhere → Prisma where object | src |
Recommended Libraries
These are libraries we use and recommend. They're not re-exported — install them directly:
| Library | Description | | -------------------------------------------------------------------------- | ------------------------------------ | | es-toolkit | Modern lodash alternative | | ohash | Object hashing | | unstorage | Universal key-value storage | | cockatiel | Retry / circuit breaker / bulkhead | | chroma-js | Color manipulation | | xbytes | Byte size formatting | | etiket | Barcode generation | | portakal | Printer / ESC/POS | | hucre | Spreadsheet utilities | | @gobrand/tiempo | Time formatting / parsing | | dinero.js | Immutable, type-safe money handling | | decimal.js | Arbitrary-precision decimals | | big.js | Minimalist arbitrary-precision dec. | | bignumber.js | Arbitrary-precision decimals/bases | | fraction.js | Exact rational numbers | | semver | Semantic version parsing/compare | | ipaddr.js | IPv4/IPv6 address parsing | | tactus | Haptic feedback for web | | liveline | Animated line charts (React) | | react-lzy-img | Lazy loading images (React) | | masonic | Virtualized masonry layout (React) | | p-map | Concurrent async mapping | | motion | Animation library (React) | | tailwind-merge | Merge Tailwind classes | | lucide-react | Icon library (React) | | jotai | Atomic state management (React) | | permix | Permission management | | std-env | Runtime environment detection | | ufo | URL utilities | | @total-typescript/ts-reset | Stricter TypeScript defaults | | better-auth | Authentication framework | | drizzle-orm | TypeScript ORM | | drizzle-cursor | Cursor-based pagination for Drizzle | | drizzle-audit | Audit logging for Drizzle | | elysia | Bun-first web framework | | hono | Lightweight web framework | | inngest | Background jobs + durable functions | | stripe | Payment processing | | paykit | Payment toolkit for Stripe | | @tanstack/react-query | Async state management (React) | | @tanstack/react-table | Headless table (React) | | @tanstack/react-form | Form management (React) | | @tanstack/react-virtual | Virtualized lists (React) | | ai | Vercel AI SDK | | graphql-yoga | GraphQL server | | pothos | GraphQL schema builder | | react-router | Routing (React) | | class-variance-authority | Component variant classes | | clsx | Conditional classnames | | next-themes | Theme management (React) | | react-email | Email templates (React) | | @uppy/core | File upload | | dotenv | Environment variables | | citty | CLI framework | | evlog | Event logging | | @electric-sql/pglite | In-memory PostgreSQL | | neverthrow | Type-safe Result type | | ts-pattern | Exhaustive pattern matching | | nanoid | Tiny unique ID generator | | superjson | Serialize Date, Map, Set via JSON | | destr | Safe, fast JSON.parse alternative | | dequal | Tiny deep equality check | | klona | Tiny deep clone | | mutative | Fast immutable updates (like Immer) | | ofetch | Better fetch with retries + parsing | | ky | Tiny fetch-based HTTP client | | consola | Elegant structured logger | | p-queue | Promise queue with concurrency | | croner | Cron scheduler (Node + browser) | | oslo | Auth utilities (TOTP, JWT, hashing) | | arctic | OAuth 2.0 provider integrations | | casl | Isomorphic authorization | | unctx | Composables via AsyncLocalStorage | | execa | Better child_process | | knip | Find unused code + dependencies | | clack | Beautiful CLI prompts + spinners | | sonner | Toast notifications (React) | | vaul | Drawer component (React) | | cmdk | Command menu (React) | | embla-carousel | Lightweight carousel | | dnd-kit | Drag and drop toolkit (React) | | nuqs | Type-safe URL search params (React) | | @tanstack/react-router | Type-safe file-based routing (React) | | @effective/rison | URL-friendly JSON encoding (Rison) | | react-error-boundary | Error boundary component (React) | | react-hotkeys-hook | Keyboard shortcuts hook (React) | | auto-animate | Zero-config DOM animations | | satori | JSX/HTML to SVG (OG images) | | orama | In-memory full-text + vector search | | gql.tada | Typed GraphQL documents at compile | | kysely | Type-safe SQL query builder | | currency.js | Safe currency arithmetic | | thumbhash | Image placeholder algorithm | | noble-hashes | Audited crypto hashes (pure TS) | | better-all | Better Promise.all with named keys | | better-result | Rust-like Result type for TS | | fuse.js | Lightweight fuzzy search | | files-sdk | Unified file storage SDK | | streamdown | Stream Markdown rendering | | ai-elements | AI-powered UI components | | tiptap | Headless rich text editor | | better-notify | Notification management | | @vercel/chat | Chat UI components | | @vercel/workflow | Durable workflow engine | | trigger.dev | Background jobs platform | | temporal | Durable workflow orchestration | | @vercel/sandbox | Code sandbox execution | | reactflow | Node-based graph editor (React) | | date-fns | Modern date utility library | | cheerio | Fast HTML parsing + manipulation | | dexie | IndexedDB wrapper with clean API |
See Also
- drizzle-cursor — Cursor-based pagination for Drizzle ORM
- drizzle-audit — Configurable audit logging for Drizzle ORM
License
MIT
