Register backends before initializing
The plugin registry has to know which engines exist before the first model load. Register, then initialize.Initialize once, early
initialize() is synchronous and cheap. Call it at app launch rather than lazily on the first
generation, so the background phase has time to finish before anyone needs it.
Let generation load the model
models.load when you want to
control when the cost is paid, for instance warming a model behind a splash screen.
Stream anything a person waits for
A 200-token reply takes seconds. Streaming turns that into words appearing immediately.Cap output length
maxOutputTokens is the single biggest lever on latency and heat. Set it to what the interface
can actually display.
Unload what you are not using
Models hold memory for as long as they are resident. On a phone, holding a language model, a speech model, and a vision model at once is how you get.insufficientMemory.
Trim conversations
History grows until it exceeds the context window. Keep the system message and the most recent turns.Keep system prompts short
Small models follow three concrete sentences better than a paragraph of persona. Say the format you want and the length you want, and nothing else.Use structured output rather than asking nicely
Asking for JSON in a system prompt works most of the time, which is the problem. When you need to parse the result, usegenerateStructured, which validates and can repair.
.constrained is not implemented yet and throws.
Handle cancellation
Cancel theTask when a view disappears. Otherwise a generation keeps running and keeps the
model resident for a screen nobody is looking at.
Check capabilities rather than assuming
MLX.register() returns false and no MLX model will load.