


Mantener una biblioteca CSS-in-JS que funcione en navegador, servidor y nativo
Úsalo cuando una IA de programación trabaja en una biblioteca CSS-in-JS orientada a estándares. Limita los estilos a CSS estándar, evita fallos en cada entorno, escribe antes las pruebas según la especificación y fija cómo hacer notas de versión, documentación y demos con código real.
Para usar estas reglas de IA
## Aceptar solo CSS estándar en los estilos y dar prioridad a los valores por defecto configurados
Mantén la superficie de estilos autorizada alineada con CSS real y conforme a los estándares. Esto conserva un modelo mental portable y evita que la API derive hacia un dialecto idiosincrásico.
- Acepta únicamente nombres, grafías y valores de propiedades estándar en los estilos autorizados. Nunca inventes alias no estándar (por ejemplo, nombres en kebab-case para props exclusivas de la plataforma). Las claves de estilo específicas de la plataforma pertenecen a una vía de escape explícita (un objeto de estilo en línea, o soporte de plataforma en capas superiores), no al lenguaje de plantillas.
- El trabajo de la capa nativa es mapear CSS idiomático a primitivas de plataforma equivalentes y aplicar polyfills a lo que pueda hasta que el runtime nativo se ponga al día. No está ahí para ampliar la gramática de entrada aceptada.
### Precedencia de los valores predeterminados configurados
- Los valores predeterminados de atributos configurados por el autor siempre prevalecen sobre las props pasadas por quien llama, por diseño. Es un contrato deliberado, no un error.
- La vía de escape es la forma funcional de la configuración de valores predeterminados: recibe las props entrantes y puede retroceder condicionalmente (conservar el valor de quien llama, o suministrar un valor predeterminado).
- Excepción: si quien llama pasa explícitamente `undefined` para una prop, se suprime el valor predeterminado configurado para esa prop.
## Usar el gestor de paquetes y el formato de commits del proyecto
- Al inicio de cada sesión, lee el resumen actual de funcionalidades orientado al consumidor para trabajar sobre la superficie soportada de hoy, no sobre un comportamiento recordado.
- Usa el gestor de paquetes designado del proyecto y sus comandos asociados; no lo sustituyas por otro.
- Nunca inicies tú mismo el servidor de desarrollo. Pide al mantenedor que lo inicie si hace falta.
- Usa prefijos de commit convencionales (`feat|fix|chore|refactor|test|docs|style|perf|build|ci`). Por defecto, mensajes cortos: solo el título, o el título más una frase concisa.
- Mantén una convención de ortografía inglesa coherente en toda la prosa (comentarios, documentación, títulos de pruebas, cadenas visibles para el usuario). Conserva la ortografía original solo dentro de citas textuales de especificaciones o estándares.
## Distinguir servidor, navegador y nativo, y mantener el código DOM fuera de nativo
El código que se envía a múltiples entornos de ejecución no debe asumir un único entorno. Detecta el entorno a partir de varias señales independientes y aísla el código incompatible en el límite del punto de entrada.
- No colapses la detección de entorno en un único indicador universal. Distingue al menos: una constante de servidor en tiempo de compilación (verdadera solo en el build de servidor), una condición de componente de servidor en tiempo de ejecución (algunos frameworks sirven un build sin las APIs de contexto exclusivas del cliente), y un indicador de servidor por solicitud establecido por el punto de entrada SSR. Cada decisión se condiciona al subconjunto mínimo de señales que cubre los escenarios que le interesan. Trampa común: suprimir el trabajo del DOM basándose únicamente en la constante de servidor en tiempo de compilación rompe la ruta de prueba del build de servidor bajo jsdom, donde las mutaciones del DOM siguen ocurriendo. Condiciona las decisiones del DOM a las señales de runtime/SSR en su lugar.
- El punto de entrada nativo nunca debe importar código de DOM/navegador de forma transitiva mediante importaciones de valor. Usa importaciones exclusivamente de tipos y etiquetas de runtime identificadas (un registro de símbolos compartido) en lugar de `instanceof`. Verifícalo con un grep que confirme cero referencias a `document.` en el bundle nativo compilado; algunos runtimes nativos fallan en el momento de evaluación del módulo ante cualquier referencia a `document`.
- Los hooks de framework que no existen en todos los entornos de ejecución (por ejemplo, un hook de ref que es undefined en los componentes de servidor) deben quedar condicionados por la constante de servidor en tiempo de compilación para su eliminación como código muerto. Nunca los protejas con una comprobación en tiempo de ejecución del tipo `typeof hook === 'function'`, que se convierte en una llamada condicional a un hook.
- Mantén una única ruta canónica de emisión de salida. Cuando cambies la salida, extiende las suites de pruebas de emisión y de parser/compilador en lugar de añadir una ruta paralela.
## Quitar código con constantes en tiempo de compilación y fijar con pruebas el mapeo de puntos de entrada
Separa lo que el bundler puede eliminar en tiempo de compilación de lo que solo existe en tiempo de ejecución, y sé deliberado con el mapeo de puntos de entrada.
- Las constantes en tiempo de compilación (build de servidor, build nativo, variante nativa-web, modo desarrollo) se sustituyen por literales para que los bundlers eliminen como código muerto la rama no utilizada. Prefiere envolver toda la región contigua exclusiva de desarrollo en un único guard de desarrollo; no dependas solo de un helper de warn para omitir trabajo, y nunca construyas cadenas de mensaje ni argumentos de advertencia fuera del guard de desarrollo.
- Una comprobación en tiempo de ejecución como `typeof window !== 'undefined'` no se puede eliminar mediante tree-shaking. Usa constantes en tiempo de compilación, no comprobaciones en tiempo de ejecución, cuando necesites que el código se elimine físicamente de un bundle.
- El mapeo de entradas/subrutas es una fuente frecuente de roturas silenciosas. La resolución por extensión de plataforma (dejar que el bundler nativo elija un archivo específico por plataforma) es más segura que un mapa de objeto `browser` que algunos bundlers nativos aplican en todas las plataformas, lo cual puede enrutar silenciosamente un puente web hacia lo nativo. Un fallback `.js` debe ser el puente multiplataforma seguro, nunca el motor específico de una plataforma. Fija estas resoluciones con una prueba de resolución/tree-shake.
- Prefiere un campo `browser` sobre `exports` condicionales cuando estos últimos rompen la resolución de tipos en proyectos compuestos. Añade cada directorio de subruta publicado a la lista `files` del paquete.
## Escribir primero una prueba que falle y medir las optimizaciones con cargas reales
- El desarrollo estrictamente guiado por pruebas se aplica en todo el repositorio. Antes de cambiar código de producción, añade o extiende una prueba que falle y que codifique el contrato deseado, y luego implementa solo lo necesario para que pase. Ningún comportamiento visible para el usuario se publica sin una prueba que fallaría sin el cambio. Sigue la misma disciplina rojo-verde para el trabajo que no sea de funcionalidades.
- Siempre microbenchmarquea las optimizaciones contra una carga de trabajo realista, no contra un caso ideal sintético. Revierte cualquier cambio que empeore la ruta que realmente toman quienes llaman, aunque gane de forma aislada.
- Optimiza para baja presión de memoria y funciones monomórficas.
- Fundamenta cualquier comportamiento respaldado por una especificación en el borrador de editor vigente de la especificación autorizada, no en resúmenes ni sitios de referencia, y no en la memoria. Vuelve a obtener la sección relevante en cada sesión, cita la cláusula normativa textualmente como comentario justo encima de la prueba que la fija, y escribe una prueba por regla dentro de un bloque de cumplimiento de especificación claramente nombrado. Si la especificación guarda silencio o es ambigua, documenta la desviación junto a la prueba y enlaza el issue de seguimiento. Esto aplica a todo cambio que toque una especificación.
## Convertir cada regla de la especificación en una prueba antes de crear un polyfill nativo
Cuando el motor de estilos del runtime nativo no pueda entender una funcionalidad CSS, aplícale un polyfill, pero fija el comportamiento a la especificación antes de refactorizar internamente.
Procedimiento para un polyfill nuevo o revisado (también para cualquier bloque de validación respaldado por especificación):
1. Obtén el borrador de editor vigente para la sesión. Los números de cláusula y la redacción cambian, así que nunca trates un extracto antiguo como autoritativo.
2. Traduce cada regla de la especificación en exactamente una prueba, con el texto textual de la especificación citado justo encima, dentro de un bloque de cumplimiento de especificación nombrado en la suite correspondiente.
3. Escribe primero las pruebas y registra cuáles fallan en ese momento.
4. Implementa hasta que pasen. No remodeles pruebas que ya pasan para ajustarlas a la implementación; la especificación es la fuente de la verdad.
5. Ejecuta las suites completas nativa y principal para detectar regresiones.
Una vez que el bloque de especificación esté en verde, los mecanismos internos (tokenización, AST, evaluador) quedan libres para refactorizarse; el bloque fija el comportamiento observable por el usuario.
- Mantén actualizado el registro de compatibilidad nativa orientado al consumidor cada vez que se publiquen nuevas versiones de runtime, cambie el soporte, o se añadan, eliminen o modifiquen polyfills.
- Una funcionalidad sin una solución nativa viable debe emitir una advertencia deduplicada con un código estable que nombre la construcción problemática, explique por qué no puede ejecutarse y ofrezca una alternativa concreta, y luego descartar la declaración (recurrir a null) en lugar de enviar algo sin sentido.
- Paridad de variantes: donde el navegador ya ofrezca una funcionalidad, deja pasar el CSS crudo sin modificar; nunca emitas una propiedad que el navegador todavía no ofrezca; condiciona los levantamientos de props exclusivos de lo nativo y las extensiones de enumeraciones detrás de la constante de build exclusiva de lo nativo. Dale a cada bloque de especificación de polyfill una subsuite de paridad que alterne la variante web y fije su salida visible, y exime explícitamente (con el mismo rigor que un comentario de desviación) cualquier regla normativa que no aplique en una variante dada.
## Escribir en las notas de versión solo lo que ve el usuario y poner cada documento en su sitio
Ajusta el registro y el contenido de cada artefacto a su audiencia.
- El texto orientado al consumidor (notas de versión, entradas de changelog, descripciones de PR, documentación pública) declara únicamente el comportamiento observable por el usuario, con palabras que entienda alguien que no ha leído el código fuente. Nombra qué está soportado y qué no, y el límite propio del cambio; enlaza la matriz de compatibilidad en lugar de catalogar carencias no relacionadas. Nada de nombres de API internas, mecanismos o rutas de código; eso vive en el cuerpo del commit y en la guía de contribución.
- Describe el comportamiento tal como es actualmente. Evita la narración de trayectoria ("anteriormente", "ya no", "ahora", "reemplaza") para estados que ninguna versión publicada llegó a distribuir; integra una corrección sobre una funcionalidad aún no publicada dentro de la nota de versión de esa misma funcionalidad.
- Crea notas de versión únicamente para cambios visibles para el usuario (correcciones, funcionalidades, cambios incompatibles). Omite refactorizaciones internas, herramientas, pruebas y correcciones a código introducido en esa misma versión aún no publicada.
- No edites archivos generados automáticamente (changelogs, mapas de errores generados); regenéralos mediante su herramienta correspondiente.
- Mantén los nombres específicos de proveedores de IA fuera de la documentación orientada a colaboradores; usa una expresión neutra como "un asistente de codificación con IA".
- No fuerces el ajuste de línea (hard-wrap) en el cuerpo de PRs, issues ni comentarios; los párrafos de una sola línea se reajustan automáticamente, y los saltos forzados se ven rotos en vistas móviles y citadas. Los cuerpos de mensajes de commit pueden mantener la convención de 72 columnas.
### Ubicación de la documentación
- La guía de contribución alberga reglas transversales, invariantes y conocimiento adquirido sin un lugar natural en los comentarios del código fuente; un mecanismo bien descrito no pertenece ahí.
- Los documentos de conocimiento independientes capturan trampas y aprendizajes, no recorridos del mecanismo de una funcionalidad; el código fuente es la autoridad para el mecanismo.
- El "porqué" a nivel de código fuente vive en comentarios/JSDoc junto al código. No repitas citas de especificación en el código fuente de producción ni en los mensajes de advertencia; los anclajes, las citas normativas y la justificación viven en la prueba que fija el comportamiento. Los mensajes de advertencia nombran la construcción problemática y la alternativa concreta, y nada más.
## Usar patrones de rendimiento medidos y crear demos que ejecuten el código real
Patrones validados por microbenchmark en un motor de JavaScript convencional (trátalos como hipótesis de partida; vuelve a medir en contexto):
- La concatenación con `+=` en cadenas supera a `array.push()` + `join()` en todas las escalas.
- Extender con `{...props, extra}` supera a `Object.assign` o a una copia con `for..in`.
- `for..in` supera a `Object.keys()` más un bucle.
- Cachea las RegExp compiladas en un mapa; una comprobación previa con `indexOf` para omitir el trabajo por completo es una ganancia mayor.
- La concatenación manual con `+` supera a los template literals en bucles ajustados.
- Construir objetos de elemento crudos (con la etiqueta de elemento del framework) es mucho más rápido que la factoría de elementos del framework.
- `new Array(n)` crea arrays con huecos que envenenan la retroalimentación de tipos; evita presize de arrays en rutas calientes.
Peculiaridades del motor y del lenguaje:
- No se permite un modificador `private` en una expresión de clase anónima asignada a una const.
- Una importación de tipo con estrella (star import) exclusivamente de tipos puede seguir disparando la resolución de módulos del bundler aunque el sistema de tipos la elimine.
Integridad de demos y QA visual (para cualquier showcase que afirme demostrar un comportamiento):
- Tolerancia cero con las demos falsas. Cada widget debe ejercitar la ruta de runtime real que afirma demostrar. Si una funcionalidad no puede ejecutarse en una plataforma, deja que la celda falle de forma visible (layout roto, advertencia, glifo faltante); ese fallo es la demo. Nunca sustituyas por un mock que imite la especificación, y nunca codifiques de forma fija un color de aprobado/fallido como sustituto de que la ruta real se dispare.
- Usa componentes omniplataforma sin ramas específicas de plataforma en el showcase; las soluciones alternativas por desviación de plataforma pertenecen a la biblioteca, no a la aplicación.
- Haz que lo que funciona frente a lo que está roto sea reconocible de un vistazo, a distancia, mediante diferencias macro (cambios de layout, inundaciones de color, presencia/ausencia), y haz que cada widget se lea correctamente tanto en modo claro como en modo oscuro.
