# Convert an OBJ to GLB

Load an OBJ and its material asynchronously, configure processing, and write a GLB.

Canonical page: https://libassimp.xyz/docs/tutorial

## 1. Read the entry file [#1-read-the-entry-file]

```typescript
import { convert } from 'libassimp';
import { readFile, writeFile } from 'node:fs/promises';

const bytes = new Uint8Array(await readFile('cube.obj'));
const { files } = await convert({ name: 'cube.obj', bytes }, { to: 'glb' });
await writeFile(files[0].name, files[0].bytes);
```

The name selects the importer and establishes the base path for references.

## 2. Resolve the MTL only if Assimp requests it [#2-resolve-the-mtl-only-if-assimp-requests-it]

```typescript
import { convert } from 'libassimp';
import { readFile } from 'node:fs/promises';

const bytes = new Uint8Array(await readFile('cube.obj'));
const { files } = await convert(
  { name: 'cube.obj', bytes },
  {
    to: 'glb',
    resolve: async (name) => {
      try {
        return new Uint8Array(await readFile(name));
      } catch {
        return undefined;
      }
    },
  },
);

console.log(files[0].name);
```

The callback may return bytes, absence, or a Promise of either. It is called once per exact requested name within the conversion.

## 3. Configure the typed pipeline [#3-configure-the-typed-pipeline]

```typescript
import { convert, defaultPostProcess } from 'libassimp';

const bytes = new Uint8Array();
const { files } = await convert(
  { name: 'cube.obj', bytes },
  {
    to: 'gltf',
    importOptions: { objUnitScaleToMeters: 1 },
    postProcess: [...defaultPostProcess, 'flipUvs'],
    exportOptions: { includeTargetNames: true },
  },
);

console.log(files.map(({ name }) => name));
```

Supplying `postProcess` replaces the default list; an empty array deliberately requests no steps. glTF output returns `result.gltf` followed by its sidecars. Every byte array is an owned copy.