Skip to main content

Overview

APK Extractor lets you download APK files from installed applications on Android devices. It automatically detects whether an app is a single APK or split APK, and handles XAPK compilation for split APKs.

Application List

Viewing Installed Apps

Both web and CLI interfaces show installed applications:
  1. Select a device from the sidebar
  2. Choose filter: User Apps, System Apps, or All Apps
  3. Wait for the app list to load
  4. Browse, search, or extract

Filter Types

User Apps

Apps installed by the user from Play Store or APK files (recommended for most use cases)

System Apps

Pre-installed system apps and services (often protected, may fail to extract)

All Apps

Both user and system apps (can be 200+ apps, slower loading)
API endpoint:
// Get user apps only (default)
GET /api/devices/:serial/apps?type=user

// Get system apps
GET /api/devices/:serial/apps?type=system

// Get all apps
GET /api/devices/:serial/apps
Implementation (server.js:288-302):
app.get('/api/devices/:serial/apps', async (req, res) => {
  const { serial } = req.params;
  const { type = 'user' } = req.query;
  const flag = type === 'user' ? '-3' : type === 'system' ? '-s' : '';
  
  const out = await runAdb(`shell pm list packages ${flag}`, serial, 30000);
  const packages = out.split('\n')
    .map(l => l.trim().replace(/^package:/, ''))
    .filter(Boolean)
    .sort();
  
  res.json({ packages, total: packages.length });
});
System apps are usually read-only and protected. Extracting them may fail with “insufficient permissions” errors.

App Information

For each app, APK Extractor displays:
  • App Name: Real application name (e.g., “WhatsApp”), not just package ID
  • Package ID: Java-style identifier (e.g., com.whatsapp)
  • Format: APK (single file) or Split APK (multiple files)
  • Size: Exact size in MB, calculated from device storage
App names are extracted using a 3-tier fallback:
  1. nonLocalizedLabel from dumpsys package
  2. label field from package metadata
  3. Humanized package name (last segment, capitalized)

Batch Info Loading

The web interface uses batch info loading for performance:
// Request info for 100+ packages in parallel
POST /api/devices/:serial/apps/batch-info
{
  "packages": ["com.android.chrome", "com.whatsapp", "com.spotify.music", ...]
}

// Response with all details
{
  "results": {
    "com.android.chrome": {
      "format": "APK",
      "isSplit": false,
      "sizeMB": "89.2 MB",
      "appName": "Chrome"
    },
    "com.whatsapp": {
      "format": "Split APK",
      "isSplit": true,
      "sizeMB": "67.4 MB",
      "appName": "WhatsApp"
    }
  }
}
This parallel processing loads 200+ apps in seconds instead of minutes.

Searching Apps

Type in the search box to filter by:
  • Application name (case-insensitive)
  • Package identifier
// Real-time filtering
const searchTerm = 'whats';
const filtered = apps.filter(app => 
  app.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
  app.package.toLowerCase().includes(searchTerm.toLowerCase())
);
Examples:
  • Search "chrome" → finds “Chrome”, “Chrome Dev”, etc.
  • Search "com.google" → finds all Google packages
  • Search "face" → finds “Facebook”, “Facebook Messenger”, etc.

CLI “Search”

The CLI doesn’t have built-in search, but you can:
  1. Use the paginated list (15 apps per page)
  2. Note the app number
  3. Jump directly to it by entering the number
For faster CLI searching, pipe the output through findstr:
adb -s SERIAL shell pm list packages | findstr chrome

Extracting Single APKs

Identifying Single APKs

Apps with “APK” format have one file and can be extracted directly:
Paquete: com.android.chrome
Formato: APK
Tamaño: 89.2 MB

Extraction Process

1

Select app

Click “Extract APK” button (web) or select the app number (CLI).
2

Get APK path

APK Extractor queries the device for the APK location:
adb -s SERIAL shell pm path com.android.chrome
# Output: package:/data/app/~~xyz==/com.android.chrome-abc==/base.apk
3

Pull from device

The APK is downloaded using adb pull:
adb -s SERIAL pull "/data/app/.../base.apk" "C:\Temp\com.android.chrome.apk"
Web: Streams directly to browser download CLI: Saves to chosen folder (default: Desktop)
4

Download complete

The file is ready to install on other devices or archive.

Web Interface Extraction

Implementation (server.js:406-443):
app.post('/api/devices/:serial/apps/:package/extract', async (req, res) => {
  const { serial, package: pkg } = req.params;
  
  // Get APK path from device
  const pathOut = await tryRunAdb(`shell pm path ${pkg}`, serial);
  const paths = pathOut.split('\n').map(l => l.replace('package:', '').trim()).filter(Boolean);
  
  if (paths.length === 0) {
    return res.status(400).json({ error: 'No se pudo obtener la ruta del APK.' });
  }
  
  if (paths.length > 1) {
    return res.status(400).json({
      error: 'Split APK / XAPK detectado',
      detail: `Esta app tiene ${paths.length} archivos APK separados...`,
      isSplit: true
    });
  }
  
  // Pull to temp directory
  const devicePath = paths[0];
  const outFile = path.join(os.tmpdir(), 'apk-extractor', `${pkg}.apk`);
  await runAdb(`pull "${devicePath}" "${outFile}"`, serial, 60000);
  
  // Stream to browser
  res.setHeader('Content-Disposition', `attachment; filename="${pkg}.apk"`);
  res.setHeader('Content-Type', 'application/vnd.android.package-archive');
  const stream = fs.createReadStream(outFile);
  stream.pipe(res);
  stream.on('close', () => fs.unlinkSync(outFile)); // Cleanup
});
The file streams directly to the browser - no manual file handling needed.

