OpenSakura
MekaHime's first AI companion, now open source. 26 emotions, her real voice, real-time replies and memory, running on your own PC. Discord mode coming soon.
翻譯準備中
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗A scalable, high-throughput Discord clone built with Next.js 16 (React 19), Express 5, Mediasoup v3 SFU, Redis Streams, and PostgreSQL (Drizzle ORM).
docker run -d --name discord-redis -p 6379:6379 redis:alpine
cd backend
npm install
npx drizzle-kit push
npm run dev
To persist messages and reactions into PostgreSQL:
# In separate terminals:
npm run streamWorker # Chat message persistence
npm run reactionWorker # Message reaction persistence
cd frontend
npm install
npm run dev
Visit http://localhost:3000 in your browser.
The phone apps are the same Next.js frontend wrapped with Capacitor 8, plus native Bluetooth mesh plugins (frontend/android/, frontend/ios/). The normal web build (npm run dev / npm run build) is not affected by any of this.
cd frontend
npm install
cp .env.capacitor.example .env.capacitor
Edit frontend/.env.capacitor and set the backend address the phone should use. On a phone, localhost is the phone itself, so use:
http://<your PC's Wi-Fi IP>:4000 (find it with ipconfig)http://10.0.2.2:4000https:// server, with CAP_ALLOW_HTTP=falseThe backend URL is baked into the app at build time. If you change
.env.capacitor, rebuild the app.
Requirements: Android Studio (with the Android SDK) and JDK 21 exactly. JDK 17 is too old and the JDK 25 bundled with Android Studio is too new for Gradle 8.14. In Android Studio: Settings → Build Tools → Gradle → Gradle JDK → Download JDK → 21. For command-line builds, point JAVA_HOME at a JDK 21.
Build the web app and copy it into the Android project:
npm run build:app
Compile the APK — either:
npm run app:open, then Build → Build App Bundle(s) / APK(s) → Build APK(s), orfrontend/android):
./gradlew assembleDebug
(PowerShell / cmd: .\gradlew.bat assembleDebug)The APK is written to frontend/android/app/build/outputs/apk/debug/app-debug.apk.
Install it on a phone (USB debugging on, phone plugged in):
adb install -r app/build/outputs/apk/debug/app-debug.apk
Or copy the APK to the phone and open it (allow "install unknown apps"). Shortcut for steps 2–3: npm run app:run builds and launches on a connected phone.
Release APK: Android Studio → Build → Generate Signed App Bundle / APK, create or pick a keystore, choose APK → release. Use an https backend for release builds.
Requirements: a Mac with Xcode and Node 22. Swift can't be compiled on Windows.
npm run build:ios
npm run ios:open
| Way | Cost | Who can install | How long it lasts |
|---|---|---|---|
| Xcode → Run (above) | Free | Phones plugged into your Mac | 7 days, then Run again |
| AltStore (below) | Free | Anyone with an Apple ID and a PC or Mac | 7 days, refreshed automatically over Wi-Fi |
| TestFlight / Ad Hoc | $99/year Apple Developer account | Up to 10,000 testers by link (TestFlight) | 90 days (TestFlight), 1 year (Ad Hoc) |
The website works in Safari for chat and voice, but not for the Bluetooth mesh: Safari can't use Bluetooth, so mesh on iPhone needs the app.
.ipa with AltStoreWith a free Apple ID you can't send someone an .ipa that installs by tapping it. With AltStore, each person installs it with their own Apple ID, and AltStore signs it on their phone.
Step 1 — Make the .ipa (you, on the Mac). Build it unsigned; AltStore signs it later. From frontend/:
npm run build:ios
cd ios/App
xcodebuild -project App.xcodeproj -scheme App -configuration Release -sdk iphoneos -derivedDataPath build CODE_SIGNING_ALLOWED=NO
mkdir -p Payload
cp -R build/Build/Products/Release-iphoneos/App.app Payload/
zip -r DemoDiscord.ipa Payload
rm -rf Payload
This gives you frontend/ios/App/DemoDiscord.ipa. Send it to testers by AirDrop, Google Drive, WhatsApp or similar. An .ipa is just a zip file with a Payload/App.app folder inside.
Set the backend in
.env.capacitorto a server the testers can reach (your deployedhttpsserver) before building. Your home Wi-Fi IP only works on your Wi-Fi.
Step 2 — Install AltStore (each tester, once). They need a Windows PC or Mac and a USB cable.
Step 3 — Install the app (each tester).
DemoDiscord.ipa to the iPhone's Files app.DemoDiscord.ipa. It installs in under a minute.Keeping it working:
.ipa and install it the same way. It replaces the old one and keeps its data.With an Apple Developer account, in Xcode pick Any iOS Device → Product → Archive → Distribute App → TestFlight (or Ad Hoc for specific registered phones). Testers install it from Apple's TestFlight app using a link.
The desktop app is the same static web build as the phone apps, shown in a native window by Wails (Go + the system web view, about 14 MB). A small Go Bluetooth layer (frontend/desktop/mesh.go) lets the offline mesh work on a PC.
Requirements: Go 1.26+ and Node. Windows 10/11 already has the WebView2 runtime. A PC with Bluetooth is needed for the mesh.
cd frontend
cp .env.desktop.example .env.desktop # backend address; falls back to .env.capacitor
npm run desktop
This builds the web app, copies it into frontend/desktop/dist/, and compiles frontend/desktop/build/bin/demo-discord.exe. The first run downloads the Wails CLI through go run, so nothing needs installing globally. npm run desktop -- --no-web skips the web build and reuses out/.
How the offline mesh works on desktop:
%APPDATA%\DemoDiscord.Mac / Linux: the Go code builds there too (npm run desktop on that OS), but it hasn't been tested, and mesh keys aren't sealed yet on those systems.
The web version shows a Download APK button (login page, Hub, and a download icon in the phone top bar) once an APK has been published. Inside the installed app the button is hidden, and iPhone visitors are told the app is Android only.
cd frontend
npm run apk # web build -> cap sync -> Gradle assembleDebug -> copy to public/downloads/
npm run apk:copy # only copy the last built APK into public/downloads/
npm run apk finds a JDK 21 by itself (JAVA_HOME if it is 21, otherwise Android Studio's download in ~/.jdks).public/downloads/demo-discord.apk and public/downloads/apk.json (version and size, shown on the button). Commit both files and push; Vercel then serves them.public/downloads/ is committed so hosts that build from git (Vercel) serve the APK. Commit it again after each npm run apk. build:app / build:ios strip it from the phone app, so the APK never ends up inside itself.versionCode.Each time the code changes:
npm install in frontend/ (in case dependencies changed).npm run test:mesh.npm run build:app (Android) or npm run build:ios (iOS). Skipping this step leaves the old web code inside the app.adb install -r replaces the old app and keeps its data.
INSTALL_FAILED_UPDATE_INCOMPATIBLE, the old APK was signed on a different PC. Uninstall it first: adb uninstall com.demodiscord.app (this deletes the app's local data and mesh identity).versionCode (and versionName) in frontend/android/app/build.gradle so phones accept it as an update.What to check on the phones:
adb logcat -s BleMesh.More detail and the full release test checklist: 08. Offline BLE Mesh Plan and 10. Mesh Channels Plan.
Comprehensive technical deep-dives and guides are located in the docs/ folder: