Preprocessing as a layer, not a script
The single most common production bug in ML is train/serve skew: your training pipeline normalizes pixels by 255 and lowercases text, but the serving code forgets one step, and the model quietly predicts garbage on inputs that look subtly different from what it trained on. Keras 3's answer is to make preprocessing a layer that lives inside the model graph — so when you save the model, the preprocessing saves with it, and there's no second script to keep in sync.
The catalog
Numeric: Rescaling(1./255) scales pixels into [0, 1]; Normalization() standardizes features to zero mean / unit variance. Text: TextVectorization tokenizes raw strings into integer sequences. Categorical: CategoryEncoding and StringLookup turn categories and strings into model-ready tensors. There are image-augmentation layers (RandomFlip, RandomRotation) in the same family.
The adapt() step
Stateless layers like Rescaling need nothing — the factor is fixed. But Normalization and TextVectorization learn statistics from your data first: you call layer.adapt(train_data) once so the layer computes mean/variance or builds its vocabulary. After adapting, the layer behaves like any other and carries those learned statistics into deployment automatically.