5 min read

PocketPal AI: Run Language Models Offline on Your Phone (GitHub, Scanned)

A private AI assistant for iPhone and Android that runs language models entirely on the phone.

PocketPal AI logo
✅
Scan: safe. Nothing malicious, and chats stay on the phone. One thing to know: the optional web search sends your queries to the search provider you pick, and pages may be read through r.jina.ai. Scanned Oct 26, 2026; the full report is below.

PocketPal AI puts a chat assistant on your phone that needs no account, no cloud and no connection once a model is downloaded. Pick a GGUF model such as Gemma, Qwen, Phi or Llama from the built-in list or from Hugging Face, load it, and chat; prompts and replies stay on the device. Underneath it runs llama.cpp through llama.rn, using the CPU, the GPU (Metal on iOS, OpenCL on Qualcomm Adreno) and, on Qualcomm chips, the NPU.

Around the chat there are Pals, custom assistants with their own model, system prompt and personality; on-device text-to-speech (Kokoro and other engines) to read replies aloud; simple tools such as a calculator and date and time in a tool-use loop; and a benchmark that measures tokens per second, with an opt-in public leaderboard. It is MIT-licensed, built with React Native, and has about 8,800 stars, with v1.21.2 released on the day of the scan.

A phone's memory limits you to small models, so the advice is to pick one that fits your device; larger ones are slow or will not load. Some community Pals on PalsHub are paid in-app purchases, though the app and the models are free.

Who it is for

People who want an AI assistant that works on a plane or keeps their chats off other people's servers, and anyone curious how fast their phone can run a language model.

Getting started

1. Developers: clone the source (everyone else installs from the App Store or Google Play)

git clone https://github.com/a-ghorbani/pocketpal-ai && cd pocketpal-ai

2. Match the pinned Node version and install dependencies (iOS also needs CocoaPods)

nvm use && yarn install && (cd ios && pod install)

3. Start Metro with yarn start, then build and run on the iOS simulator

yarn ios

For everyday use, install PocketPal from the App Store or Google Play, open the menu, go to Models, download one that fits your phone, tap Load and start chatting. Gated Hugging Face models need your own access token under Settings.

Safety scan

We cloned a-ghorbani/pocketpal-ai at commit 3c5b498 on Oct 26, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • No secrets and no self-decoding code. The one pattern hit is a 4,799-character line in jest/fixtures/llamaServerWire.ts, a recorded test fixture, and the bare-IP URL (1.2.3.4) is in a test of the URL-reading allowlist.
  • Install hooks are for developers building from source: postinstall runs patch-package and clones the Khronos OpenCL headers from GitHub for building llama.rn; prepare sets up husky git hooks. Nothing like this runs when you install the app from a store.
  • Network use is opt-in. Web search uses your own key for Tavily, Brave, Exa, Firecrawl, Parallel or You.com, and the in-app consent text says page reading may go through r.jina.ai when a provider has no reader of its own, and that keys and queries are never sent to PocketPal. Leaderboard results and feedback are only sent if you choose to.
  • 347 known advisories. 243 are in e2e/yarn.lock, end-to-end test tooling that never ships. The rest are in the main yarn.lock, mostly React Native build and development tooling. One that does ship is expr-eval, used by the calculator tool, which has a code-execution advisory; CalculateEngine.ts creates its parser with allowMemberAccess set to false, which its own comment explains is there to block that escape route.
  • 4 workflows, none using pull_request_target; none of the 4 third-party actions is pinned to a commit. Contributing guide and code of conduct present; no security policy or Dependabot.

What the scanner counted

CheckResult
SecretsNone found.
Suspicious code1 pattern hit found and read; every one is listed under the raw findings.
Install-time code2 npm lifecycle scripts
Committed binaries1 executable or compiled object committed; listed under the raw findings.
CI workflows4 workflows. None use pull_request_target. 4 of 4 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often web-site.com, huggingface.co, e.com, a.com. 1 URL to a bare IP address, listed under the raw findings.
Known vulnerabilities347 advisories across 1,883 pinned packages: 12 critical, 160 high, 149 moderate, 26 low. e2e/yarn.lock: 826 packages, 243 advisories; yarn.lock: 1,293 packages, 149 advisories.
Project hygieneHas licence file, contributing guide. Missing security policy, automated dependency updates, CodeQL.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Pattern hits (1)
WhereRuleMatch
jest/fixtures/llamaServerWire.ts:90very-long-line4799 chars
URLs to bare IP addresses (1)
WhereRuleMatch
src/services/talents/__tests__/readUrlAllowlist.test.ts:133ip-literal-url'http://1.2.3.4/x',
npm lifecycle scripts (2)
  • package.json postinstall: ./scripts/postinstall.sh
  • package.json prepare: husky
Committed binaries (1)
  • android/gradle/wrapper/gradle-wrapper.jar: JAR, 49 KB
