
How to set up, build, and contribute to Memo.
| Dependency | Version | Notes |
|---|---|---|
| Go | 1.26+ | Backend |
| Flutter | 3.10+ | Desktop + mobile frontend |
| C++ compiler | GCC or Clang | Required for CGO (SQLite) |
| Node.js | 18+ | For memo-web (this documentation site) |
# Clone the repository
git clone https://github.com/BugraAkdemir/memo.git
cd memo
# Install Go dependencies
go mod download
# Build and run backend
CGO_ENABLED=1 go run . --port 8090
# Frontend (in another terminal)
cd frontend
flutter pub get
flutter run -d linux
| File | Purpose |
|---|---|
main.go |
Backend entry point — flag parsing, signal handling, shutdown |
internal/app/app.go |
Central orchestrator — wires all subsystems together |
frontend/lib/main.dart |
Flutter entry point — Material app, routing, providers |
config/config.yaml |
Default configuration — all sections documented in config reference |
memo/
├── main.go # Backend entry point
├── internal/
│ ├── app/ # Central orchestrator (chat, LLM, memory, agents)
│ ├── webserver/ # HTTP server (~90 endpoints)
│ ├── provider/ # External LLM providers + router
│ ├── memory/ # RAG vector store (SQLite + sqlite-vec)
│ ├── agent/ # Tool-calling sandbox
│ ├── orchestra/ # Multi-model workflows
│ ├── cloudsync/ # Google Drive E2E backup
│ ├── sessions/ # Chat persistence
│ ├── whatsapp/ # WhatsApp bridge
│ ├── calendar/ # Calendar and reminders
│ └── identity/ # System prompt / persona
├── frontend/
│ └── lib/
│ ├── main.dart # App entry point
│ ├── providers/ # Riverpod state management
│ ├── widgets/ # UI components
│ │ └── settings/tabs/ # Settings tab pages
│ └── core/
│ └── api_client.dart # Dio HTTP client for backend API
└── config/
└── config.yaml # Default configuration
Run before every commit:
# Backend tests
go test ./... -race -count=1 -timeout 60s
go build ./...
# Frontend analysis
cd frontend && flutter analyze
cd frontend && flutter test
GitHub Actions pipelines on every push to main:
.tar.gz.zip.zipArtifacts are downloadable from the Actions tab.
http.ServeMux, no external router. sync.RWMutex for concurrency. Never store context.Context in struct fields.AsyncNotifierProvider for state. Always add mounted checks before setState in async callbacks.feat(memory):, fix(provider):, docs:, etc.)