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.
- Repository: github.com/a-ghorbani/pocketpal-ai
- Licence: MIT (MIT License)
- Language: TypeScript. Stars: 8,812. Forks: 979. Last push: Oct 26, 2026.
- Scan: safe, Oct 26, 2026, commit 3c5b498
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-ai2. 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 iosFor 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
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | 1 pattern hit found and read; every one is listed under the raw findings. |
| Install-time code | 2 npm lifecycle scripts |
| Committed binaries | 1 executable or compiled object committed; listed under the raw findings. |
| CI workflows | 4 workflows. None use pull_request_target. 4 of 4 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 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 vulnerabilities | 347 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 hygiene | Has licence file, contributing guide. Missing security policy, automated dependency updates, CodeQL. |
| OpenSSF Scorecard | Not 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)
| Where | Rule | Match |
|---|---|---|
| jest/fixtures/llamaServerWire.ts:90 | very-long-line | 4799 chars |
URLs to bare IP addresses (1)
| Where | Rule | Match |
|---|---|---|
| src/services/talents/__tests__/readUrlAllowlist.test.ts:133 | ip-literal-url | 'http://1.2.3.4/x', |
npm lifecycle scripts (2)
package.jsonpostinstall:./scripts/postinstall.shpackage.jsonprepare:husky
Committed binaries (1)
android/gradle/wrapper/gradle-wrapper.jar: JAR, 49 KB
Worst known vulnerabilities (24 of 347)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-5rq4-664w-9x2c | critical | basic-ftp@5.0.5 | Basic FTP has Path Traversal Vulnerability in its downloadToDir() method |
| GHSA-m7jm-9gc2-mpf2 | critical | fast-xml-parser@5.2.5 | fast-xml-parser has an entity encoding bypass via regex injection in DOCTYPE entity names |
| GHSA-m7jm-9gc2-mpf2 | critical | fast-xml-parser@5.3.3 | fast-xml-parser has an entity encoding bypass via regex injection in DOCTYPE entity names |
| GHSA-fjxv-7rqg-78g4 | critical | form-data@4.0.2 | form-data uses unsafe random function in form-data for choosing boundary |
| GHSA-jqcg-44mw-7w3h | critical | proxy-addr@2.0.7 | proxy-addr vulnerable to IP spoofing via IPv4-mapped IPv6 trust subnet |
| GHSA-w7jw-789q-3m8p | critical | shell-quote@1.8.2 | shell-quote quote() does not escape newlines in object .op values |
| GHSA-w7jw-789q-3m8p | critical | shell-quote@1.8.3 | shell-quote quote() does not escape newlines in object .op values |
| GHSA-v5rq-49vh-5v5c | critical | @simple-git/argv-parser@1.1.1 | simple-git: `VISUAL` editor environment variable is omitted from unsafe editor detection |
| GHSA-q9v2-7m5w-4693 | critical | expr-eval@2.0.2 | expr-eval vulnerable to Code Execution |
| GHSA-xq3m-2v4x-88gg | critical | protobufjs@7.5.4 | Arbitrary code execution in protobufjs |
| GHSA-x6jw-m9v5-85vh | critical | simple-git@3.36.0 | simple-git unsafe-operation guard does not block trailer command configuration |
| GHSA-xv26-6w52-cph6 | critical | websocket-driver@0.7.4 | websocket-driver: Message corruption via abuse of protocol length headers |
| GHSA-27p8-2357-5qqv | high | @xmldom/xmldom@0.8.11 | xmldom: DocType `name` Injection Bypasses requireWellFormed |
| GHSA-2v35-w6hq-6mfw | high | @xmldom/xmldom@0.8.11 | xmldom: Uncontrolled recursion in XML serialization leads to DoS |
| GHSA-4w3w-2rp5-g8jm | high | @xmldom/xmldom@0.8.11 | xmldom: Attribute name injection via setAttribute() bypasses requireWellFormed |
| GHSA-8344-3jmq-59r6 | high | @xmldom/xmldom@0.8.11 | xmldom: Quadratic-time attribute deduplication |
| GHSA-93r5-fhx6-vmg9 | high | @xmldom/xmldom@0.8.11 | xmldom: Quadratic-time parsing via the malformed-input recovery path - `parseElementStartPart` re-scan and `normalize()`… |
| GHSA-965w-775f-mr7g | high | @xmldom/xmldom@0.8.11 | xmldom: Quadratic-memory consumption |
| GHSA-c7q8-3ch8-vqpv | high | @xmldom/xmldom@0.8.11 | xmldom: Processing Instruction Target Injection Bypasses requireWellFormed |
| GHSA-f6ww-3ggp-fr8h | high | @xmldom/xmldom@0.8.11 | xmldom has XML injection through unvalidated DocumentType serialization |
| GHSA-j759-j44w-7fr8 | high | @xmldom/xmldom@0.8.11 | xmldom has XML node injection through unvalidated comment serialization |
| GHSA-w2rr-34g9-rvrj | high | @xmldom/xmldom@0.8.11 | xmldom: Element name injection via createElement() bypasses requireWellFormed |
| GHSA-wh4c-j3r5-mjhp | high | @xmldom/xmldom@0.8.11 | xmldom: XML injection via unsafe CDATA serialization allows attacker-controlled markup insertion |
| GHSA-x4fp-j954-r2f4 | high | @xmldom/xmldom@0.8.11 | xmldom: End-tag Whitespace-Trim Regex ReDoS - quadratic backtracking in the 0.8.x end-tag parser |
By the numbers
| Stars | 8,812 |
|---|---|
| Forks | 979 |
| Contributors | 50 |
| Commits | 952 |
| Open issues | 110 |
| Open pull requests | 21 |
| Releases | 91 |
| Latest release | v1.21.2 |
| Licence | MIT |
| Main language | TypeScript |
| Project age | 2 years |
| Last push | Oct 26, 2026 |
| Tracked files | 1,979 |
| Lines of code | 341.4K |
| Checkout size | 34 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.
