react-native-car-projection
v1.0.0
Published
React Native module for Android Auto and CarPlay integration
Maintainers
Readme
React Native Car Projection [VIBE CODED]
⚠️ NOTE: I am not a native mobile developer, so I vibe-coded this for my own purposes. Use at your own risk.
A modern React Native module for integrating Android Auto and CarPlay functionality using the Car App Library and Expo Modules API. Built for Expo SDK 53+ with React Native 0.79 and React 19 support.
🚀 Features
- ✅ Modern Architecture: Built with Expo Modules API and Android Car App Library
- ✅ Expo SDK 53+ Compatible: Works with React Native 0.79 and React 19
- ✅ TypeScript Support: Full TypeScript definitions included
- ✅ Template System: ListTemplate, MessageTemplate, and more
- ✅ Easy Integration: Simple setup with config plugin
- ✅ Event Handling: React to user interactions and navigation changes
- ✅ New Architecture Ready: Supports React Native's new architecture
📋 Prerequisites
- Expo SDK 53 or later
- React Native 0.79+
- React 19+
- Android API level 23+
- Android Auto app installed on device
🏁 Installation
1. Install the module
npm install react-native-car-projection
# or
yarn add react-native-car-projection2. Add the config plugin
Add the plugin to your app.json or expo.json:
{
"expo": {
"plugins": [
[
"react-native-car-projection",
{
"carAppCategory": "navigation",
"minCarApiLevel": 1,
"targetCarApiLevel": 6
}
]
]
}
}3. Rebuild your app
npx expo prebuild --clean
npx expo run:androidExample apps (app types)
The plugin supports three app types. Example apps for each are available in the TestCarProjection repository under the examples/ directory:
| Type | Config | Description | Example app |
|------|--------|-------------|-------------|
| Car App only (no media) | mediaSupport: false, mediaOnly: false, carAppCategory e.g. "navigation" | No MediaBrowserService. Car App template UI only. | examples/TestCarAppOnly |
| Car App + media | mediaOnly: false, mediaSupport: true | Car App Service and MediaBrowserService. Template UI and now-playing slot. | examples/TestCarAppPlusMedia |
| Media only | mediaOnly: true, mediaSupport: true | MediaBrowserService only (no Car App). Browse + now-playing, like Spotify. | examples/TestMediaOnly |
Each example app runs on both iOS and Android; Android Auto–specific behavior applies on Android when connected to a head unit or DHU. See examples/README.md for how to run them.
🎯 Quick Start
import React, { useEffect } from 'react';
import CarProjection, { createListTemplate } from 'react-native-car-projection';
export default function App() {
useEffect(() => {
// Register your root screen
CarProjection.registerScreen({
name: 'root',
template: createListTemplate({
title: 'My App',
header: 'Main Menu',
items: [
{
title: 'Navigation',
texts: ['Start navigation'],
onPress: () => {}
}
]
})
});
// Start the session
CarProjection.startSession();
}, []);
return <YourAppContent />;
}Media-only mode: browse content (setMediaBrowseTree)
When using mediaOnly: true, you can set the MediaBrowser browse tree so the car shows available items (e.g. Recently Played, playlists, tracks). Call setMediaBrowseTree with a map where keys are parent IDs and values are arrays of MediaItem. The root key must be "__ROOT__". Use addMediaPlayFromIdListener to start playback when the user taps a playable item.
// Example: root with one folder and one track
await CarProjection.setMediaBrowseTree({
__ROOT__: [
{ id: 'playlist_1', title: 'Recently Played', browsable: true, playable: false },
{ id: 'track_1', title: 'Song Title', artist: 'Artist', playable: true },
],
playlist_1: [
{ id: 'track_2', title: 'Another Song', artist: 'Artist', playable: true },
],
});
CarProjection.addMediaPlayFromIdListener((event) => {
// Start playing the track with id event.mediaId
playTrackById(event.mediaId);
});For more detailed documentation, see the full README in the repository.
