SDK de Expo / React Native
@kilden-io/expo es el SDK cliente de Kilden para apps de Expo y React Native: captura de eventos, tracking de pantallas, identidad persistida y feature flags. Es la contraparte móvil del SDK web — misma semántica, adaptada a React Native (AsyncStorage en lugar de localStorage, un flush en background en lugar de sendBeacon). Para browsers usa @kilden/sdk; para tu backend usa un SDK de servidor.
Autocapture, session replay y plugins son solo web por ahora; este SDK no los incluye.
Instalación
Sección titulada «Instalación»npx expo install @kilden-io/expo expo-crypto @react-native-async-storage/async-storageBare React Native (sin Expo) también funciona: cada binding de plataforma es una dependencia blanda. Sin expo-crypto el SDK cae a cualquier polyfill global de crypto.getRandomValues (p. ej. react-native-get-random-values); sin AsyncStorage loguea un warning y mantiene la identidad en memoria, así que los ids no sobreviven un reinicio de la app.
Primer evento
Sección titulada «Primer evento»import kilden from "@kilden-io/expo";
kilden.init("YOUR_WRITE_KEY");
kilden.track("order_completed", { revenue: 99.9, currency: "CLP" });kilden.screen("Checkout", { step: 2 });El export por defecto es un singleton — llama a init una vez e impórtalo donde quieras. Las llamadas hechas antes de init se guardan y se reproducen en orden; las lecturas de flags antes de init se resuelven a su default. Si necesitas clientes aislados (tests, múltiples proyectos), usa createClient(writeKey, options).
La regla clave
Sección titulada «La regla clave»Usa la write key pública de tu proyecto (wk_…). Jamás incluyas una key secreta (sk_…) en una app: todo lo que va dentro de un bundle puede extraerse, y una key secreta filtrada le permite a cualquiera escribir eventos de servidor verificados en tu proyecto. El constructor rechaza las keys secretas de plano — la imagen espejo de los SDKs de servidor, que rechazan las públicas. El modelo completo está en niveles de confianza.
La superficie del cliente
Sección titulada «La superficie del cliente»| Método | Qué hace |
|---|---|
init(writeKey, options?) |
Inicializa el singleton. Ver Configuración |
track(event, properties?, options?) |
Encola un evento. options acepta timestamp y uuid explícitos |
screen(name, properties?, options?) |
Registra una vista de pantalla: un evento $screen con $screen_name |
identify(distinctId, traits?, options?) |
Vincula al usuario anónimo con tu id de usuario. Ver Identidad |
alias(aliasId) |
Vincula otro id conocido a la identidad actual (emite $alias) |
reset() |
Logout: id anónimo nuevo, token de identidad y cache de flags limpiados |
getDistinctId() |
Distinct id actual. Async — espera la hidratación del storage |
setIdentityToken(token) |
Setea o limpia el JWT de verificación de identidad |
isFeatureEnabled(key, options?) / getFeatureFlag(key, options?) |
Feature flags, evaluados remotamente. Async — ver Feature flags |
flush() |
Fuerza el envío de la cola |
close() |
Flush final con deadline de 10 segundos, después el cliente queda inerte |
Las garantías son las del SDK web: la API pública nunca lanza después de la construcción, tus datos nunca se mutan, y cada evento lleva un UUID v7 generado en el cliente para que los reintentos sean idempotentes. El formato de wire, la política de retry y el comportamiento del payload siguen kilden-sdk-spec — la misma autoridad contra la que se testean los SDKs de servidor.
Identidad
Sección titulada «Identidad»Los usuarios empiezan anónimos: un id anon_ + UUID v7, generado en el primer arranque y persistido en AsyncStorage. Cuando inician sesión:
identify vincula la historia anónima con tu id de usuario, con la misma semántica del grafo de personas que en la web. En el logout:
kilden.reset();reset rota a una identidad anónima nueva y descarta el token de identidad y el cache de flags. Si lo omites, el siguiente login en ese dispositivo queda vinculado al rastro anónimo del usuario anterior.
A diferencia del SDK web, este SDK también expone alias(aliasId): emite $alias, vinculando otro id conocido a la identidad actual sin cambiar el estado local. La mayoría de las apps solo necesita identify.
Verificación de identidad
Sección titulada «Verificación de identidad»Los eventos de cliente son no verificados por defecto — cualquiera puede extraer tu write key pública del bundle de la app. Para obtener eventos verified: true (requeridos por el messenger, respetados por los triggers de campañas), tu backend firma un JWT de vida corta para el usuario logueado y el SDK lo lleva con cada batch:
kilden.init("YOUR_WRITE_KEY", { getIdentityToken: async () => { const response = await fetch("https://your-backend.example/kilden/identity", { method: "POST", headers: { Authorization: `Bearer ${sessionToken}` }, // el token de sesión de tu app }); if (!response.ok) return null; const { token } = await response.json(); return token; },});El SDK refresca el token unos 60 segundos antes de que expire y una vez ante un 401. Los SDKs de servidor te dan el endpoint de firma en tres líneas — kilden/laravel trae POST /kilden/identity listo. Modelo completo: verificación de identidad.
Feature flags
Sección titulada «Feature flags»Evaluación remota contra /decide, con cache de 30 segundos por identidad:
if (await kilden.isFeatureEnabled("new_checkout")) { renderNewCheckout();}
const variant = await kilden.getFeatureFlag("checkout_test", { personProperties: { plan: "pro" }, // solo esta evaluación; evita el cache default: "control", // se devuelve cuando Kilden no puede responder});Las lecturas de flags nunca lanzan y nunca reintentan — una respuesta tardía de un flag no sirve, así que una lectura fallida devuelve tu default (false si no seteaste uno). identify() y reset() invalidan el cache, así que los valores convergen a la nueva identidad de inmediato. La primera lectura de cada flag emite un evento de exposición $feature_flag_called. La semántica de targeting y bucketing está en la guía de feature flags.
Batching y ciclo de vida
Sección titulada «Batching y ciclo de vida»Los eventos se encolan en memoria y se flushean cada 5 segundos, al llegar a 20 eventos encolados, y cuando la app deja el primer plano (vía AppState — React Native no tiene sendBeacon, así que el flush en background es el reemplazo móvil). El envío reintenta con backoff exponencial y respeta Retry-After. La cola está acotada a 10.000 eventos; al llegar al tope se descarta el evento nuevo, nunca la historia.
Por defecto la cola vive en memoria: los eventos aún encolados cuando el OS mata la app se pierden (React Native no expone una señal de “la app va a terminar” — el flush en background es el último hook confiable). Setea persistQueue: true para escribir la cola write-through a AsyncStorage: los eventos no entregados se restauran y se envían en el siguiente launch. La entrega es at-least-once — Kilden dedupea por uuid del evento, así que un batch que estaba en vuelo durante un kill jamás se cuenta doble. Llama a flush() en checkpoints naturales, y a close() si tu app tiene un punto de shutdown real — drena la cola con un deadline de 10 segundos y deja el cliente inerte.
Configuración
Sección titulada «Configuración»Todas las opciones con sus defaults:
kilden.init("YOUR_WRITE_KEY", { apiHost: "https://ingest.kilden.io", flushAt: 20, // largo de cola que dispara un flush flushIntervalMs: 5000, // flush periódico maxQueueSize: 10000, // tope duro; al tope se descarta el evento NUEVO requestTimeoutMs: 10000, // por request HTTP debug: false, // logging verboso + warnings de prefijo $ enabled: true, // false convierte todo el cliente en un no-op persistQueue: false, // true = la cola sobrevive a que el OS mate la app (se restaura y entrega en el siguiente launch)});El resto son puntos de inyección y plomería de identidad:
| Opción | Qué hace |
|---|---|
identityToken |
JWT de identidad inicial, si ya tienes uno en el init |
getIdentityToken |
Fetcher async del token, llamado 60 s antes de expirar y ante un 401. Ver verificación de identidad |
context |
() => Properties que se mezcla en cada evento como properties de sistema extra (las properties explícitas del evento ganan) |
storage |
Override de KeyValueStorage; por defecto AsyncStorage |
transport |
Override de Transport; por defecto fetch |
getRandomValues |
Override de entropía; por defecto expo-crypto, después el crypto.getRandomValues global |
appState |
Override de la fuente de ciclo de vida; por defecto el AppState de React Native |
Los puntos de inyección existen para que el core corra en cualquier lado — bare React Native, Expo Web, tests en Node. Por defecto cada evento lleva contexto del dispositivo: $os, $os_version, $device_type, $screen_width, $screen_height, más $lib y $lib_version.
Adónde seguir
Sección titulada «Adónde seguir»- Identificar usuarios — qué hace
identifyen el grafo de personas. - Verificación de identidad — el modelo de confianza detrás del token.
- Feature flags — targeting, rollouts, bucketing determinístico.
- kilden-sdk-expo en GitHub — código, changelog, discussions.