# qtdatastream-web

> Browser-native TypeScript (de)serializer for Qt's QDataStream format

Latest version **0.0.1** (published 2026-06-20) · MIT license · 0 weekly downloads

## Install

```sh
npm install qtdatastream-web
pnpm add qtdatastream-web
yarn add qtdatastream-web
bun add qtdatastream-web
```

## Health

**Score 65/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.0.1 |
| Published | 2026-06-20 |
| First published | 2026-06-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >= 18 |
| Dependencies | 0 |
| Unpacked size | 111.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Maintainers | delwing |
| Keywords | qt, datastream, qdatastream, qvariant, browser, typescript |

## Links

- npm: https://www.npmjs.com/package/qtdatastream-web
- Repository: https://github.com/Delwing/qtdatastream
- Homepage: https://github.com/Delwing/qtdatastream#readme
- Issues: https://github.com/Delwing/qtdatastream/issues
- npm.io page: https://npm.io/package/qtdatastream-web

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 0.0.1 (latest) — 2026-06-20

## README

# qtdatastream-web

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A TypeScript (de)serializer for Qt's [QDataStream](http://doc.qt.io/qt-4.8/qdatastream.html)
format that runs natively in the **browser** — built only on `Uint8Array`,
`DataView`, `BigInt`, and `TextEncoder`/`TextDecoder`. No `Buffer`, no Node
streams, no polyfills.

Supported types: `QBool`, `QShort`, `QInt`, `QInt64`, `QUInt`, `QUInt64`,
`QDouble`, `QMap`, `QList`, `QString`, `QVariant`, `QStringList`, `QByteArray`,
`QUserType`, `QDateTime`, `QTime`, `QChar`, `QInvalid`.

## Install

```sh
npm install qtdatastream-web
```

The package ships ES modules and TypeScript declarations. There is no default
runtime dependency.

## Quick start

```ts
import { read, write } from 'qtdatastream-web';

// Serialize a value to a Uint8Array...
const bytes = write({ AString: 'BString', CString: 42 });

// ...and read it back.
const value = read(bytes); // { AString: 'BString', CString: 42 }
```

`write`/`read` operate on a single `QVariant` with no framing — convenient for
reading from and writing to files. Input to `read` may be a `Uint8Array`,
`ArrayBuffer`, any `TypedArray`, or a `number[]`; output is always a
`Uint8Array`.

### Reading a file in the browser

```ts
import { read } from 'qtdatastream-web';

const file = input.files[0];
const value = read(await file.arrayBuffer());
```

### Writing a file in the browser

```ts
import { write } from 'qtdatastream-web';

const blob = new Blob([write(value)], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
```

## API

```ts
import {
  read, write,           // single QVariant, no length prefix
  readAll,               // read every QVariant until the buffer is exhausted
  readPacket, writePacket, // QVariant prefixed with a 4-byte big-endian length
  ReadBuffer,            // sequential big-endian reader over a byte buffer
  types,                 // all Q* type classes + Types enum
  util,                  // str(), date <-> Julian day, deep mapping
  bytes,                 // low-level byte/encoding helpers
  serialization,         // Serializable / serialize decorators
} from 'qtdatastream-web';
```

Submodules are also importable directly, e.g. `qtdatastream-web/types`.

## Type inference

JavaScript values are coerced to Qt types automatically.

| JavaScript | QClass                          |
|------------|---------------------------------|
| string     | QString                         |
| number     | QUInt (configurable)            |
| bigint     | QInt64                          |
| boolean    | QBool                           |
| Array      | QList&lt;QVariant&lt;?&gt;&gt;   |
| Date       | QDateTime                       |
| Map        | QMap                            |
| Object     | QMap                            |

Force any value into a specific Qt type with `<QClass>.from`:

```ts
import { types } from 'qtdatastream-web';
const qbytearray = types.QByteArray.from('hello'); // string written as a QByteArray
```

Change the default class plain numbers coerce to:

```ts
import { types } from 'qtdatastream-web';
types.QVariant.coerceNumbersTo(types.Types.DOUBLE); // numbers now serialize as QDouble
```

### Reading back to JavaScript

| QClass      | JavaScript     |
|-------------|----------------|
| QString     | string         |
| QUInt/QInt/QShort/QDouble/QTime | number |
| QUInt64/QInt64 | bigint      |
| QBool       | boolean        |
| QList       | Array          |
| QStringList | Array&lt;string&gt; |
| QByteArray  | Uint8Array     |
| QMap        | Object         |
| QUserType   | Object         |
| QDateTime   | Date           |
| QChar       | string         |
| QInvalid    | undefined      |

> 64-bit integers are read as `bigint` and may be written as `bigint` or
> `number`.

## QUserType

`QUserType` covers Qt's user-defined types (`QVariant::UserType`). Register a
parser/serializer for each type by name before use.

```ts
import { types } from 'qtdatastream-web';
const { QUserType, Types } = types;

// Simple usertype backed by a single Qt type
QUserType.register('NetworkId', Types.INT);

// Structured usertype (parsing order is preserved)
QUserType.register('BufferInfo', [
  { id: Types.INT },
  { network: Types.INT },
  { type: Types.SHORT },
  { name: Types.BYTEARRAY },
]);

// Usertypes may nest other usertypes by name (declare the referenced one first)
QUserType.register('BufferInfoContainer', [
  { id: Types.INT },
  { bufferInfo: 'BufferInfo' },
]);
```

Writing a usertype value:

```ts
import { write, types } from 'qtdatastream-web';

const bytes = write({
  BufferInfo: new types.QUserType('BufferInfo', {
    id: 2,
    network: 4,
    type: 5,
    name: 'BufferInfo name',
  }),
});
```

## Decorators

Classes can declare their serialization shape with decorators. These use the
legacy decorator syntax, so enable `experimentalDecorators` in your
`tsconfig.json` (or the equivalent Babel plugin).

```ts
import { types, Serializable, serialize } from 'qtdatastream-web';
const { QString, QUInt, Types, QUserType } = types;

QUserType.register('Network::Server', Types.MAP);

@Serializable('Network::Server')
class Server {
  @serialize(QString, { in: 'HostIn', out: 'HostOut' })
  host?: string;

  @serialize(QUInt, 'Port')
  port = 6667;

  @serialize(QUInt)
  sslVersion = 0;

  constructor(args: Partial<Server>) {
    Object.assign(this, args);
  }
}
```

`Serializable`'s argument (the usertype name) is optional; without it, instances
export as a `QMap`. If a serializable class implements `_export()`, its return
value is serialized instead of the instance's own attributes.

## Development

```sh
yarn install
yarn build       # compile to dist/
yarn typecheck   # type-check without emitting
yarn test        # run the test suite (Vitest)
yarn test:watch  # run Vitest in watch mode
```

## Credits

This project is based on the original
[node-qtdatastream](https://github.com/magne4000/node-qtdatastream) by
Joël Charles, whose work defines the QDataStream encoding implemented here.

## License

MIT.

---
_Source: https://npm.io/package/qtdatastream-web · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
