
Research
SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.
@pixi/react
Advanced tools
@pixi/react
Simply the best way to write PixiJS applications in React
Write PixiJS applications using React declarative style 👌
@pixi/react is an open-source, production-ready library to render high performant PixiJS applications in React.
If you want to start a new React project from scratch then we recommend Create React App, but @pixi/react should work with any React application (Remix, Next.js, etc).
To add @pixi/react to an existing React application, just install the dependencies:
npm install pixi.js@^8.2.6 @pixi/react
import {
Application,
extend,
} from '@pixi/react'
import {
Container,
Graphics,
} from 'pixi.js'
import { useCallback } from 'react'
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>
<pixiContainer x={100} y={100}>
<pixiGraphics draw={drawCallback} />
</pixiContainer>
</Application>
)
}
extendOne of the most important concepts to understand with v8 is extend. Normally @pixi/react would have to import all pf Pixi.js to be able to provide the full library as JSX components. Instead, we use an internal catalogue of components populated by the extend API. This allows you to define exactly which parts of Pixi.js you want to import, keeping your bundle sizes small.
To allow @pixi/react to use a Pixi.js component, pass it to the extend API:
import { Container } from 'pixi.js'
import { extend } from '@pixi/react'
extend({ Container })
const MyComponent = () => (
<pixiContainer />
)
[!CAUTION] Attempting to use components that haven't been passed to the
extendAPI will result in errors.
<Application>The <Application> component is used to wrap your @pixi/react app. The <Application> component can take all props that can be set on PIXI.Application.
import { Application } from '@pixi/react'
const MyComponent = () => {
return (
<Application
autoStart
sharedTicker />
)
}
defaultTextStyledefaultTextStyle is a convenience property. Whatever is passed will automatically be assigned to Pixi.js's TextStyle.defaultTextStyle.
[!NOTE] This property is not retroactive. It will only apply to text components created after
defaultTextStyleis set. Any text components created before settingdefaultTextStylewill retain the base styles they had beforedefaultTextStylewas changed.
extensionsextensions is an array of extensions to be loaded. Adding and removing items from this array will automatically load/unload the extensions. The first time this is handled happens before the application is initialised. See Pixi.js's extensions documentation for more info on extensions.
resizeToThe <Application> component supports the resizeTo property, with some additional functionality: it can accept any HTML element or it can take a React ref directly.
import { Application } from '@pixi/react'
import { useRef } from 'react'
const MyComponent = () => {
const parentRef = useRef(null)
return (
<div ref={parentRef}>
<Application resizeTo={parentRef} />
</div>
)
}
All other components should be included in your IDE's intellisense/autocomplete once you've installed/imported @pixi/react. If it's exported from Pixi.js, it's supported as a component with the pixi prefix. Here's a selection of commonly used components:
<pixiContainer />
<pixiGraphics />
<pixiSprite />
<pixiAnimatedSprite />
<pixiText />
<pixiHtmlText />
<pixiGraphics>The pixiGraphics component has a special draw property. draw takes a callback which receives the Graphics context, allowing drawing to happen on every tick.
const MyComponent = () => {
return (
<pixiGraphics draw={graphics => {
graphics.clear()
graphics.setFillStyle({ color: 'red' })
graphics.rect(0, 0, 100, 100)
graphics.fill()
}} />
)
}
@pixi/react supports custom components via the extend API. For example, you can create a <viewport> component using the pixi-viewport library:
import { extend } from '@pixi/react'
import { Viewport } from 'pixi-viewport'
extend({ Viewport })
const MyComponent = () => {
<viewport>
<pixiContainer />
</viewport>
}
The extend API will teach @pixi/react about your components, but TypeScript won't know about them nor their props. If you're using Typescript, check out our docs for Typescript Users.
useApplicationuseApplication allows access to the parent PIXI.Application created by the <Application> component. This hook will not work outside of an <Application> component. Additionally, the parent application is passed via React Context. This means useApplication will only work appropriately in child components, and in the same component that creates the <Application>.
For example, the following example useApplication will not be able to access the parent application:
import {
Application,
useApplication,
} from '@pixi/react'
const ParentComponent = () => {
// This will cause an invariant violation.
const { app } = useApplication()
return (
<Application />
)
}
Here's a working example where useApplication will be able to access the parent application:
import {
Application,
useApplication,
} from '@pixi/react'
const ChildComponent = () => {
const { app } = useApplication()
console.log(app)
return (
<container />
)
}
const ParentComponent = () => (
<Application>
<ChildComponent />
</Application>
)
useExtenduseExtend allows the extend API to be used as a React hook. Additionally, the useExtend hook is memoised, while the extend function is not.
import { Container } from 'pixi.js'
import { useExtend } from '@pixi/react'
const MyComponent = () => {
useExtend({ Container })
return (
<container />
)
}
useTickuseTick allows a callback to be attached to the Ticker on the parent application.
import { useTick } from '@pixi/react'
const MyComponent = () => {
useTick(() => console.log('This will be logged on every tick'))
}
useTick optionally takes an options object. This allows control of all ticker.add options, as well as adding the isEnabled option. Setting isEnabled to false will cause the callback to be disabled until the argument is changed to true again.
import { useState } from 'react'
import { useTick } from '@pixi/react'
const MyComponent = () => {
const [isEnabled, setIsEnabled] = useState(false)
useTick(() => console.log('This will be logged on every tick as long as `isEnabled` is `true`'), isEnabled)
return (
<sprite onClick={setIsEnabled(previousState => !previousState)}>
)
}
[!CAUTION] The callback passed to
useTickis not memoised. This can cause issues where your callback is being removed and added back to the ticker on every frame if you're mutating state in a component whereuseTickis using a non-memoised function. For example, this issue would affect the component below because we are mutating the state, causing the component to re-render constantly:import { useState } from 'react' import { useTick } from '@pixi/react' const MyComponent = () => { const [count, setCount] = useState(0) useTick(() => setCount(previousCount => previousCount + 1)) return null }This issue can be solved by memoising the callback passed to
useTick:import { useCallback, useState, } from 'react' import { useTick } from '@pixi/react' const MyComponent = () => { const [count, setCount] = useState(0) const updateCount = useCallback(() => setCount(previousCount => previousCount + 1), []) useTick(updateCount) }
@pixi/react already offers types for built-in components, but custom components need to be added to the library's type catalogue so it knows how to handle them. This can be achieved by adding your custom components to the PixiElements interface. Here's what it may look like to add the viewport component from our earlier extend example:
// 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>;
}
}
Now you'll be able to use your custom component in your project without any type errors!
If you like to live life on the wild side, you can enable unprefixed Pixi elements (i.e. <container> instead of <pixiContainer>) by adding the UnprefixedPixiElements interface to the PixiElements interface.
// global.d.ts
import { type UnprefixedPixiElements } from '@pixi/react'
declare module '@pixi/react' {
interface PixiElements extends UnprefixedPixiElements {}
}
The prefixed and unprefixed elements have the same functionality, but we recommend sticking to the prefixed components to avoid collisions with other libraries that add intrinsic elements to JSX (such as react-dom and @react-three/fiber).
[!IMPORTANT] Some components conflict with other libaries, such as
<svg>inreact-domand<color>in@react-three/fiber. To address this thepixiprefixed elements are always available, even after injecting the unprefixed elements.
The props for built-in components are available on the PixiElements type and can be used to extend the built-in types.
import { type PixiElements } from '@pixi/react'
export type TilingSpriteProps = PixiElements['pixiTilingSprite'] & {
image?: string;
texture?: Texture;
};
FAQs
Write PixiJS applications using React declarative style.
The npm package @pixi/react receives a total of 27,855 weekly downloads. As such, @pixi/react popularity was classified as popular.
We found that @pixi/react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.

Company News
Socket is proud to join the OpenJS Foundation as a Silver Member, deepening our commitment to the long-term health and security of the JavaScript ecosystem.

Security News
npm now links to Socket's security analysis on every package page. Here's what you'll find when you click through.