{"id":50394089,"url":"https://github.com/max-109/cracker","last_synced_at":"2026-05-30T20:00:55.989Z","repository":{"id":328245587,"uuid":"1099208185","full_name":"Max-109/cracker","owner":"Max-109","description":"AI chat web and mobile app","archived":false,"fork":false,"pushed_at":"2026-05-30T18:39:04.000Z","size":145374,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T19:17:42.985Z","etag":null,"topics":["ai","chat","codex","expo","mobile","nextjs","openai","transcription","web"],"latest_commit_sha":null,"homepage":"https://cracker.mom","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Max-109.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-18T17:52:10.000Z","updated_at":"2026-05-30T18:34:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Max-109/cracker","commit_stats":null,"previous_names":["max-109/cracker"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Max-109/cracker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Max-109%2Fcracker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Max-109%2Fcracker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Max-109%2Fcracker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Max-109%2Fcracker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Max-109","download_url":"https://codeload.github.com/Max-109/cracker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Max-109%2Fcracker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33707328,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","chat","codex","expo","mobile","nextjs","openai","transcription","web"],"created_at":"2026-05-30T20:00:43.789Z","updated_at":"2026-05-30T20:00:55.977Z","avatar_url":"https://github.com/Max-109.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./app/icon-template.svg\" width=\"84\" alt=\"Cracker mark\" /\u003e\n  \u003ch1\u003eCracker\u003c/h1\u003e\n  \u003cp\u003e\u003cstrong\u003eAI chat web and mobile app focused on UI/UX.\u003c/strong\u003e\u003c/p\u003e\n  \u003cp\u003e\n    \u003cimg alt=\"Next.js\" src=\"https://img.shields.io/badge/Next.js-16-%23d4a86b?style=for-the-badge\u0026labelColor=3f3f46\" /\u003e\n    \u003cimg alt=\"React\" src=\"https://img.shields.io/badge/React-19-%23d4a86b?style=for-the-badge\u0026labelColor=3f3f46\" /\u003e\n    \u003cimg alt=\"Tailwind CSS\" src=\"https://img.shields.io/badge/Tailwind-v4-%23d4a86b?style=for-the-badge\u0026labelColor=3f3f46\" /\u003e\n    \u003cimg alt=\"Expo\" src=\"https://img.shields.io/badge/Expo-SDK%2056-%23d4a86b?style=for-the-badge\u0026labelColor=3f3f46\" /\u003e\n    \u003cimg alt=\"Redis\" src=\"https://img.shields.io/badge/Redis-cache%20%2B%20sync-%23d4a86b?style=for-the-badge\u0026labelColor=3f3f46\" /\u003e\n    \u003cimg alt=\"AI SDK\" src=\"https://img.shields.io/badge/AI%20SDK-v5-%23d4a86b?style=for-the-badge\u0026labelColor=3f3f46\" /\u003e\n  \u003c/p\u003e\n  \u003ctable width=\"100%\"\u003e\n    \u003ctr\u003e\n      \u003cth width=\"68%\"\u003eWeb app\u003c/th\u003e\n      \u003cth width=\"32%\"\u003eMobile app\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd width=\"68%\" align=\"center\"\u003e\u003cimg src=\"./cracker.gif\" alt=\"Cracker web app preview\" width=\"100%\" /\u003e\u003c/td\u003e\n      \u003ctd width=\"32%\" align=\"center\"\u003e\u003cimg src=\"./cracker-mobile.gif\" alt=\"Cracker mobile app preview\" width=\"100%\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/table\u003e\n\u003c/div\u003e\n\n## What is Cracker?\n\nCracker is a private AI chat app built around an OpenAI-compatible backend, with a Next.js web app and an Expo React Native mobile app. It uses PostgreSQL as the source of truth and optional Redis/Valkey for faster settings sync, cache hits, and lightweight coordination.\n\nIt has encrypted chat storage, local auth, model switching, file attachments, web tools, learning mode, memory, and a matching mobile app.\n\nYou can also connect OpenAI accounts in the browser and use their Codex/ChatGPT-plan usage for compatible models. Add more than one account if you want. Cracker checks usage, picks the account with the most room left, and tries the next account when one hits a limit.\n\n## Features\n\n- Browser-connected OpenAI accounts with usage-aware rotation for Codex/ChatGPT-plan usage.\n- Model presets: Expert (GPT 5.5), Balanced (GPT 5.4 Mini), and Ultra Fast (GPT 5.3 Codex Spark).\n- Fast mode support.\n- PostgreSQL + Drizzle ORM for chats, settings, users, memory, encrypted messages, and email/password auth.\n- Admin dashboard with invitation-code signup for private access.\n- Guest mode.\n- File and image attachments.\n- Streaming chat with reasoning, tool events, and tokens/sec stats.\n- Accent-color theming across the UI, favicon, app icon, and code highlighting.\n- MCP tools for Brave Search and YouTube.\n- Learning mode for summaries, flashcards, and guided explanations.\n- Expo SDK 56 / React Native Android app in `cracker-mobile/`, targeting `https://cracker.mom` by default.\n\n## Tech stack\n\n| Part | Tech |\n| --- | --- |\n| Web | Next.js 16, React 19, Tailwind CSS v4 |\n| Mobile | Expo SDK 56, React Native 0.85, Expo Router |\n| Runtime | Bun |\n| AI | Vercel AI SDK, OpenAI-compatible provider |\n| Data | PostgreSQL, Drizzle ORM |\n| Auth | JWT cookies / bearer tokens, PostgreSQL users |\n\n## Requirements\n\n- Bun\n- PostgreSQL\n- OpenAI-compatible API key or proxy key\n- Java 17 and Android SDK command-line tools for Android builds\n\n## Environment\n\nCreate `.env` in the repo root:\n\n```env\nDATABASE_URL=postgresql://user:password@host:5432/cracker\nOPENAI_BASE_URL=http://your-api-host:8080/v1\nOPENAI_API_KEY=your_proxy_key\nAUTH_SESSION_SECRET=replace_with_a_long_random_secret\nENCRYPTION_KEK=64_hex_characters\n\n# Optional tools\nBRAVE_API_KEY=\nYOUTUBE_API_KEY=\nTAVILY_API_KEY=\n\n# Optional Redis cache/sync backend\n# Prefer this for your own VPS Redis/Valkey:\nREDIS_URL=redis://:password@your-vps:6379\n# Or use Upstash REST instead:\nUPSTASH_REDIS_REST_URL=\nUPSTASH_REDIS_REST_TOKEN=\n# Optional namespace / forced DB-only mode:\nREDIS_PREFIX=cracker:\nREDIS_DISABLED=false\n```\n\n`DATABASE_URL` may also be `POSTGRES_URL`, `POSTGRES_PRISMA_URL`, or `POSTGRES_URL_NON_POOLING`. `PROXY_API_KEY` is accepted instead of `OPENAI_API_KEY`.\n\nRedis is optional. If Redis vars are unset, the app falls back to PostgreSQL-only behavior. Use `REDIS_URL` for a VPS Redis/Valkey instance; Upstash REST vars are supported as a serverless fallback. Never expose Redis credentials with `NEXT_PUBLIC_` or `EXPO_PUBLIC_`.\n\n## Run the web app\n\n```bash\nbun install\nbunx drizzle-kit push\nbun run dev\n```\n\nOpen `http://localhost:3000`.\n\n## Create an admin user\n\n```bash\nADMIN_PASSWORD=\"your-password\" bun run scripts/create-admin.ts admin@example.com \"Admin\"\n```\n\nThe script creates or updates the user as admin and prints an invitation code.\n\n## Run the mobile app\n\n```bash\ncd cracker-mobile\nbun install\nbun start -- --clear\n```\n\nUse a native build or dev client. The app includes MMKV, Reanimated, dynamic app icons, Secure Store, and Nitro modules, so plain Expo Go is not the reliable target.\n\n## Run Android in an emulator\n\nInstall the emulator and an Android 36 ARM image once:\n\n```bash\nexport ANDROID_HOME=/opt/homebrew/share/android-commandlinetools\nexport ANDROID_SDK_ROOT=\"$ANDROID_HOME\"\nexport PATH=\"$ANDROID_HOME/emulator:$ANDROID_HOME/platform-tools:$PATH\"\n\nyes | sdkmanager \"emulator\" \"system-images;android-36;google_apis;arm64-v8a\"\nprintf 'no\\n' | avdmanager create avd \\\n  -n cracker_api36 \\\n  -k \"system-images;android-36;google_apis;arm64-v8a\" \\\n  -d pixel_7 \\\n  --force\n```\n\nStart the emulator:\n\n```bash\nexport ANDROID_HOME=/opt/homebrew/share/android-commandlinetools\nexport ANDROID_SDK_ROOT=\"$ANDROID_HOME\"\nexport PATH=\"$ANDROID_HOME/emulator:$ANDROID_HOME/platform-tools:$PATH\"\n\nemulator -avd cracker_api36 -no-snapshot -no-audio -no-boot-anim -gpu swiftshader_indirect\n```\n\nIn another terminal, wait for boot, install the APK, launch the app, and capture logs:\n\n```bash\nexport ANDROID_HOME=/opt/homebrew/share/android-commandlinetools\nexport PATH=\"$ANDROID_HOME/platform-tools:$PATH\"\n\nadb wait-for-device\nuntil adb shell getprop sys.boot_completed | grep -q 1; do sleep 2; done\n\nadb install -r cracker.apk\nadb logcat -c\nadb shell am force-stop com.cracker.mobile\nadb shell am start -W -n com.cracker.mobile/.MainActivity\nsleep 10\nadb logcat -d -v threadtime \u003e cracker-logcat.txt\n```\n\nUseful crash filters:\n\n```bash\ngrep -E 'FATAL EXCEPTION|AndroidRuntime|ReactNativeJS|UnsatisfiedLinkError|SoLoader|Nitro|MMKV|QuickCrypto|Reanimated|com\\.cracker\\.mobile' cracker-logcat.txt\n```\n\nTake a screenshot from the emulator:\n\n```bash\nadb exec-out screencap -p \u003e cracker-screen.png\n```\n\n## Build the Android APK\n\n```bash\ncd cracker-mobile\nexport JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home\nexport ANDROID_HOME=/opt/homebrew/share/android-commandlinetools\nexport PATH=\"$JAVA_HOME/bin:$PATH\"\n\n# Required for local Gradle builds. Keep APK small: arm64-v8a only.\necho 'sdk.dir=/opt/homebrew/share/android-commandlinetools' \u003e android/local.properties\ngrep -q '^reactNativeArchitectures=arm64-v8a' android/gradle.properties || \\\n  printf '\\nreactNativeArchitectures=arm64-v8a\\n' \u003e\u003e android/gradle.properties\n\nbun install\nbunx tsc --noEmit\ncd android\n./gradlew assembleRelease\ncd ../..\ncp cracker-mobile/android/app/build/outputs/apk/release/app-release.apk cracker.apk\n```\n\nUse Java 17 for Android builds. Java 21+ is misleading here and can fail with this React Native/Gradle setup.\n\nThe latest local build output is `cracker.apk` in the repo root.\n\n## Clean Android rebuild after Expo/native changes\n\n```bash\ncd cracker-mobile\nexport JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home\nexport ANDROID_HOME=/opt/homebrew/share/android-commandlinetools\nexport PATH=\"$JAVA_HOME/bin:$PATH\"\n\nbunx expo prebuild --clean --platform android\n./scripts/copy-foreground-icons.sh\nprintf '\\norg.gradle.java.home=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home\\nreactNativeArchitectures=arm64-v8a\\n' \u003e\u003e android/gradle.properties\necho 'sdk.dir=/opt/homebrew/share/android-commandlinetools' \u003e android/local.properties\nbunx tsc --noEmit\ncd android \u0026\u0026 ./gradlew assembleRelease\ncd ../..\ncp cracker-mobile/android/app/build/outputs/apk/release/app-release.apk cracker.apk\n```\n\n## Project layout\n\n```txt\napp/                    Next.js routes, API routes, and web components\ndb/                     Drizzle schema and database connection\nlib/                    AI provider, auth, encryption, uploads, tools\nscripts/create-admin.ts Admin bootstrap script\ncracker-mobile/         Expo mobile app\ncracker-mobile/android/ Native Android project used for APK builds\n```\n\n## Notes\n\n- Mobile voice transcription is hidden until mobile has OpenAI account auth; the backend transcription route requires `openAIAccountAuth`.\n- `expo-doctor` reports the Metro override in `cracker-mobile/metro.config.js`; it is intentional to avoid the parent Next.js app's React copy.\n- Root `android/` is a Capacitor wrapper. Use `cracker-mobile/android/` for the Expo Android APK above.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax-109%2Fcracker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmax-109%2Fcracker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax-109%2Fcracker/lists"}