@pixi/react Documentation

repository·main·Indexed 25 days ago

https://github.com/pixijs/pixi-react

A production-ready library for writing high-performance PixiJS applications using React's declarative style. It provides the <Application /> component, the extend API for registering PixiJS classes as JSX elements (e.g., <pixiContainer />), and hooks such as useApplication, useExtend, and useTick for ticker-based animations and application instance access.

Tokens
7.1K
Snippets
25
Records
42
Agent score
84%

What's inside @pixi/react

  1. Register custom components in the PixiElements type catalogue

    main

    To prevent TypeScript errors when using custom components, you must add them to the PixiElements interface via module augmentation. This allows the library's type system to recognize your custom elements.

    // global.d.ts
    import { type Viewport } from 'pixi-viewport';
    import { type PixiReactElementProps } from '@pixi/react';
    
    declare module '@pixi/react'
    {
        interface PixiElements
        {
            viewport: PixiReactElementProps<typeof Viewport>;
        }
    }
  2. Enable unprefixed Pixi elements

    main

    By default, components use the pixi prefix (e.g., <pixiContainer>). To enable unprefixed elements (e.g., <container>), extend the PixiElements interface with UnprefixedPixiElements.

    Note: It is recommended to use prefixed components to avoid naming collisions with other libraries like react-dom (e.g., <svg>) or @react-three/fiber (e.g., <color>). Prefixed elements remain available even after enabling unprefixed ones.

    // global.d.ts
    import { type UnprefixedPixiElements } from '@pixi/react';
    
    declare module '@pixi/react'
    {
        interface PixiElements extends UnprefixedPixiElements {}
    }
  3. Enable unprefixed Pixi elements in TypeScript

    main

    By default, components use the pixi prefix (e.g., <pixiContainer />). To enable unprefixed elements (e.g., <container />), extend the PixiElements interface with UnprefixedPixiElements.

    Note: Prefixed elements are still available even if unprefixed elements are enabled to avoid collisions with other libraries like react-dom or @react-three/fiber.

    // global.d.ts
    import { type UnprefixedPixiElements } from '@pixi/react'
    
    declare module '@pixi/react' {
      interface PixiElements extends UnprefixedPixiElements {}
    }
  4. Add custom components to TypeScript definitions

    main

    To use custom components (registered via extend) with TypeScript, you must add them to the PixiElements interface in a declaration file.

    // global.d.ts
    import { type PixiReactElementProps } from '@pixi/react'
    import { type Viewport } from 'pixi-viewport'
    
    declare module '@pixi/react' {
      interface PixiElements {
        viewport: PixiReactElementProps<typeof Viewport>;
      }
    }
  5. Create custom components using the extend API

    main

    You can integrate third-party PixiJS classes as React components using the extend API. When you pass a class to extend, @pixi/react makes a corresponding component available using a lower-case version of the class name (e.g., Viewport becomes <pixiViewport />).

    Note: extend registers the component for runtime use, but it does not provide automatic TypeScript definitions. If you are using TypeScript, you must manually declare the component and its props to avoid type errors.

    import {
        Application,
        extend,
    } from '@pixi/react';
    import { Viewport } from 'pixi-viewport';
    
    // Register the component
    extend({ Viewport });
    
    const MyComponent = () => (
        <Application>
            {/* Use the lower-case prefixed name */}
            <pixiViewport>
                <pixiContainer />
            </pixiViewport>
        </Application>
    );
  6. Use the `<Application>` component to wrap your app

    main

    The <Application> component is the root component used to wrap your @pixi/react application. It accepts all props available in the PIXI.ApplicationOptions configuration for PIXI.Application.

    import { Application } from '@pixi/react';
    
    const MyComponent = () => (
        <Application autoStart sharedTicker />
    );
  7. Extend built-in component props with TypeScript

    main

    To add custom properties to existing built-in components, use the PixiElements type to access the base props for a specific element. You can then intersect this type with your own property definitions.

    import { type Texture } from 'pixi.js';
    import { type PixiElements } from '@pixi/react';
    
    export type TilingSpriteProps = PixiElements['pixiTilingSprite'] & {
        image?: string;
        texture?: Texture;
    };
  8. Extend @pixi/react with Pixi.js components

    main

    In v8, @pixi/react uses an internal catalogue of components populated via the extend API. This approach allows you to selectively import only the Pixi.js components you need, which helps keep bundle sizes small. To make a Pixi.js component available as a JSX component, pass it to the extend function.

    Once extended, the component is available in JSX using a lowercase prefix (e.g., Container becomes <pixiContainer />).

    import {
        Application,
        extend,
    } from '@pixi/react';
    import { Container } from 'pixi.js';
    
    // Register the Pixi.js component
    extend({ Container });
    
    const MyComponent = () => (
        // Use the component with the 'pixi' prefix
        <pixiContainer />
    );
  9. Use Pixi.js classes as React components

    main

    Every class exported from pixi.js is available as a React component in @pixi/react using the pixi prefix. All properties of the underlying Pixi.js class are available as props on the corresponding component. This allows you to declaratively define your Pixi scene using React syntax.

    <pixiContainer x={100} y={100}>
        <pixiSprite anchor={{ 0.5, 0.5 }} texture={texture} />
    </pixiContainer>
  10. Quick Start with @pixi/react

    main

    To use PixiJS components declaratively in React, you must first use the extend function to register PixiJS classes as React components. Once extended, the classes are available as lowercase JSX elements (e.g., Container becomes <pixiContainer />).

    Wrap your component tree in the <Application /> component provided by @pixi/react to initialize the PixiJS application.

    import {
      Application,
      extend,
    } from '@pixi/react'
    import {
      Container,
      Graphics,
    } from 'pixi.js'
    import { useCallback } from 'react'
    
    // Register PixiJS classes as React components
    extend({
      Container,
      Graphics,
    })
    
    const MyComponent = () => {
      const drawCallback = useCallback(graphics => {
        graphics.clear()
        graphics.setFillStyle({ color: 'red' })
        graphics.rect(0, 0, 100, 100)
        graphics.fill()
      }, [])
    
      return (
        <Application>
          {/* Use the extended components with lowercase 'pixi' prefix */}
          <pixiContainer x={100} y={100}>
            <pixiGraphics draw={drawCallback} />
          </pixiContainer>
        </Application>
      )
    }
  11. Avoid performance issues with useTick by memoising callbacks

    main

    The callback passed to useTick is not memoised. If you pass an inline function or a non-memoised function that depends on component state, the callback may be removed and re-added to the ticker on every single frame. This can cause significant performance degradation or unexpected behavior if the component re-renders frequently.

    To prevent this, always wrap your callback in useCallback to ensure the function reference remains stable across renders.

    import {
        Application,
        useTick,
    } from '@pixi/react';
    import { useCallback, useState } from 'react'
    
    const ChildComponent = () => {
        const [rotation, setRotation] = useState(0)
    
        // Memoise the callback to prevent re-adding to the ticker every frame
        const animateRotation = useCallback(() => setRotation(previousState => previousState + 1), []);
    
        useTick(animateRotation);
    
        return <pixiSprite rotation={rotation} />;
    };
    
    const MyComponent = () => (
        <Application>
            <ChildComponent />
        </Application>
    );