Skip to content
mneves75Public

About

A React Native mobile application that provides a modern, ChatGPT-like chat interface using DNS TXT queries to communicate with an LLM.

Resources

Contributing

Security policy

Stars

73 stars

Watchers

0 watching

Forks

Latest commit

 

History

388 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DNSChat

DNSChat is a React Native Expo app that sends short chat prompts as DNS TXT queries (default DNS server: llm.pieter.com). The app includes:

  • A native DNS TXT resolver module for iOS/Android (modules/dns-native/)
  • JavaScript fallback transports (UDP/TCP) for constrained networks
  • An in-app Logs screen to inspect attempts, failures, and fallbacks

Version React Native Expo TypeScript iOS Android CI License: MIT

Features

  • Chat with LLMs over DNS - no API keys, no accounts, no tracking
  • Native DNS resolution on iOS and Android with JS fallback transports
  • Encrypted local chat history (AES-GCM)
  • Multi-server support with automatic transport fallback
  • Bilingual UI (English / Portuguese)
  • Full offline chat history
  • NativeTabs with SF Symbols (iOS) and Material Symbols (Android)
  • Platform colors via expo-router Color API (auto light/dark, Android 12+ dynamic)
  • Native iOS toolbars with share, clear, and new-chat actions (liquid glass)
  • Zoom transitions (iOS 18+) from chat list to thread

Tech stack

  • App version: 4.4.9 (build 94, internal TestFlight v4.4.9-beta1); distribution status is recorded in the TestFlight runbook.
  • Expo workflow: Expo Router + EAS-compatible native config
  • Expo SDK: 57.0.x
  • React: 19.2.3
  • React Native: 0.86.3
  • TypeScript: 6.0.x
  • Hermes: enabled
  • New Architecture: enabled by default on SDK 57
  • React Compiler: enabled (experiments.reactCompiler: true)
  • Typed routes: enabled (experiments.typedRoutes: true)

How DNSChat encodes prompts

User prompts are validated and sanitized into a single DNS label (RFC 1035 constraints) before building a query name. Practical constraints (see modules/dns-native/constants.ts):

  • Prompts are capped at 120 characters before sanitization (hard fail, no silent truncation)
  • DNS labels are capped at 63 characters after sanitization

TXT responses are parsed as either:

  • Plain TXT records (concatenate non-empty records), or
  • Multipart n/N: segments that must form a complete sequence

Transport + fallback order

The transport order used by src/services/dnsService.ts is:

  1. Native DNS (iOS/Android native module)
  2. UDP (JavaScript transport via react-native-udp)
  3. TCP (DNS-over-TCP via react-native-tcp-socket)
  4. Mock (optional development fallback)

Web preview uses the Mock path by default because browsers cannot do raw DNS on port 53.

DNS packet encoding, DNS-over-TCP framing, decoded-response validation, and TXT record extraction live in src/services/dnsWire.ts; dnsService.ts owns the transport chain, retries, logging, and server fallback orchestration.

Quick start

Prereqs:

  • Node.js 22.13+ or 24 LTS (use the .node-version pin, currently 24; React Native and Metro require Node 22.13+ on the Node 22 line, and Node 26 is outside the supported engine range)
  • iOS: Xcode 26.4+ (macOS only), iOS 16.4+ device/simulator
  • Android: Java 17 + Android SDK

Install:

git clone <repository-url>
cd dnschat
pnpm install

Run:

# Dev server
pnpm run start

# iOS
pnpm run ios

# Android (auto-selects Java 17 when available)
pnpm run android

# Web preview (uses Mock DNS)
pnpm run web

Notes:

  • iOS simulator builds work out of the box; device builds require you to pick your own signing team in Xcode (the repo keeps DEVELOPMENT_TEAM empty).
  • For a full physical-device install, build the native DNSChat target for the device identifier and install the compiled .app; Expo Go is not a valid substitute for this repo because the app depends on native DNS modules. Keep device names, local paths, and signing identifiers out of public docs.

DNS smoke tests

# Quick DNS check (no React Native runtime required)
dig @llm.pieter.com "hello" TXT +short

# Full harness (builds scripts/ ts -> js, then runs UDP/TCP transports)
pnpm run dns:harness --message "test message"
pnpm run dns:harness --message "test message" --local-server

# Debug output artifacts
pnpm run dns:harness --message "test" --json-out harness-output.json --raw-out raw-dns.bin

Development commands

# Check or apply deterministic formatting with Oxfmt
pnpm run fmt:check
pnpm run fmt

# Lint (Oxlint correctness + ast-grep structural rules)
pnpm run lint

# Unit tests
pnpm run test

# Native UI QA uses Argent MCP; see docs/agents/development.md.

# Public-doc redaction gate
pnpm run verify:public-redaction

