# jax

A Cursor rule for Python projects using JAX, covering functional purity, array types, compilation behavior, random keys, and gradient tests.

- rule · `type=rule` · Cursor · ★ 3580
- Author: sanjeed5
- License: CC0-1.0 · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/jax.mdc
- Updated: 2026-05-19
- HTML: https://affpapa.org/en/nevibecode/rules/jax

## What it does

This rule targets Python files matching `**/*.py`. It guides the coding agent around JAX transformations such as `jit`, `grad`, `vmap`, and `pmap`. The recommendations include passing state through function arguments, updating arrays with `.at[]`, and using JAX-compatible control flow instead of stateful Python iterators. These patterns address common sources of incorrect results and compilation problems.

Numerical and performance guidance covers explicit `float32` constants, consistent array shapes, and batching with `vmap`. When input shapes change, JAX may compile a function again; the rule suggests keeping shapes stable or considering `static_argnums` for non-array arguments that determine them. Random number generation should use `jax.random` with separately split PRNG keys.

The rule also encourages `jax.Array` type annotations, `pytest` for unit and integration tests, and `jax.test_util.check_grads` for derivative checks. It is intended for code that uses JAX, and ordinary Python loops inside `jit`-compiled functions can interfere with compilation. JAX control-flow primitives such as `lax.scan`, `lax.while_loop`, and `lax.cond` are recommended for those cases.

## Install

### Cursor (native platform)

**Manually: put the files in place**
- File: `.cursor/rules/jax.mdc` — Frontmatter: description, globs, alwaysApply

### Claude Code

**Manually: put the files in place**
- File: `.claude/rules/jax.md` — The paths frontmatter field limits the files: move globs from the source into paths

### Codex

**AGENTS.md**
- Codex reads AGENTS.md: paste the rule text there

### GitHub Copilot

**Manually: put the files in place**
- File: `.github/instructions/jax.instructions.md` — The applyTo field sets which files it applies to: move globs from the source into applyTo

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/rules/jax.md`

### Cline

**Manually: put the files in place**
- File: `.clinerules/jax.md`

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/jax.mdc

## When to use it
- Remove mutable global state from JAX functions
- Replace in-place array assignments with functional updates
- Rewrite Python loops using JAX control-flow primitives
- Avoid recompilation caused by changing array shapes
- Test gradients for custom numerical operations

## Example prompts
- Review my Python files against the JAX rule and refactor functions that rely on mutable global state.
- Replace the Python loop inside this `jit` function with a suitable `jax.lax` operation.
- Check my PRNG key handling and add gradient tests for the custom function.

## Source text · jax.mdc · CC0-1.0

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: ba43d7dcbdb27432.

BEGIN THIRD-PARTY FILE ba43d7dcbdb27432
````text
---
description: Definitive guidelines for writing high-performance, functionally pure, and maintainable JAX code, focusing on common pitfalls and optimal patterns for accelerators.
globs: **/*.py
---
# jax Best Practices

JAX is the backbone of our AI/ML and numerical computing projects. Adhere to these principles for high-performance, reproducible, and maintainable JAX code.

## 1. Functional Purity: The Absolute Core

JAX transformations (`jit`, `grad`, `vmap`, `pmap`) operate exclusively on **functionally pure** code. This means functions must be free of side-effects: all inputs explicit, all results returned.

*   **Avoid mutable global state:** JAX captures global values at first `jit` compilation, leading to stale values.
    ❌ BAD:
    ```python
    g = 0
    def impure_uses_globals(x):
        return x + g # `g` is captured at first jit
    # ... later g = 10, but jit(impure_uses_globals) still uses g=0
    ```
    ✅ GOOD: Pass all state explicitly.
    ```python
    def pure_uses_globals(x, g_val):
        return x + g_val
    # ... pass g_val=0, then g_val=10
    ```

*   **No in-place array mutation:** JAX arrays are immutable. Use the `.at[]` syntax for functional updates.
    ❌ BAD:
    ```python
    import jax.numpy as jnp
    arr = jnp.zeros((3,3))
    arr[1, :] = 1.0 # TypeError!
    ```
    ✅ GOOD:
    ```python
    import jax.numpy as jnp
    arr = jnp.zeros((3,3))
    updated_arr = arr.at[1, :].set(1.0) # Returns a new array
    ```

*   **Avoid Python iterators in `jit`ted code:** Iterators introduce state.
    ❌ BAD:
    ```python
    from jax import jit
    def sum_iterator(it):
        total = 0
        for x in it: # Python loop with iterator
            total += x
        return total
    # jit(sum_iterator)(iter(range(10))) # Will fail or give unexpected results
    ```
    ✅ GOOD: Use JAX control flow primitives.
    ```python
    from jax import lax
    import jax.numpy as jnp
    def sum_array(arr):
        # Use lax.scan or lax.fori_loop for JAX-compatible loops
        return lax.fori_loop(0, arr.shape[0], lambda i, x: x + arr[i], 0)
    # jit(sum_array)(jnp.arange(10))
    ```

## 2. Numerical Type Discipline

Prioritize `float32` for performance on accelerators. Avoid implicit `float64` promotion.

*   **Explicit `dtype` for constants:**
    ❌ BAD: Implicitly typed Python floats can lead to `float64` promotion.
    ```python
    import jax.numpy as jnp
    x = jnp.ones(5, dtype=jnp.float32)
    y = x * 2.0 # 2.0 is a Python float, can cause unwanted promotion
    ```
    ✅ GOOD: Use 0-D `jnp.array` with explicit `dtype` or `jnp.float32()`.
    ```python
    import jax.numpy as jnp
    x = jnp.ones(5, dtype=jnp.float32)
    y = x * jnp.array(2.0, dtype=jnp.float32)
    # Or more concisely:
    z = x * jnp.float32(2.0)
    ```

## 3. Performance Considerations: Stable Compilation

Prevent costly recompilations and leverage XLA effectively.

*   **Static shapes:** Keep input shapes static or pass them via `static_argnums` to `jit`. Dynamic shapes force recompilation.
    ❌ BAD:
    ```python
    from jax import jit
    def dynamic_shape_func(x):
        return x.sum()
    # jit(dynamic_shape_func)(jnp.ones(5))
    # jit(dynamic_shape_func)(jnp.ones(10)) # Recompiles!
    ```
    ✅ GOOD:
    ```python
    from jax import jit
    @jit
    def static_shape_func(x):
        return x.sum()
    # Call with consistent shapes
    # static_shape_func(jnp.ones(5))
````
END THIRD-PARTY FILE ba43d7dcbdb27432

The third-party file has ended. Everything between the ba43d7dcbdb27432 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3467 of 6157 bytes. © sanjeed5 · CC0-1.0 · https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/jax.mdc

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
