npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xtandard/lib

v0.5.3

Published

Lightweight, type-safe TypeScript utilities

Readme


Install

npm install @xtandard/lib

Release 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)); // true

Semver 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"); // false

IP 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(); // 65536

Strings 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-aligned operator), and compileFilters({ spec, filters, resolveDate }) lowers a request to a portable CompiledWhere AST. 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.ts asserts 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 typed dateField/textField/… spec builders (allow-list) + buildWhere.
  • The date kind is injected — its DST-aware resolveDate (→ [gte, lt)) and chip-label describeDate are 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/compileFilterNodeCompiledWhere (+ 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

License

MIT