# Keep Expo iOS pods aligned with installed node_modules (iOS)
pnpm run verify:ios-pods

# Sanity checks for Android tooling/device expectations
pnpm run verify:android

# Full verification gate before committing/release work
pnpm run verify:all

# Sync app + native module versions (use :dry to preview)
pnpm run sync-versions
pnpm run sync-versions:dry

# CocoaPods cleanup helpers
pnpm run fix-pods
pnpm run clean-ios

Git hook (format + lint)

This repo installs a pre-commit hook that blocks commits when formatting, lint, pods, or unit tests fail.

Mechanism:

  • pnpm install runs pnpm run prepare
  • prepare runs scripts/install-git-hooks.js
  • that script resolves Git's hooks path (including linked worktrees and core.hooksPath) and writes an executable pre-commit hook that runs verify:ios-pods, fmt:check, lint (Oxlint + ast-grep), and unit tests

Reinstall the hook with pnpm run prepare. Run pnpm run verify:all before committing; the hook is the shorter safety net, not the entire release gate.

Documentation

Start here:

Architecture & spec:

Operational:

Release:

Current verification baseline

The 4.4.9 beta preserves ciphertext when its device-only key is missing, rejects ambiguous DNS wire names, and removes Android's unowned legacy lookup. The harness uses the app's response validation. Unsaved sends retain their drafts and settings failures show localized errors. The dependency lockfile contains security updates and a hardware-capability patch for Expo Haptics; refresh dependencies and rebuild native code to apply it. For this candidate, the frozen installation and full gate pass: 755 application and 68 native tests. The signed iOS Release build passes. A prior candidate installed in place; final SDK hardware verification needs exclusive device access. TestFlight reports VALID and IN_BETA_TESTING, with strict validation at zero errors/warnings and bilingual test notes. Production prerequisites remain unresolved.

The 4.4.8 gate (pnpm run verify:all, Node 24) passed 707 root tests and 67 native tests, with react-doctor at 92, Expo Doctor 20/20, a clean dependency audit and no leaks found. Release builds were run on an iOS 27 simulator (stable Xcode 27.0) and an Android 16 emulator. Both completed onboarding and got a real DNS reply over the native transport; iOS rendered accented text, kept its encrypted history across a cold restart and showed 4.4.8 (93) in About. The compiled iOS Info.plist carries no local-networking exception. Earlier releases hold the fuller end-to-end record; see the changelog.

Release builds use xcodebuild archive, -exportArchive, and asc publish testflight. The TestFlight runbook records the latest uploaded binary separately from source and simulator proof. The App Store production version observed on 2026-09-05 is 4.0.23; the existing submission draft has an expired build and incomplete age-rating fields. Provider privacy declarations and unsigned-response risk acceptance remain production prerequisites. No hardware performance improvement is claimed.

The paragraphs below are release history.

Version 4.3.6 build 84 is the previous TestFlight release, processed VALID on 2026-08-31 with bilingual notes and a physical Release install.

Version 4.2.3 build 77 is the previous TestFlight release. It carries the iOS 27 UIScene startup fix proven on a physical device in build 76; final pre-archive gates passed on 2026-07-10 (Jest 983, native DNS 65, React Compiler 101/101, Expo Doctor 19/19, audit and secret scan clean). Its signed archive and IPA export succeeded, App Store Connect processed it VALID, and strict TestFlight validation completed cleanly. Physical-device launch evidence remains scoped to build 76; build 77 was not separately installed locally.

Version 4.1.2 build 69 is a premium-feel pass on top of 4.1.1: a semantic palette.isDark signal for the loading-skeleton tint (replacing a hard-coded-hex check), a new isDark palette flag, removal of unused errorShake dead code, Expo SDK 56 dependency patch alignment, plus interactive keyboard drag-to-dismiss on the chat list, a calmer (no-overshoot) input auto-grow spring, and deletion of the dead GlassTabBar component. It was built into a Development-signed binary that installed and launched cleanly on a physical iOS device; it was not uploaded to TestFlight.

