Skip to main content

Create Your First Item

XRift items are reusable 3D components that can be placed inside worlds. They are implemented with React Three Fiber and distributed via Module Federation. In this tutorial, we will explain how to create, customize, and upload an item project using the XRift CLI.

Prerequisites

  • Node.js 18.0.0 or higher
  • XRift CLI installed

Step 1: Create a Project

Create a new item project:

xrift create item my-first-item
cd my-first-item

You can set the project name and item title/description interactively. You can skip this with the -y option.

By default, WebXR-JP/xrift-item-template is used. You can specify a different template with -t <repository>.

Step 2: Start the Development Server

npm run dev

Open http://localhost:5173 in your browser to preview the item locally. The development server uses src/dev.tsx as its entry point and provides a Canvas, Physics, and OrbitControls environment to inspect your item.

Step 3: Understand the Template Layout

The generated project comes with a working sample item:

my-first-item/
├── src/
│ ├── Item.tsx # The item component itself
│ ├── index.tsx # Module Federation export entry
│ └── dev.tsx # Dev server entry (not included in production build)
├── xrift.json # Item configuration
├── vite.config.ts # Build & Module Federation setup
└── package.json

What the Template Includes

  • A rotating crystal — sample animation using useFrame
  • A base with physics — a fixed-type RigidBody with a collider
  • A point light — emulates crystal glow

Step 4: Customize the Item

Edit src/Item.tsx to customize your item. Items export an Item component that receives position and scale from the host world.

import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import { RigidBody } from '@react-three/rapier';
import { Mesh } from 'three';

export interface ItemProps {
position?: [number, number, number];
scale?: number;
}

export const Item: React.FC<ItemProps> = ({ position = [0, 0, 0], scale = 1 }) => {
const meshRef = useRef<Mesh>(null);

useFrame((_state, delta) => {
if (meshRef.current) {
meshRef.current.rotation.y += delta;
}
});

return (
<group position={position} scale={scale}>
<RigidBody type="fixed" colliders="cuboid">
<mesh ref={meshRef} castShadow>
<boxGeometry args={[0.5, 0.5, 0.5]} />
<meshStandardMaterial color="orange" />
</mesh>
</RigidBody>
</group>
);
};
tip

Keep the shape of ItemProps (accepting position and scale). The XRift platform passes transforms to your item through these props when it is placed.

Add Physics

Items use the same @react-three/rapier physics engine as worlds:

import { RigidBody } from '@react-three/rapier';

{/* Static object that doesn't move */}
<RigidBody type="fixed" colliders="cuboid">
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="gray" />
</mesh>
</RigidBody>

{/* Object affected by gravity and collisions */}
<RigidBody type="dynamic">
<mesh>
<sphereGeometry args={[0.5]} />
<meshStandardMaterial color="red" />
</mesh>
</RigidBody>

Using Three.js Addons

When using Three.js addon modules such as DRACOLoader or GLTFLoader, import them from three/addons/*:

// OK: kept in the shared chunk
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

This prevents addon modules from being inlined into the item bundle. If inlined, @xrift/code-security may flag new Worker() inside them as a critical violation. See Shared Dependencies for details.

Step 5: Run a Security Check

You can run a code security check before uploading:

xrift check item

To run the build alongside the check:

xrift check item --build

Step 6: Build and Upload

Create a production build:

npm run build

Upload to the XRift platform:

xrift upload item

On the first upload, you will be prompted for a title (required) and description (optional). If item.title is already set in xrift.json, the prompt is skipped.

After uploading, a code review runs automatically (usually completed in a few minutes). Once approved, the item is published and becomes available from your inventory.

Next Steps