AI-powered coffee cherry detection and maturity classification using YOLOv11 and WebAssembly.
- 🎯 Real-time Detection: Detect and count coffee cherries in images
- 🏷️ Maturity Classification: Classify cherries into 5 maturity stages:
- 🔴 Ripe - Ready for harvest
- 🟠 Semi-ripe - Almost ready
- 🟢 Unripe - Needs more time
- 🟣 Overripe - Past optimal
- 🟤 Dry - Dried on tree
- 📊 Statistics & History: Track your analysis.
- ⚡ WebGPU Acceleration: GPU-accelerated inference.
- 📦 Zero-Bundle WASM: Model and runtime are loaded from a global CDN.
- Frontend: Next.js 16, React 19, TailwindCSS 4, shadcn/ui
- ML Runtime: Burn - Rust ML framework
- Deployment: Vercel (Frontend), Cloudflare R2 (WASM/Model)
- Node.js 20+
- pnpm 9+
- AWS CLI (for deploying WASM)
- Rust (only if you need to modify the WASM module)
-
Clone the repository:
git clone https://github.com/yourusername/coffeefruitcounter.git cd coffeefruitcounter -
Install dependencies:
pnpm install
-
Configure Environment: Create a
.env.localfile:NEXT_PUBLIC_WASM_BASE_URL=https://your-r2-domain.com NEXT_PUBLIC_WASM_VERSION=v1.0.0
-
Start the development server:
pnpm dev
The WASM module and model weights are hosted on Cloudflare R2 to keep the frontend bundle light and build times fast.
You need a Cloudflare R2 bucket and an API Token with Object Read & Write permissions.
- Create a bucket (e.g.,
coffee-fruit-counter). - Go to R2 > Manage R2 API Tokens > Create API Token.
- Select Object Read & Write.
- Copy the
Access Key ID,Secret Access Key, and theS3 API Endpoint.
Export the following environment variables. The script uses the aws CLI, which requires the standard AWS credentials to be set.
# AWS CLI Credentials for R2
export AWS_ACCESS_KEY_ID="<YOUR_ACCESS_KEY_ID>"
export AWS_SECRET_ACCESS_KEY="<YOUR_SECRET_ACCESS_KEY>"
export AWS_DEFAULT_REGION="auto"
# Script Configuration
export R2_BUCKET="<YOUR_BUCKET_NAME>"
export R2_ENDPOINT="https://<ACCOUNT_ID>.r2.cloudflarestorage.com"
export MODEL_URL="<URL_TO_DOWNLOAD_MODEL_ONNX>"Run the script with a version tag (e.g., v1.0.0). This tag matches the version you will set in the frontend app.
./scripts/deploy_wasm.sh v1.0.0This will:
- Download the model from
MODEL_URL(if not found locally). - Build the Rust/WASM binaries (SIMD + No-SIMD).
- Upload the artifacts to
s3://<bucket>/wasm/v1.0.0/.
Update NEXT_PUBLIC_WASM_VERSION in your .env.local or Vercel project settings to match the deployed version.
NEXT_PUBLIC_WASM_BASE_URL=https://<YOUR_R2_PUBLIC_DOMAIN>
NEXT_PUBLIC_WASM_VERSION=v1.0.0coffeefruitcounter/
├── app/ # Next.js app
├── components/ # React components
├── lib/
│ ├── wasm-loader.ts # Dynamic remote WASM loader
│ └── wasm-types.d.ts # Ambient types for WASM
├── scripts/
│ └── deploy_wasm.sh # WASM build & deploy script
├── yolo-wasm/ # Rust source code
└── ...
MIT