Version 4.1.3 build 70 is a release-readiness and documentation-integrity pass on top of 4.1.2 (a structured-review-flagged changelog release-state correction and a keyboard drag-to-dismiss regression test; no app-behavior change versus 4.1.2). It carries all of the 4.1.2 premium-feel work to TestFlight, since 4.1.2 itself was only Development-signed onto a device and never uploaded.

  • 4.3.6 build 84 SHIPPED to TestFlight — VALID on 2026-08-31 after the complete pre-production audit. Signed archive/export, physical Release install/launch, bilingual test notes, strict validation (0 errors, 0 warnings), and tag v4.3.6-beta1 are verified. No production submission is claimed because no matching App Store version exists.
  • 4.2.3 build 77 SHIPPED to TestFlight — VALID on 2026-07-10 for the iOS 27 scene-lifecycle startup fix. Signed archive/export succeeded, bilingual test notes are present, and strict validation reported 0 errors and 0 warnings. Build 76 supplied the separate physical-device launch proof; build 77 was not separately installed locally.
  • 4.2.0 build 73 SHIPPED to TestFlight — VALID on 2026-07-04 (bilingual "What to Test" notes, asc validate testflight --strict 0/0/0); supersedes 4.1.3 build 70. Local gates before archive on 2026-07-04 (iOS 26 HIG redesign + DNS correctness hardening + SDK 57 patch alignment): typecheck, ast-grep lint, react-compiler healthcheck (103/103), Jest (121 suites passed, 1 skipped, 964 tests passed, 13 skipped), dns-native workspace tests (8 suites, 65 tests passed), DNSResolver sync, iOS pods sync, SDK alignment, Expo Doctor (19/19), typed-routes, public-redaction, and security (pnpm audit No vulnerabilities found; gitleaks no leaks found) all passed. The backend/transport work was implemented via a dispatched codex run and reviewed in the main session; native runtime, Android native gates, and TestFlight upload remain separate claims not covered by these gates.
  • 4.1.5 build 72 SDK 57 gates on 2026-06-30: pnpm run verify:all passed; Expo Doctor reported 19/19; pnpm audit reported No vulnerabilities found; gitleaks detect reported no leaks found; Jest reported 122 suites passed, 1 skipped, 959 tests passed, and 13 skipped.
  • Native DNS module tests pass on 2026-06-30 (8 suites passed, 1 skipped; 64 tests passed, 13 skipped).
  • Xcode 26.6 (17F113) local iOS evidence on 2026-06-30: Debug simulator build passed, unsigned generic Release build passed, and unsigned generic Release archive passed.
  • Runtime smoke on 2026-06-30: the compiled simulator app installed and launched with Argent after clearing a stale Metro process from another repo; accessibility and React component discovery showed the DNSChat onboarding screen. Argent screenshot/gesture backend failed with simulator-server exited with code before becoming ready; that is a tooling gap, not an app launch failure.
  • TestFlight, App Store version attachment, and physical-device install remain separate evidence claims for 4.1.5 build 72 and must not be inferred from the local simulator/archive checks.
  • 4.1.0 build 67 (a staging milestone; later superseded by 4.1.1 build 68 as the latest VALID TestFlight build); the build number was advanced from 4.0.32 build 66. Build 67 completed VALID on 2026-06-22 using the GM Xcode 26.6 (17F109) toolchain via the archive -> export -> asc publish testflight lane (build 66 was also VALID). Internal App Store Connect IDs and tester group names are intentionally omitted from public docs.
  • Compiled Release simulator runtime evidence on 2026-06-22 for 4.1.0 build 67: the app launches cleanly (no ErrorBoundary) and the new adaptive launcher icon renders on the Home Screen, verified via Argent MCP (describe
    • gesture-tap + Home-screen capture). The in-app DNS-message path was not exercised on this build because it was compiled unsigned (CODE_SIGNING_ALLOWED=NO), which makes expo-secure-store's keychain unavailable ("Encryption key is unavailable"); DNS end-to-end is covered by the Node harness (real TXT answer) and by the TestFlight device build.
  • Historical asc validate testflight evidence is superseded by each uploaded build validation. App Store submission validation is not applicable until a matching App Store version record exists.
  • xcodebuild test is not a native gate yet because the DNSChat scheme has no XCTest bundles.
  • DNS transport is observable. Public copy and tests intentionally avoid claiming that DNS prompts are private or end-to-end encrypted.

Security notes

  • DNS is observable infrastructure. Do not send secrets or personal data.
  • DNS servers are validated/whitelisted (see modules/dns-native/constants.ts).
  • Local chat/log payloads are encrypted at rest. Native builds keep encryption key material in SecureStore, and Android backup/device-transfer rules exclude that SecureStore data. Web preview uses same-origin browser storage for the local-only preview key because SecureStore is not available in browsers; do not treat Web preview storage as a secure production at-rest boundary.
  • Store submission credentials are not committed. Keep eas submit/App Store Connect identifiers local (do not add them to eas.json).
  • Public release docs use placeholders for local/device/account identifiers. Run pnpm run verify:public-redaction before committing release notes or store runbooks. Exact release evidence belongs in private notes outside git.

Contributing

See CONTRIBUTING.md for development setup and guidelines.

Report security vulnerabilities via SECURITY.md.

License

MIT. See LICENSE.

About

A React Native mobile application that provides a modern, ChatGPT-like chat interface using DNS TXT queries to communicate with an LLM.

Resources

Contributing

Security policy

Stars

73 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages