@billdaddy/qskit
v0.1.1
Published
Tiny, type-safe query string parse and stringify — array formats (bracket/index/comma/repeat) and number/boolean coercion. Zero dependencies.
Maintainers
Readme
qskit
Tiny, type-safe query string parse & stringify — multiple array formats (bracket / index / comma / repeat) and number/boolean coercion. Zero dependencies.
URLSearchParams is fine until you need arrays as tags[]=a&tags[]=b, numbers
that come back as numbers, or stable sorted output. qskit gives you parse and
stringify with the array conventions every backend uses and optional type
coercion — symmetric, predictable, and zero-dependency.
import { parse, stringify } from "@billdaddy/qskit";
parse("a=1&a=2&page=3"); // { a: ["1", "2"], page: "3" }
stringify({ tags: ["x", "y"] }); // "tags=x&tags=y"Why qskit?
- Symmetric
parse/stringify. The samearrayFormatround-trips cleanly. - Every array convention.
"none"(repeat keys),"bracket"(a[]=),"index"(a[0]=),"comma"(a=1,2). - Optional coercion.
parseNumbersandparseBooleansturn"42"/"true"into42/true. - Sensible encoding. Proper percent-encoding,
+decoded to space, array brackets kept readable. - Null/undefined handling.
undefinedis dropped;nullbecomes a bare key (or dropped withskipNull). - Typed & tiny. Full types, ESM + CJS, zero dependencies.
Install
npm install @billdaddy/qskit
# or: pnpm add @billdaddy/qskit / yarn add @billdaddy/qskit / bun add @billdaddy/qskitparse(input, options?)
import { parse } from "@billdaddy/qskit";
parse("?a=1&b=2"); // { a: "1", b: "2" } (leading ?/# ignored)
parse("a=1&a=2"); // { a: ["1", "2"] }
parse("q=hello+world"); // { q: "hello world" }
parse("ids[]=1&ids[]=2", { arrayFormat: "bracket" }); // { ids: ["1", "2"] }
parse("a[0]=x&a[1]=y", { arrayFormat: "index" }); // { a: ["x", "y"] }
parse("a=1,2,3", { arrayFormat: "comma" }); // { a: ["1", "2", "3"] }
parse("n=42&ok=true", { parseNumbers: true, parseBooleans: true });
// { n: 42, ok: true }interface ParseOptions {
arrayFormat?: "none" | "bracket" | "index" | "comma"; // default "none"
parseNumbers?: boolean; // default false
parseBooleans?: boolean; // default false
}stringify(object, options?)
import { stringify } from "@billdaddy/qskit";
stringify({ a: 1, b: "x", c: true }); // "a=1&b=x&c=true"
stringify({ ids: [1, 2] }); // "ids=1&ids=2"
stringify({ ids: [1, 2] }, { arrayFormat: "bracket" }); // "ids[]=1&ids[]=2"
stringify({ ids: [1, 2] }, { arrayFormat: "comma" }); // "ids=1,2"
stringify({ c: 3, a: 1 }, { sort: true }); // "a=1&c=3"
stringify({ a: 1, b: undefined }); // "a=1"interface StringifyOptions {
arrayFormat?: "none" | "bracket" | "index" | "comma"; // default "none"
sort?: boolean; // default false
skipNull?: boolean; // default false (null → bare key)
}Contributors ✨
This project follows the all-contributors specification. Contributions of any kind are welcome — code, docs, bug reports, ideas, reviews! See the emoji key for how each contribution is recognized, and open a PR or issue to get involved.
Thanks goes to these wonderful people:
License
MIT © Tung Tran
