# Experimental Features

Some BoltFFI features are behind an experimental flag. The API for these features may change between releases, so they require an explicit opt-in.

Java, C#, and Python bindings are generally available and no longer require experimental opt-in.

| Feature                     | Key                        | Status                             |
| --------------------------- | -------------------------- | ---------------------------------- |
| Dart target                 | `dart`                     | In progress                        |
| Kotlin Multiplatform target | `kotlin_multiplatform`     | Initial JVM/Android actuals        |
| C target                    | `c`                        | Synchronous APIs; see [limits](#c) |
| TS async streams            | `typescript.async_streams` | Functional                         |

## Enabling

### CLI flag

Pass `--experimental` to include experimental targets during that command run:

```bash
boltffi generate all --experimental
boltffi pack all --experimental
```

### Config file

Add the feature key to `experimental` in `boltffi.toml`:

```toml
experimental = ["kotlin_multiplatform", "typescript.async_streams"]
```

The CLI flag applies to a single command. The config array applies to every build.

## Feature Details

### Kotlin Multiplatform

**Key:** `kotlin_multiplatform`

Enables `boltffi generate kmp` and includes Kotlin Multiplatform output during `boltffi generate all --experimental`. The generated module contains `commonMain` declarations plus `jvmMain` and `androidMain` actuals that delegate to the existing Kotlin/JNI bindings.

This is an initial target slice. Kotlin/Native `cinterop` actuals for iOS/macOS are not generated yet.

### C

**Key:** `c`

Set `targets.c.enabled = true`, then run `boltffi pack c --experimental` to build a header and native libraries for the current host. `boltffi generate c --experimental` writes only the header.

C supports synchronous functions and methods, classes, records, enums with or without payloads, collections, custom types, constants, and typed results. Add `--deny-skipped` when every exported declaration must have a C binding.

- Async functions, async methods and constructors, streams, and async callback traits are not generated for C.
- Inline `Fn`, `FnMut`, and `FnOnce` parameters do not have generated C wrappers.
- Callback payload conversion is incomplete; see [C vtables](/docs/callbacks.md#c-vtables).
- Interned-string transport is not implemented for C.
- Allocation and return-value conversion failures do not have a separate C error channel. Some paths return an empty or zeroed value. The `ok` field on a Rust `Result` reports the Rust result, not all possible allocation failures.
- [C packaging](/docs/packaging.md#c-experimental) is host-only. Cross-compilation through Cargo target selection is not supported.

These limits do not exclude records with strings, data enums, options, nested collections, maps, or custom types from synchronous functions. The generated header and skipped-declaration report describe the API available for a particular library.

### TypeScript Async Streams

**Key:** `typescript.async_streams`

Enables `AsyncIterable` stream generation for TypeScript/WASM targets. Without this flag, stream methods are skipped during TypeScript codegen.

## Graduating from Experimental

When a feature stabilizes, it moves out of the experimental list. The `--experimental` flag and config entry are no longer required. Existing code continues to work without changes.
