# Configure import and export

Use generated import options, named post-process steps, exact target options, and runtime capability metadata.

Canonical page: https://libassimp.xyz/docs/guides/export-properties

## Target-specific export options [#target-specific-export-options]

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

const bytes = new Uint8Array();
const { files } = await convert(
  { name: 'part.glb', bytes },
  {
    to: '3mf',
    exportOptions: {
      unit: 'millimeter',
      decimalPrecision: 9,
      application: 'libassimp',
      upAxis: 'z',
    },
  },
);

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

`ExportOptionsFor<'3mf'>` offers only 3MF fields. Runtime validation applies the same generated enum values, numeric bounds, and defaults before native work. Invalid configuration rejects with `INVALID_OPTIONS` and deterministic field paths.

Binary and material variants are options rather than extra format names:

```typescript
import { convertFormats } from 'libassimp';

const bytes = new Uint8Array();
const results = await convertFormats(
  { name: 'part.glb', bytes },
  {
    targets: [
      { to: 'fbx', exportOptions: { binary: false } },
      { to: 'ply', exportOptions: { binary: true } },
      { to: 'stl', exportOptions: { binary: true } },
      { to: 'obj', exportOptions: { materials: false } },
    ],
  },
);

console.log(results.map(({ format }) => format));
```

FBX defaults to binary, PLY and STL default to ASCII, and OBJ defaults to writing materials when present.

## Import and post-process options [#import-and-post-process-options]

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

const bytes = new Uint8Array();
await convert(
  { name: 'part.obj', bytes },
  {
    to: 'glb',
    importOptions: { objUnitScaleToMeters: 0.001 },
    postProcess: [...defaultPostProcess, 'flipUvs'],
  },
);
```

`importOptions` configures importer and processing properties. `postProcess` is an exact replacement list, not an additive list. Named conflicts and duplicate steps are rejected.

## Build dynamic UI from metadata [#build-dynamic-ui-from-metadata]

```typescript
import { assimpCapabilities } from 'libassimp';

for (const [name, descriptor] of Object.entries(assimpCapabilities.export['3mf'].exportOptions)) {
  console.log(
    name,
    descriptor.kind,
    descriptor.default,
    'values' in descriptor ? descriptor.values : undefined,
  );
}
```

The serializable registry supplies descriptions, kinds, defaults, ranges, enum values, and applicability. It contains public camelCase names only; native Assimp keys and raw escape bags are private.