Worst known vulnerabilities (24 of 347)
AdvisorySeverityPackageSummary
GHSA-5rq4-664w-9x2ccriticalbasic-ftp@5.0.5Basic FTP has Path Traversal Vulnerability in its downloadToDir() method
GHSA-m7jm-9gc2-mpf2criticalfast-xml-parser@5.2.5fast-xml-parser has an entity encoding bypass via regex injection in DOCTYPE entity names
GHSA-m7jm-9gc2-mpf2criticalfast-xml-parser@5.3.3fast-xml-parser has an entity encoding bypass via regex injection in DOCTYPE entity names
GHSA-fjxv-7rqg-78g4criticalform-data@4.0.2form-data uses unsafe random function in form-data for choosing boundary
GHSA-jqcg-44mw-7w3hcriticalproxy-addr@2.0.7proxy-addr vulnerable to IP spoofing via IPv4-mapped IPv6 trust subnet
GHSA-w7jw-789q-3m8pcriticalshell-quote@1.8.2shell-quote quote() does not escape newlines in object .op values
GHSA-w7jw-789q-3m8pcriticalshell-quote@1.8.3shell-quote quote() does not escape newlines in object .op values
GHSA-v5rq-49vh-5v5ccritical@simple-git/argv-parser@1.1.1simple-git: `VISUAL` editor environment variable is omitted from unsafe editor detection
GHSA-q9v2-7m5w-4693criticalexpr-eval@2.0.2expr-eval vulnerable to Code Execution
GHSA-xq3m-2v4x-88ggcriticalprotobufjs@7.5.4Arbitrary code execution in protobufjs
GHSA-x6jw-m9v5-85vhcriticalsimple-git@3.36.0simple-git unsafe-operation guard does not block trailer command configuration
GHSA-xv26-6w52-cph6criticalwebsocket-driver@0.7.4websocket-driver: Message corruption via abuse of protocol length headers
GHSA-27p8-2357-5qqvhigh@xmldom/xmldom@0.8.11xmldom: DocType `name` Injection Bypasses requireWellFormed
GHSA-2v35-w6hq-6mfwhigh@xmldom/xmldom@0.8.11xmldom: Uncontrolled recursion in XML serialization leads to DoS
GHSA-4w3w-2rp5-g8jmhigh@xmldom/xmldom@0.8.11xmldom: Attribute name injection via setAttribute() bypasses requireWellFormed
GHSA-8344-3jmq-59r6high@xmldom/xmldom@0.8.11xmldom: Quadratic-time attribute deduplication
GHSA-93r5-fhx6-vmg9high@xmldom/xmldom@0.8.11xmldom: Quadratic-time parsing via the malformed-input recovery path - `parseElementStartPart` re-scan and `normalize()`…
GHSA-965w-775f-mr7ghigh@xmldom/xmldom@0.8.11xmldom: Quadratic-memory consumption
GHSA-c7q8-3ch8-vqpvhigh@xmldom/xmldom@0.8.11xmldom: Processing Instruction Target Injection Bypasses requireWellFormed
GHSA-f6ww-3ggp-fr8hhigh@xmldom/xmldom@0.8.11xmldom has XML injection through unvalidated DocumentType serialization
GHSA-j759-j44w-7fr8high@xmldom/xmldom@0.8.11xmldom has XML node injection through unvalidated comment serialization
GHSA-w2rr-34g9-rvrjhigh@xmldom/xmldom@0.8.11xmldom: Element name injection via createElement() bypasses requireWellFormed
GHSA-wh4c-j3r5-mjhphigh@xmldom/xmldom@0.8.11xmldom: XML injection via unsafe CDATA serialization allows attacker-controlled markup insertion
GHSA-x4fp-j954-r2f4high@xmldom/xmldom@0.8.11xmldom: End-tag Whitespace-Trim Regex ReDoS - quadratic backtracking in the 0.8.x end-tag parser

By the numbers

Stars8,812
Forks979
Contributors50
Commits952
Open issues110
Open pull requests21
Releases91
Latest releasev1.21.2
LicenceMIT
Main languageTypeScript
Project age2 years
Last pushOct 26, 2026
Tracked files1,979
Lines of code341.4K
Checkout size34 MB

Lines by language: TypeScript 245.1K, JSON 76.8K, JavaScript 9,100, Kotlin 3,618, Markdown 2,200, YAML 1,580.

Questions

Is PocketPal AI free?

Yes. PocketPal AI is MIT-licensed and free on the App Store and Google Play, with no subscription or pro tier. The models are free downloads under their own licences; some community Pals on PalsHub are premium in-app purchases.

Does PocketPal AI work offline?

Yes. Once a model is downloaded, chat, text-to-speech and the built-in tools run entirely on the phone with no connection. Only optional features such as web search, the benchmark leaderboard and feedback use the internet.

Which model should I use on my phone?

One that fits your phone's memory. The model list in the app suggests options, and the Benchmark page measures tokens per second and memory use, so you can compare a few small models on your own device before settling on one.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.