A polished event intelligence platform for developers, builders, and technical communities.
Eventio discovers developer events across the web, normalizes them into one reliable schema, and serves them through a fast API and a beautiful calendar experience.
Eventio is a full-stack TypeScript monorepo that turns scattered developer opportunities into a clean, searchable event graph.
It focuses on:
- Coding contests and competitive programming rounds.
- Hackathons and build weekends.
- Developer workshops, AI/data events, and technical community programs.
- API-first access to normalized event data.
- Calendar-first discovery for humans.
The product experience lives in apps/web. The ingestion and backend pipeline lives across apps/api, apps/workers, and the shared packages/* workspace modules.
| Area | What You Get |
|---|---|
| Discovery | A calendar UI for browsing upcoming, ongoing, and past developer events. |
| Search | API query support for platform, category, status, pagination, and sorting. |
| Ingestion | Worker scripts that run scraper modules and write local scraper exports when needed. |
| Normalization | Shared packages for shaping source data into canonical event records. |
| Persistence | PostgreSQL schema and migrations managed through Drizzle. |
| Operations | Docker Compose for local PostgreSQL/Redis, health checks, lint hooks, and pnpm workspace scripts. |
Source platforms
|
v
Scraper modules -> worker scripts -> raw/normalized event data
|
v
Deduplication + normalization packages
|
v
PostgreSQL + Drizzle schema
|
v
Fastify API -> React/Vite web app
The system is intentionally modular: scrapers can evolve independently, API behavior is centralized, and the frontend can point at any compatible API base URL through public runtime config.
apps/
api/ Fastify API for health checks and /api/v1 routes
web/ React 19 + Vite frontend, SEO assets, calendar UI
workers/ Scraper runner and scheduled background entrypoints
packages/
config/ Environment loading and validation helpers
db/ Drizzle schema, database client, migrations
dedupe/ Event duplicate detection primitives
normalization/ Event shaping and cleanup package
observability/ Structured logging
queue/ BullMQ and Redis connection utilities
scraper-core/ Platform scrapers and scraper output helpers
search/ Search-related workspace package
shared/ Shared TypeScript types
tests/
e2e/ Playwright browser smoke tests
- Node.js
20+ - pnpm
8+ - Docker Desktop or Docker Engine, if you want local PostgreSQL and Redis
corepack enable
corepack prepare pnpm@latest --activate
pnpm installcp .env.example .envFor the default Docker Compose stack, these values are enough:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/eventio
DIRECT_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/eventio
REDIS_URL=redis://localhost:6379
PUBLIC_SITE_URL=http://localhost:5175
PUBLIC_API_BASE_URL=http://localhost:3000docker compose up -dThis starts:
- PostgreSQL on
localhost:5432 - Redis on
localhost:6379
Optional API container:
docker compose --profile app up --build apiOptional PgBouncer pooler:
docker compose --profile pooling up -d pgbouncerpnpm db:pushpnpm devCommon local URLs:
| Surface | URL |
|---|---|
| Web app | http://localhost:5175 or the Vite URL printed in your terminal |
| API health | http://localhost:3000/healthz |
| API v1 | http://localhost:3000/api/v1/... |
| In-app API docs | http://localhost:5175/docs |
| Command | Purpose |
|---|---|
pnpm dev |
Run workspace development scripts in parallel. |
pnpm build |
Build all packages/apps that expose a build script. |
pnpm lint |
Run ESLint across workspace packages. |
pnpm test |
Run package test scripts where present. |
pnpm check |
Run the default pre-push quality check. |
pnpm db:push |
Apply Drizzle schema changes to the configured database. |
pnpm db:generate |
Generate a Drizzle migration. |
pnpm scrape:trigger |
Trigger a worker scraper entrypoint. |
pnpm scrape:run |
Run scraper modules through the worker script. |
pnpm scrape:run:ci |
Run scraper modules in CI-friendly mode. |
The Fastify server exposes:
GET /healthz
GET /api/v1/*
POST /api/v1/*
The route implementation delegates to apps/api/lib/event-api.ts, which keeps API behavior reusable by both the standalone API server and the web server integration.
Typical filters include:
platformcategorystatussortorder- pagination inputs
See the in-app docs at /docs for request examples.
Use .env.example as the source of truth. Important groups:
| Group | Variables |
|---|---|
| App runtime | NODE_ENV, HOST, PORT, API_HOST, API_PORT, LOG_LEVEL |
| Public URLs | PUBLIC_SITE_URL, PUBLIC_API_BASE_URL |
| Database | DATABASE_URL, DIRECT_DATABASE_URL |
| Queue/cache | REDIS_URL |
| API auth/rate limits | PUBLIC_API_KEYS, INTERNAL_API_KEYS, PUBLIC_RATE_LIMIT_PER_MINUTE, ANONYMOUS_RATE_LIMIT_PER_MINUTE |
| Browser integrations | PUBLIC_FIREBASE_*, PUBLIC_POSTHOG_* |
Never commit real secrets. Keep local credentials in .env, deployment secrets in the deployment platform, and examples in .env.example.
The Docker setup is split into two useful paths:
docker compose up -dfor local infrastructure only.docker compose --profile app up --build apifor a containerized API smoke run.
The Dockerfile builds the workspace, keeps runtime process handling through dumb-init, exposes port 3000, and runs @eventio/api through the workspace start script.
Scraper code lives in packages/scraper-core/src. Worker entrypoints live in apps/workers/src.
Local scraper JSON exports are intentionally ignored:
apps/workers/scraper-output/
That directory is useful for debugging source behavior, but it should not be committed.
Before opening a pull request or pushing shared work, run:
pnpm lint
pnpm buildFor UI changes, run the app and capture screenshots. For API or ingestion changes, include sample requests, source notes, or representative payloads.
| Document | Purpose |
|---|---|
| ARCHITECTURE.md | System design, runtime boundaries, and data flow. |
| CONTRIBUTING.md | Local setup, branch rules, PR standards, and contribution workflow. |
| SECURITY.md | Vulnerability reporting and security scope. |
| SUPPORT.md | Where to ask for help and what to include. |
| GOVERNANCE.md | Maintainer responsibilities and decision-making model. |
| CHANGELOG.md | Project history and unreleased notes. |
| apps/web/README.md | Frontend-specific guide. |
Eventio is maintained by Om Khalane.
- Portfolio: omkhalane.dev
- Repository: github.com/omkhalane/eventio
- Security: see SECURITY.md
MIT. See LICENSE.
