{"id":49285189,"url":"https://github.com/ktav-lang/js","last_synced_at":"2026-05-03T16:02:16.814Z","repository":{"id":353561738,"uuid":"1219936484","full_name":"ktav-lang/js","owner":"ktav-lang","description":"Universal JS/TS bindings for Ktav — a plain configuration format with three rules, zero indentation, and zero quoting. WASM-backed, ships for Node, Deno, Bun, and browsers from a single package.","archived":false,"fork":false,"pushed_at":"2026-05-03T10:26:21.000Z","size":346,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T12:15:41.146Z","etag":null,"topics":["bindings","bun","config","configuration","deno","javascript","ktav","napi","napi-rs","nodejs","parser","serializer","typescript","wasm","webassembly"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ktav-lang.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-24T11:25:25.000Z","updated_at":"2026-05-03T10:26:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ktav-lang/js","commit_stats":null,"previous_names":["ktav-lang/js"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ktav-lang/js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ktav-lang","download_url":"https://codeload.github.com/ktav-lang/js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fjs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32575115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bindings","bun","config","configuration","deno","javascript","ktav","napi","napi-rs","nodejs","parser","serializer","typescript","wasm","webassembly"],"created_at":"2026-04-25T21:07:03.818Z","updated_at":"2026-05-03T16:02:16.809Z","avatar_url":"https://github.com/ktav-lang.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ktav (JavaScript / TypeScript)\n\n\u003e Universal JS/TS bindings for [Ktav](https://github.com/ktav-lang/spec) —\n\u003e a plain configuration format. JSON-shape, no quotes, no commas, dotted\n\u003e keys. Powered by Rust under the hood, shipped as native N-API for Node\n\u003e and Bun, WebAssembly for Deno, browsers, and bundlers.\n\n**Languages:** **English** · [Русский](README.ru.md) · [简体中文](README.zh.md)\n\n**Specification:** this package implements **Ktav 0.1**. The format is\nversioned and maintained independently of this package — see\n[`ktav-lang/spec`](https://github.com/ktav-lang/spec) for the formal\ndocument.\n\n---\n\n## Install\n\n```bash\nnpm install @ktav-lang/ktav\n```\n\n\u003e **Naming note:** the bare `ktav` name is blocked on npm's similarity\n\u003e filter (too close to `koa`, `keyv`, `klaw`, …), so the package ships\n\u003e under the `@ktav-lang` scope. Rust (`ktav` on crates.io) and Python\n\u003e (`ktav` on PyPI) keep the short form.\n\nOne package serves every target runtime:\n\n| Runtime          | Backend  | How it's loaded                          |\n|------------------|----------|------------------------------------------|\n| Node ≥ 18, Bun   | N-API    | Platform-specific `.node` via optional dep |\n| Deno, browser    | WASM     | `web` target, consumer awaits `ready()`  |\n| Webpack / Vite / Rollup / esbuild | WASM | `bundler` target, bundler resolves `.wasm` |\n\nNative binaries are prebuilt for Linux (x64/arm64, glibc + musl),\nmacOS (x64/arm64), and Windows (x64/arm64); npm installs the one that\nmatches the current host through `optionalDependencies`. If nothing\nmatches, the loader throws early with a clear diagnostic.\n\n## Quick start\n\n### Parse — typed reads off the parsed object\n\n```ts\nimport { loads, dumps } from \"@ktav-lang/ktav\";\n\ninterface DB { host: string; timeout: number; }\ninterface Config {\n  service: string;\n  port:    number;\n  ratio:   number;\n  tls:     boolean;\n  tags:    string[];\n  db:      DB;\n}\n\nconst cfg = loads\u003cConfig\u003e(`\nservice: web\nport:i 8080\nratio:f 0.75\ntls: true\ntags: [\n    prod\n    eu-west-1\n]\ndb.host: primary.internal\ndb.timeout:i 30\n`);\n\ncfg.port;        // 8080 — typed as number\ncfg.db.timeout;  // 30\n```\n\n### Build \u0026 render — construct a document in code\n\n```ts\nconst doc = {\n  name:  \"frontend\",\n  port:  8443,\n  tls:   true,\n  ratio: 0.95,\n  upstreams: [\n    { host: \"a.example\", port: 1080 },\n    { host: \"b.example\", port: 1080 },\n  ],\n  notes: null,\n};\nconst text = dumps(doc);\n// name: frontend\n// port:i 8443\n// tls: true\n// ratio:f 0.95\n// upstreams: [\n//     { host: a.example  port:i 1080 }\n//     { host: b.example  port:i 1080 }\n// ]\n// notes: null\n```\n\nA complete runnable Node example lives in [`examples/node/index.mjs`](examples/node/index.mjs).\n\n### WASM consumers (Deno, browser)\n\nCall `ready()` once before the first `loads` / `dumps` — the wasm\ntarget defers instantiation:\n\n```ts\nimport { ready, loads } from \"@ktav-lang/ktav\";\nawait ready();\nloads(\"port:i 8080\\n\");\n```\n\nNode / Bun consumers skip this — the native binary is loaded at import\ntime.\n\n### Native FFI subexport (Deno, Bun) — `@ktav-lang/ktav/ffi`\n\nFor Deno users who want native speed without the WASM tax — and for\nBun users who prefer `bun:ffi` over the N-API path — there's an\nopt-in subexport that talks directly to the C ABI shared library\n(`ktav_cabi`, the same binary used by the Java / Go / .NET bindings):\n\n```ts\nimport { loads, dumps } from \"@ktav-lang/ktav/ffi\";\n\n// loads / dumps are ASYNC here (waiting on dlopen on first call)\nconst cfg = await loads(\"port:i 8080\\n\");\nconst text = await dumps({ port: 8443 });\n```\n\n| Runtime  | Mechanism          | Permission flag                                                             |\n|----------|--------------------|-----------------------------------------------------------------------------|\n| Deno     | `Deno.dlopen`      | `--allow-ffi=\u003cpath-to-libktav_cabi\u003e` (or `--allow-ffi` for any FFI target)  |\n| Bun      | `bun:ffi`          | none — Bun trusts FFI                                                       |\n| Node     | n/a                | throws — use the default import (already N-API native)                      |\n| Browser  | n/a                | throws — use `@ktav-lang/ktav/wasm` instead                                 |\n\nThe library file ships in the matching `@ktav-lang/js-\u003crid\u003e`\noptional dependency (same one that holds the `.node` binary), so\n`npm install @ktav-lang/ktav` is enough — no separate download.\nOverride with `KTAV_LIB_PATH` for local cabi builds.\n\nTrade-off: ~3–5× faster than WASM on parse / dump of large\ndocuments; requires a permission grant on Deno; loses Deno's\n\"works in any sandbox\" property. Stick with the default import\nunless you've measured a need.\n\nRunnable examples: [`examples/deno/ffi.ts`](examples/deno/ffi.ts),\n[`examples/bun/ffi.ts`](examples/bun/ffi.ts).\n\n## Public API\n\n```ts\nfunction loads\u003cT = KtavValue\u003e(s: string): T;\nfunction dumps\u003cT extends KtavInput = KtavInput\u003e(obj: T): string;\n\n// web / Deno / browser only; Node + Bun ignore it\nfunction ready(input?: URL | Response | ArrayBuffer): Promise\u003cvoid\u003e;\n```\n\nThe generic parameter on `loads` is an **unchecked cast** — use it when\nyou know the shape for IDE autocomplete. Pass nothing for the\nstructural `KtavValue` type.\n\n## Type mapping\n\n| Ktav             | JavaScript                                |\n|------------------|-------------------------------------------|\n| `null`           | `null`                                    |\n| `true` / `false` | `boolean`                                 |\n| `:i \u003cdigits\u003e`    | `number` (safe range) / `bigint` (larger) |\n| `:f \u003cnumber\u003e`    | `number`                                  |\n| bare scalar      | `string`                                  |\n| `[ ... ]`        | `Array`                                   |\n| `{ ... }`        | plain object (insertion-ordered)          |\n\nKtav keeps **\"no magic types\"** — a bare `port: 8080` stays a string at\nthe parser level. Use the typed markers `:i` / `:f` when you want\nnumbers, or coerce at the application layer.\n\nOn encode, `Number.isInteger(x)` decides `:i` vs `:f`; `bigint` always\nencodes as `:i`. `NaN` and `±Infinity` are rejected — Ktav 0.1.0 does\nnot represent them.\n\n## Single-file browser build\n\n`dist/wasm/web/ktav.inline.js` is a variant with the WASM binary\nbase64-embedded — drop it into any `\u003cscript type=\"module\"\u003e` without a\nsibling `.wasm` file and without any HTTP server. Works over `file://`.\n\n```html\n\u003cscript type=\"module\"\u003e\n    import init, { loads, dumps } from \"https://unpkg.com/ktav/dist/wasm/web/ktav.inline.js\";\n    await init();\n    console.log(loads(\"hello: world\\n\"));\n\u003c/script\u003e\n```\n\nTrade-off: ≈ 35 % bigger uncompressed, ≈ 5 % after gzip — base64\ncompresses well against the wasm's near-random bytes.\n\n## Philosophy\n\nKtav is intentionally small. Its five design principles\n(from [`spec/CONTRIBUTING.md`](https://github.com/ktav-lang/spec/blob/main/CONTRIBUTING.md)):\n\n1. **Locality** — a line's meaning does not depend on another line.\n2. **One sentence** — any new rule fits in one sentence of the spec.\n3. **No whitespace sensitivity** (line breaks aside).\n4. **No magic types** — the format never decides `\"8080\"` means a number.\n5. **Explicit over clever** — `::` is verbose on purpose.\n\nThese bindings honour that: no schema inference, no auto-casting, no\ndefaulting. If you want typing, do it at the boundary with your own\ntool (Zod, io-ts, hand-written validators) against the native\nstructures this library returns.\n\n## Related projects\n\n- [`ktav-lang/spec`](https://github.com/ktav-lang/spec) — canonical\n  format specification and language-agnostic conformance test suite.\n- [`ktav-lang/rust`](https://github.com/ktav-lang/rust) — reference Rust\n  implementation. The N-API crate and the WASM crate both wrap it.\n- [`ktav-lang/python`](https://github.com/ktav-lang/python) — Python\n  bindings (PyO3) over the same crate.\n\n## Versioning\n\nFollows [Semantic Versioning](https://semver.org/) with the pre-1.0\nconvention that a MINOR bump is breaking. Package version and the\n`ktav` crate version move together.\n\n## Development\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, the runtime\ntest matrix, and the contribution workflow.\n\n## Support the project\n\nThe author has many ideas that could be broadly useful to IT worldwide —\nnot limited to Ktav. Realizing them requires funding. If you'd like to\nhelp, please reach out at **phpcraftdream@gmail.com**.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\n## Other Ktav implementations\n\n- [`spec`](https://github.com/ktav-lang/spec) — specification + conformance suite\n- [`rust`](https://github.com/ktav-lang/rust) — reference Rust crate (`cargo add ktav`)\n- [`csharp`](https://github.com/ktav-lang/csharp) — C# / .NET (`dotnet add package Ktav`)\n- [`golang`](https://github.com/ktav-lang/golang) — Go (`go get github.com/ktav-lang/golang`)\n- [`java`](https://github.com/ktav-lang/java) — Java / JVM (`io.github.ktav-lang:ktav` on Maven Central)\n- [`php`](https://github.com/ktav-lang/php) — PHP (`composer require ktav-lang/ktav`)\n- [`python`](https://github.com/ktav-lang/python) — Python (`pip install ktav`)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktav-lang%2Fjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fktav-lang%2Fjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktav-lang%2Fjs/lists"}