CLI Extraction

For CLI users:
Carpeta de destino (Enter para usar el escritorio):
> C:\MyAPKs

Extrayendo APK...
Destino: C:\MyAPKs\com.android.chrome.apk

/data/app/.../base.apk: 1 file pulled. 89.3 MB/s (93456789 bytes in 1.001s)

╔══════════════════════════════════════════════════════╗
║  [OK] APK extraido exitosamente!                    ║
╚══════════════════════════════════════════════════════╝

Archivo guardado en:
  C:\MyAPKs\com.android.chrome.apk
The folder opens automatically in Windows Explorer.
Some system apps may be protected and fail extraction with “error: insufficient permissions”. User-installed apps always work.

Extracting Split APKs (XAPK)

What are Split APKs?

Modern Android apps often use App Bundles, which split the APK into multiple files:
  • base.apk - Core app logic
  • split_config.arm64_v8a.apk - CPU architecture-specific code
  • split_config.en.apk - English language resources
  • split_config.xxhdpi.apk - Screen density resources
You cannot install a split APK by installing just base.apk - you need all files.
XAPK format packages all split APKs into a single installable file with a manifest.json describing the structure.

Detecting Split APKs

APK Extractor shows “Split APK” format:
Paquete: com.whatsapp
Formato: Split APK
Tamaño: 67.4 MB
Archivos: 5
Attempting to extract as a regular APK will fail:
{
  "error": "Split APK / XAPK detectado",
  "detail": "Esta app tiene 5 archivos APK separados y no puede exportarse como un único .apk.",
  "isSplit": true,
  "paths": [
    "/data/app/.../base.apk",
    "/data/app/.../split_config.arm64_v8a.apk",
    ...
  ]
}
You must use “Compile XAPK” instead.

XAPK Compilation

1

Initiate compilation

Click “Compile XAPK” (web) or select [1] from the split APK menu (CLI).
2

Extract all APKs

APK Extractor pulls all APK files from the device in parallel:
const pullResults = await Promise.all(paths.map(async (p, idx) => {
  const fname = path.basename(p).replace(/\r/g, '');
  const localPath = path.join(tmpDir, fname || `split_${idx}.apk`);
  await runAdb(`pull "${p.trim()}" "${localPath}"`, serial, 120000);
  return { fname, ok: true };
}));
Progress: “Extraído 3/5: split_config.en.apk”
3

Create manifest.json

Generates an XAPK manifest with package metadata:
{
  "xapk_version": 2,
  "package_name": "com.whatsapp",
  "name": "WhatsApp",
  "version_code": "223412",
  "version_name": "2.23.4.12",
  "min_sdk_version": "21",
  "target_sdk_version": "34",
  "split_apks": [
    { "file": "base.apk", "id": "base" },
    { "file": "split_config.arm64_v8a.apk", "id": "split_config.arm64_v8a" },
    ...
  ],
  "expansions": []
}
4

Package as ZIP

All APKs + manifest.json are compressed into a ZIP file, then renamed to .xapk:
powershell -Command "Compress-Archive -Path 'temp\*' -DestinationPath 'output.zip'"
rename output.zip com.whatsapp.xapk
5

Download

Web: Automatically downloads to browser CLI: Saves to chosen folder and opens in Explorer

Real-Time Progress (Web)

The web interface shows live progress using Server-Sent Events (SSE):
GET /api/devices/:serial/apps/:package/compile-xapk

// SSE stream
data: {"msg":"Obteniendo rutas del APK en el dispositivo...","progress":5}
data: {"msg":"Encontrados 5 archivos APK. Extrayendo en paralelo...","progress":10}
data: {"msg":"Extraído 1/5: base.apk","progress":20}
data: {"msg":"Extraído 2/5: split_config.arm64_v8a.apk","progress":30}
...
data: {"msg":"Empaquetando XAPK...","progress":80}
data: {"msg":"XAPK listo. Descargando...","progress":95}
data: {"done":true,"ok":true,"fileReady":true,"size":70234567}
Client:
const eventSource = new EventSource(`/api/devices/${serial}/apps/${pkg}/compile-xapk`);

eventSource.onmessage = (event) => {
  const { msg, progress, done, ok, fileReady } = JSON.parse(event.data);
  
  if (done) {
    if (ok && fileReady) {
      // Trigger download
      window.location.href = `/api/devices/${serial}/apps/${pkg}/download-xapk`;
    }
    eventSource.close();
  } else {
    // Update progress bar
    updateProgress(progress, msg);
  }
};
XAPK compilation for large apps (100+ MB) can take 30-60 seconds. The progress bar keeps you informed.

CLI XAPK Compilation

The CLI shows detailed progress:
Paso 1/3: Extrayendo APKs del dispositivo...

  Extrayendo: base.apk
  [OK] base.apk
  Extrayendo: split_config.arm64_v8a.apk
  [OK] split_config.arm64_v8a.apk
  Extrayendo: split_config.en.apk
  [OK] split_config.en.apk
  Extrayendo: split_config.xxhdpi.apk
  [OK] split_config.xxhdpi.apk
  Extrayendo: split_config.xxxhdpi.apk
  [OK] split_config.xxxhdpi.apk

Paso 2/3: Creando manifest.json...
  [OK] manifest.json creado

Paso 3/3: Empaquetando en XAPK...

╔══════════════════════════════════════════════════════╗
║  [OK] XAPK compilado exitosamente!                  ║
╚══════════════════════════════════════════════════════╝

Archivo: C:\Users\YourName\Desktop\com.whatsapp.xapk

Puedes instalar el .xapk con:
  - XAPK Installer (APKPure)
  - APKMirror Installer
  - Mediante SAI (Split APKs Installer)

Installing Extracted APKs

Single APK Installation

Transfer the .apk file to the target Android device and:
  1. File Manager: Open the APK file, tap Install
  2. ADB Install:
    adb install com.android.chrome.apk
    
  3. Drag & Drop: In Android emulator
Enable “Install from unknown sources” in Android settings if installing APKs outside the Play Store.

XAPK Installation

XAPK files require a special installer:

SAI

Split APKs Installer - Open source, recommended

APKPure

APKPure app includes XAPK Installer

APKMirror

APKMirror Installer app
Steps:
  1. Install SAI (or another XAPK installer) on the target device
  2. Transfer the .xapk file
  3. Open with the installer app
  4. Tap Install - the installer extracts and installs all APKs
You cannot install XAPK by renaming to .zip and extracting manually. The installer handles signature verification and proper installation order.

Batch Extraction (Advanced)

While the UI focuses on one app at a time, you can script batch extraction via the API:
// Extract multiple apps from a device
const serial = '1A2B3C4D5E6F';
const packages = ['com.android.chrome', 'com.whatsapp', 'com.spotify.music'];

for (const pkg of packages) {
  const response = await fetch(`/api/devices/${serial}/apps/${pkg}/info`);
  const { isSplit } = await response.json();
  
  if (isSplit) {
    // Compile XAPK (handle SSE stream)
    console.log(`Compiling XAPK for ${pkg}...`);
    // (SSE handling code)
  } else {
    // Extract single APK
    const apkResponse = await fetch(`/api/devices/${serial}/apps/${pkg}/extract`, {
      method: 'POST'
    });
    const blob = await apkResponse.blob();
    // Save blob to file
  }
}
For true batch automation, write a Node.js script that loops through apps and uses the API endpoints directly.

Troubleshooting

The app is a protected system app. User-installed apps can always be extracted, but some system apps are protected.Solution: Only extract user apps, or try with root access (not officially supported).
Common causes:
  • Different CPU architecture: Extract from ARM64 device, trying to install on ARM32
  • Minimum SDK mismatch: App requires newer Android version
  • Signature mismatch: If the app is already installed with a different signature
Solutions:
  • Check target device compatibility
  • Uninstall existing app first
  • Use XAPK for split APKs (includes all architecture splits)
Possible causes:
  • Device disconnected during extraction
  • Insufficient disk space on PC
  • ADB timeout (large app, slow connection)
Solutions:
  • Keep device connected (use USB for stability)
  • Free up disk space
  • Increase timeout in server.js (change 120000 ms to higher value in line 484)
The adb pull command failed silently. Check:
  • Device still connected?
  • Sufficient USB transfer speed?
  • Try again - transient network/USB issue
The CLI saves to the folder you specified. If you pressed Enter without typing a path, it defaults to:
C:\Users\YourName\Desktop
Check your Desktop or the folder shown in the success message.
  • Check browser download settings (may be blocked)
  • Look for the download notification in your browser
  • Check browser’s Downloads folder
  • Try a different browser

Performance Tips

USB for Large Apps

Use USB connections for apps over 100 MB - WiFi is slower and less stable.

Filter User Apps

Loading “All Apps” (200+) is slower than “User Apps” (20-50). Use filters wisely.

Batch via API

For 10+ apps, write a script using the API for parallel extraction.

Close Other ADB Apps

Android Studio, Vysor, or other ADB tools can interfere. Close them during extraction.

Next Steps

XAPK Feature

Deep dive into XAPK compilation

App Extraction Feature

Technical details on extraction

API - Apps Endpoints

API reference for app endpoints

Device Management

Managing multiple devices

Wireless Debugging

Extract over WiFi

Build docs developers (and LLMs) love