Professional Android Device Manager - A modern, cross-platform desktop GUI for Android Debug Bridge (ADB)
Built with Tauri, React, and Tailwind CSS, DroidOps simplifies Android device management through an intuitive interface for operations that typically require command-line interaction.
- 📊 Device Dashboard - Real-time device info including model, Android version, and battery status
- 📱 App Manager - List, install, and uninstall applications with ease
- 📁 File Explorer - Browse and manage device files with drag-and-drop support
- 🖼️ Gallery - View device photos organized by albums with thumbnail caching
- ⚡ Fastboot Tools - Dedicated interface for bootloader operations
- 📦 Sideloading - Streamlined APK installation via drag-and-drop
- 💻 ADB Shell - Integrated terminal for direct ADB command execution
| Layer | Technology |
|---|---|
| Core | Tauri v2 (Rust) |
| Frontend | React + Vite |
| Styling | Tailwind CSS v4 |
| Icons | Lucide React |
| State | React Hooks |
Ensure you have the following installed:
- Node.js (LTS recommended)
- Rust & Cargo (for Tauri)
- ADB (Android Debug Bridge) - Added to system PATH
- Visual Studio C++ Build Tools (Windows only)
-
Clone the repository:
git clone https://github.com/bbinxx/droidops.git cd droidops -
Install dependencies:
npm install
-
Run in development mode:
npm run tauri dev
npm run tauri buildBuild artifacts will be in src-tauri/target/release/bundle/
src/
├── components/ # Reusable UI components
│ ├── DeviceSelector.jsx
│ ├── FileExplorer.jsx
│ ├── Gallery.jsx
│ └── Sidebar.jsx
├── pages/ # Page-level components
│ ├── Dashboard.jsx
│ ├── AppManager.jsx
│ ├── ShellPage.jsx
│ ├── FastbootPage.jsx
│ └── SideloadPage.jsx
├── lib/ # Core functionality
│ ├── adb.js # ADB command wrappers
│ └── cache.js # File caching utilities
├── data/ # Configuration & strings
│ ├── strings.js # All UI text/labels (i18n-ready)
│ └── config.js # App configuration & constants
├── hooks/ # Custom React hooks
│ └── useStrings.js # String management hook
├── utils/ # Utility functions
│ └── dialog.js # Standardized dialogs
└── App.jsx # Main application
DroidOps uses a fully modular, data-driven architecture making it easy to:
- 🌐 Add internationalization (i18n)
- 🔧 Modify configuration without touching code
- 🎨 Maintain consistent UI/UX
- 🧩 Extend features easily
All UI text is centralized in src/data/strings.js:
import { STRINGS, formatString } from '../data/strings';
// Direct access
const title = STRINGS.dashboard.title;
// With placeholders
const message = formatString(STRINGS.apps.confirmUninstall, { app: 'MyApp' });String Categories:
app- Application metadatanavigation- Menu labelsdevice- Device-related stringsdashboard,apps,files,gallery- Page-specific stringserrors- Error messagescommon- Common UI strings
App-wide settings in src/data/config.js:
import { APP_CONFIG, ROUTES, DEVICE_STATES } from '../data/config';
// Use configuration
const theme = APP_CONFIG.ui.defaultTheme;
// Use route constants
navigate(ROUTES.DASHBOARD);
// Use device states
if (device.state === DEVICE_STATES.OFFLINE) { ... }import { confirmDelete, confirmUninstall, alertDialog } from '../utils/dialog';
// Confirm actions
if (confirmDelete(fileName)) {
deleteFile();
}
// Show alerts
alertDialog(STRINGS.files.uploadSuccess);- Framework: Tailwind CSS
- Theme: Dark by default
- Color Palette:
- Primary:
#2ca9bc - Background:
#0f0f12 - Surface:
#1a1a1f - Border:
#27272a
- Primary:
// 1. React & third-party
import React, { useState } from 'react';
import { Icon } from 'lucide-react';
// 2. Data & config
import { STRINGS } from '../data/strings';
import { APP_CONFIG } from '../data/config';
// 3. Utilities & hooks
import { useStrings } from '../hooks/useStrings';
import { confirmDialog } from '../utils/dialog';
// 4. Local imports
import { myFunction } from '../lib/myLib';// ❌ Bad
if (activeTab === "dashboard") { ... }
// ✅ Good
import { ROUTES } from '../data/config';
if (activeTab === ROUTES.DASHBOARD) { ... }// ❌ Bad
<button>Delete</button>
// ✅ Good
<button>{STRINGS.files.delete}</button>- Create page component in
src/pages/ - Add route to
ROUTESinconfig.js - Add strings to appropriate section in
strings.js - Register route in
App.jsx - Add navigation item to
Sidebar.jsx
- Add to
src/data/strings.js:
export const STRINGS = {
myFeature: {
title: "My Feature",
description: "Description here",
action: "Action button label"
}
};- Use in component:
import { STRINGS } from '../data/strings';
<h1>{STRINGS.myFeature.title}</h1>- Add to
src/data/config.js:
export const APP_CONFIG = {
myFeature: {
setting1: true,
setting2: "value"
}
};- Use in code:
import { APP_CONFIG } from '../data/config';
if (APP_CONFIG.myFeature.setting1) { ... }- ✅ Keep components focused - Single responsibility
- ✅ Use data files - No hardcoded strings/config
- ✅ Leverage hooks - Extract reusable logic
- ✅ Handle errors gracefully - Use standardized dialogs
- ✅ Document new features - Update documentation
When updating existing code:
- Replace hardcoded strings with
STRINGSreferences - Replace magic values with
APP_CONFIGconstants - Use
ROUTESfor navigation logic - Use dialog utilities instead of raw
window.confirm/alert - Extract reusable logic into hooks
Contributions are welcome! Please follow the modular architecture and coding standards outlined above.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Follow the component guidelines and use data-driven design
- Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License.
Built with ❤️ using modern web technologies and Rust for a fast, secure, and beautiful desktop experience.