<R1 Create SDK />
r1-create
Unofficial community JavaScript/TypeScript SDK for building R1/RabbitOS plugins with full hardware access, AI integration, and mobile optimization.
Features
- 🔧 Hardware Access: Accelerometer, touch simulation, PTT button, scroll wheel
- 💾 Storage: Secure and plain storage with automatic Base64 encoding
- 🤖 LLM Integration: Direct interaction with R1's AI system + text-to-speech
- 🌐 Web Search: SERP API integration for real-time information
- 📱 Optimized UI: Purpose-built for 240x282px display with hardware acceleration
- 🎨 UI Design System: Responsive components and design utilities
- 🎥 Media APIs: Camera, microphone, speaker with web standard compatibility
- 🎮 Device Controls: Convenient hardware event management
- ⚡ Performance: Minimal DOM operations, hardware-accelerated CSS
- 📦 TypeScript: Full type definitions and IntelliSense support
Installation
npm install r1-create Quick Start
import { r1, createR1App, deviceControls, ui } from 'r1-create';
// Simple setup
createR1App(async (sdk) => {
console.log('R1 App initialized!');
// Setup UI
ui.setupViewport();
// Setup device controls
deviceControls.init();
deviceControls.on('sideButton', () => {
console.log('Side button clicked!');
});
// Text-to-speech
await sdk.messaging.speakText('Hello from R1!');
// Ask the LLM something
await sdk.llm.askLLMSpeak('Hello, how are you today?');
}); Core APIs
Hardware
// Accelerometer
await r1.accelerometer.start((data) => {
console.log(`Tilt: x=${data.x}, y=${data.y}, z=${data.z}`);
});
// Touch simulation
r1.touch.tap(120, 141); // Center of screen
// Hardware buttons
r1.hardware.on('sideClick', () => console.log('PTT clicked'));
r1.hardware.on('scrollUp', () => console.log('Scroll up')); Storage
// Store user preferences (automatically Base64 encoded)
await r1.storage.plain.setItem('theme', { dark: true, color: 'blue' });
const theme = await r1.storage.plain.getItem('theme');
// Secure storage for sensitive data
await r1.storage.secure.setItem('api_key', 'secret123');
const apiKey = await r1.storage.secure.getItem('api_key', false); // Get as string LLM Integration
// Send message to LLM
await r1.messaging.sendMessage('What time is it?', { useLLM: true });
// Ask LLM to speak response
await r1.llm.askLLMSpeak('Tell me a joke', true); // Save to journal
// Direct text-to-speech (no LLM processing)
await r1.messaging.speakText('Hello world!');
await r1.llm.textToSpeech('This will be spoken directly');
// Web search with SERP API
await r1.messaging.searchWeb('current weather in Tokyo');
// Send message with plugin ID and image
await r1.messaging.sendMessage('Analyze this image', {
useLLM: true,
pluginId: 'image-analyzer',
imageBase64: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='
});
// Get structured JSON response
await r1.llm.askLLMJSON('List 3 facts about rabbits in JSON format');
// Handle responses
r1.messaging.onMessage((response) => {
if (response.parsedData) {
console.log('Parsed response:', response.parsedData);
}
}); Media APIs
// Camera
const stream = await r1.camera.start({ facingMode: 'user' });
const videoElement = r1.camera.createVideoElement();
document.body.appendChild(videoElement);
// Capture photo
const photo = r1.camera.capturePhoto(240, 282);
// Microphone
await r1.microphone.startRecording();
const audioBlob = await r1.microphone.stopRecording();
// Speaker
await r1.speaker.play(audioBlob);
await r1.speaker.playTone(440, 1000); // A note for 1 second UI Utilities
import { LayoutUtils, CSSUtils, R1_DIMENSIONS } from 'r1-create';
// Create R1-optimized container
const container = document.createElement('div');
LayoutUtils.applyR1Container(container);
// Hardware-accelerated animations
CSSUtils.setTransform(element, 'translateX(10px)');
CSSUtils.addTransition(element, 'transform', 300);
// Screen dimensions
console.log(`Screen: ${R1_DIMENSIONS.width}x${R1_DIMENSIONS.height}px`); UI Design System
import { ui } from 'r1-create';
// Setup viewport for proper scaling
ui.setupViewport();
// Create responsive button
const button = document.createElement('button');
ui.createButton(button, { type: 'wide', background: '#FE5F00' });
button.textContent = 'Press Me';
// Create responsive text
const title = document.createElement('h1');
ui.createText(title, { size: 'title', color: '#FFFFFF' });
title.textContent = 'Welcome';
// Create grid layout
const grid = document.createElement('div');
ui.createGrid(grid, { columns: 2, gap: ui.getSpacing().md });
// Get design tokens
const colors = ui.getColors();
const fonts = ui.getFontSizes();
const spacing = ui.getSpacing();
// Convert pixels to viewport units
const vwValue = ui.pxToVw(30); // "12.5vw" Device Controls
import { deviceControls } from 'r1-create';
// Initialize with options
deviceControls.init({
sideButtonEnabled: true,
scrollWheelEnabled: true,
keyboardFallback: true // Space bar simulates side button
});
// Register event handlers
deviceControls.on('sideButton', (event) => {
console.log('Side button pressed');
});
deviceControls.on('scrollWheel', (data) => {
console.log('Scrolled', data.direction); // 'up' or 'down'
});
// Control enable/disable
deviceControls.setSideButtonEnabled(false);
deviceControls.setScrollWheelEnabled(true);
// Programmatic triggering (for testing)
deviceControls.triggerSideButton(); Advanced Usage
Custom Plugin Class
import { R1Plugin } from 'r1-create';
const plugin = new R1Plugin({
onMount: () => console.log('Plugin mounted'),
onMessage: (data) => console.log('Received:', data),
onHardwareEvent: (event) => console.log('Hardware event:', event)
});
plugin.mount(); Performance Monitoring
import { PerformanceUtils } from 'r1-create';
// Measure performance
PerformanceUtils.startMeasure('animation');
// ... do animation work
PerformanceUtils.endMeasure('animation');
// Monitor frame rate
PerformanceUtils.monitorFPS(5, (fps) => {
console.log(`Average FPS: ${fps}`);
}); Best Practices
- Optimize for Mobile: Use hardware-accelerated CSS properties (transform, opacity)
- Minimize DOM Operations: Use
DOMUtils.batchOperations()for multiple changes - Handle Storage Errors: Always check if storage is available before use
- Audio Context: Initialize audio on user interaction for browser compatibility
- Memory Management: Clean up event listeners and media streams