A micro-volunteering platform connecting nonprofits with skilled volunteers. Complete quick 5 to 30-minute missions, help verified charities, and earn skill badges.
Nonprofits and community organizations often need quick help with specific tasks (translating a document, designing a flyer, reviewing data, or writing copy), but recruiting full-time volunteers is slow and difficult. MicroMatch breaks volunteering down into bite-sized missions that busy people can complete in under 30 minutes.
Volunteers pick tasks that match their skills, submit their work, and earn verified digital badges for their portfolio. Nonprofits get tasks completed quickly by motivated contributors without endless administrative overhead.
- Bite-sized task feed: Filter by time (
β€15 / β€20 / β€30 min), cause hashtags, or shortest duration first. - Volunteer portal: Claim tasks, submit proof of work via file or link, track review status, and collect skill badges.
- Nonprofit dashboard: Post tasks with deadlines and volunteer caps, review submissions, and manage organization badge awards.
- Charity verification: Simple trust verification where nonprofits submit their tax or charity ID, verified against public registries with a verified badge displayed on their tasks.
- Custom badge awards: Organizations define custom award badges (label, color, icon, criteria) automatically awarded upon task approval.
- Worldwide localization: Paraglide provides type-safe, reviewed UI catalogs and locale-prefixed routes; self-hosted LibreTranslate handles user-created task content on the server.
- Email updates: Automated email notifications keep volunteers and organizations informed of approvals and submissions.
These are real recordings of the application in action, captured by the automated test suite and rendered as previews:
The complete volunteering workflow: claim task β submit work β charity approves β earn badge
A volunteer claims a task, submits their work, the nonprofit reviews and approves the submission, and the digital badge is awarded to the volunteer's profile.
NGO badge tooling β define a badge, then read the analytics
Badges are org-owned definitions rather than a hardcoded list: an NGO picks a template or builds its own, and the awarder mints it on claim approval.
Run
bun run demoto regenerate: it reseeds, records fresh MP4s, and converts them to GIFs. The reseed is not optional. Demo tasks auto-archive after 30 days of no activity, and the closed-loop recording needs its claim and badge state reset or the badge never appears. See CONTRIBUTING.md for the one-time setup,e2e/demo/for the specs, andplaywright.demo.config.tsfor the recording configuration.
The core loop, end-to-end:
sequenceDiagram
autonumber
actor V as Volunteer
actor N as NGO
participant App as MicroMatch
participant DB as Appwrite
participant Mail as Plunk
N->>App: Post task
App->>DB: tasks.create (isVerified β NGO's verification status)
V->>App: Browse feed, claim task
App->>DB: claims.create (status=pending)
V->>App: Submit proof (URL or file)
App->>DB: claims.update (proofUrl, notes)
N->>App: Approve claim
App->>DB: claims.update (status=approved)
App->>DB: badges.create (matching BadgeDefinitions for org)
App-->>V: Dashboard updates, badge appears in vault
Note over N,Mail: Verification flow (parallel)
N->>App: Submit verification (tax ID + doc)
App->>DB: ngoVerifications.create (status=pending)
Note over App: Admin reviews queue with ProPublica enrichment
App->>DB: status=approved, back-fill tasks.isVerified
App->>Mail: Send "you're verified" email
Mail-->>N: π§
| Framework | SvelteKit on Vercel (adapter-vercel, nodejs22.x runtime) |
| Runtime + package manager | Bun |
| Backend | Appwrite Cloud β Database (TablesDB), Auth, Storage, Teams |
| Plunk as the transactional email provider (server-side HTTP API migration) | |
| NGO verification | ProPublica Nonprofit Explorer API for US 501(c)(3) lookups |
| Translation | Self-hosted LibreTranslate on an ARM64 Oracle VM behind translate.micromatch.app |
| Static UI localization | Paraglide JS with committed catalogs for English, Spanish, French, German, Portuguese, Chinese, and Arabic |
| UI | Plus Jakarta Sans + Inter, custom CSS (warm cream palette + coral accents), Iconify, Lottie |
| Testing | Vitest (unit + API + components) and Playwright (e2e) |
Quick path:
git clone https://github.com/Builder106/micro-match.git
cd MicroMatch
bun install
cp .env.example .env
# Fill in Appwrite + Plunk + ProPublica + LibreTranslate values
bun run devThe app runs at http://localhost:5173. Full setup (Appwrite resources, environment variables, project layout, conventions) lives in CONTRIBUTING.md.
bun run dev # dev server with HMR
bun run build # production build (uses adapter-vercel)
bun run check # svelte-check + tsc
bun run test # vitest (459 tests across server / API / components)
bun run test:e2e # Playwright (run `bunx playwright install chromium` once)
bun run seed # (re)seed the demo NGO + tasks β run before any demo recording
bun run verify:libretranslate # live health and API-key smoke check
bun run demo # seed, record the demo suite, convert to GIFs
bun run render-media # regenerate the README banners + social preview from /static/*.htmlThree layers of coverage:
- Server modules (vitest, node) β pure-ish helpers and DB CRUD:
tagColors,propublica,email,verifications,badgeDefs,badgeCriteria,badgeAwarder. Mock fetch + Appwrite at the module boundary. - API endpoints (vitest, node) β
/api/verifications,/api/verifications/[userId]/approve,/api/verifications/[userId]/reject,/api/profile/role,/api/badges/manage. Auth gates, validation, multi-step side effects. - Components (vitest, jsdom) β
BadgeChip,EmptyState,ProgressBar,VerificationCard(all four state branches via mocked fetch). - End-to-end (Playwright, chromium) β public-facing flows: landing, feed, login/signup multi-step, forgot-password, protected route redirect.
bun run test:coveragewrites an HTML report tocoverage/.
The demo suite in e2e/demo/ is deliberately not part of this. It shares Playwright but exists to record the GIFs above, so it's slow by design (slowMo, dwell beats), needs seeded fixtures, and never runs in CI.
Stored in Appwrite TablesDB (see docs/appwrite-schema.md for full schema details):
| Table | Holds |
|---|---|
tasks |
Mission cards posted by NGOs (title, tags, time estimate, deadline, status, isVerified) |
claims |
Volunteer submissions for tasks (proofUrl, notes, status: pending / approved / rejected) |
badges |
Awarded badge instances (userId, taskId, label, color) |
badgeDefinitions |
Org-owned badge templates (orgId, label, criteria, taskId for task-specific) |
ngoVerifications |
Verification queue (orgName, country, taxId, docFileId, status, reason) |
Plus three Appwrite Teams (volunteers, ngos, admins) for role + moderation gating. Storage uses separate avatars and verifications buckets with file-level permissions. To automatically provision the database tables, attributes, and storage buckets:
bun scripts/setup-appwrite.ts- CONTRIBUTING.md β local setup, project layout, conventions, PR process
- docs/index.md β platform docs index
- docs/volunteer.md β volunteer guide
- docs/ngo.md β NGO guide
- docs/api.md β full API specification (public & authenticated endpoints)
- docs/appwrite-schema.md β database schema and Appwrite resources specification
- docs/faq.md β FAQ
MIT β see LICENSE.





